alias_metrics 0.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile +1 -5
- data/README +23 -2
- data/alias_metrics.gemspec +2 -2
- data/bin/alias_candidates +19 -0
- data/bin/alias_metrics +1 -0
- data/lib/alias_metrics.rb +2 -0
- data/lib/alias_metrics/alias_line_parser/zsh.rb +16 -0
- data/lib/alias_metrics/alias_list.rb +77 -71
- data/lib/alias_metrics/alias_usage.rb +10 -10
- data/lib/alias_metrics/command_history.rb +96 -60
- data/lib/alias_metrics/fragment.rb +19 -0
- data/lib/alias_metrics/shortenable.rb +10 -8
- data/spec/alias_list_spec.rb +67 -21
- data/spec/command_history_spec.rb +46 -11
- metadata +14 -10
- data/Gemfile.lock +0 -27
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/README
CHANGED
@@ -1,14 +1,21 @@
|
|
1
1
|
This tool is to visualize alias usage to parse command history. You can evaluate whether you use alias efficiently or not.
|
2
2
|
* It can show reduced types and more redusable types
|
3
3
|
* It can show how degree you use each alias
|
4
|
+
* It can show candidate alias_commands
|
4
5
|
|
5
6
|
The visabliable shell scripts is the followings:
|
6
7
|
* zsh (${HOME}/.zsh-history)
|
7
8
|
|
8
9
|
|
10
|
+
Install:
|
11
|
+
|
12
|
+
gem install alias_metrics
|
13
|
+
|
14
|
+
|
9
15
|
How to use:
|
10
16
|
|
11
17
|
$ alias | alias_metrics
|
18
|
+
$ alias | alias_candidates
|
12
19
|
|
13
20
|
|
14
21
|
Case Study:
|
@@ -36,13 +43,27 @@ If you use alias all, you can reduce more 3.98% types (11575 / 290970)
|
|
36
43
|
|
37
44
|
...
|
38
45
|
<<
|
39
|
-
I regist alias g=`git`, but I often forgot to use this alias. This result show I typed "git" 1530 times. So I can reduce 1530 *
|
46
|
+
I regist alias g=`git`, but I often forgot to use this alias. This result show I typed "git" 1530 times. So I can reduce 1530 * (3-1) = 3060 types by typing "g" instead of "git".
|
40
47
|
|
48
|
+
$ alias | alias_candidates
|
49
|
+
>>
|
50
|
+
types count command => shorten command
|
51
|
+
6510 651 git status => "g status","gst"
|
52
|
+
5979 1993 git => "g"
|
53
|
+
4860 972 ls -G => "ls -G"
|
54
|
+
3627 1209 vim => no alias
|
55
|
+
2912 182 bundle exec rake => "be rake"
|
56
|
+
2900 290 git commit => "g commit"
|
57
|
+
2695 245 bundle exec => "be"
|
58
|
+
2544 159 git flow feature => "g flow feature"
|
59
|
+
2268 324 git add => "g add","ga"
|
60
|
+
...
|
61
|
+
<<
|
62
|
+
I often use "vim" command. But "vim" command has no alias. If I regsit alias v=`vim`, I can reduce 1209 * (3-1) = 2418 types by typing "v" instead of "vim".
|
41
63
|
|
42
64
|
Todo:
|
43
65
|
|
44
66
|
* It can parse other shell scrpt(bash, csh, etc...)
|
45
|
-
* Add the function that recommends alias that can reduce your types by setting it
|
46
67
|
* Add the function that show Gold Standard
|
47
68
|
* Acceleration
|
48
69
|
|
data/alias_metrics.gemspec
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = 'alias_metrics'
|
3
|
-
spec.version = '0.1'
|
3
|
+
spec.version = '0.1.2'
|
4
4
|
spec.summary = "This tool is to visualize alias usage to parse command history. You can evaluate whether you use alias efficiently or not."
|
5
5
|
spec.author = ["Kohei Tomita"]
|
6
6
|
spec.email = "tommy.fmale@gmail.com"
|
7
|
-
spec.executables = %w(alias_metrics)
|
7
|
+
spec.executables = %w(alias_metrics alias_candidates)
|
8
8
|
spec.files = `git ls-files`.split("\n") rescue ''
|
9
9
|
spec.homepage = "https://github.com/tomity/alias_metrics"
|
10
10
|
spec.add_development_dependency 'rspec', '~> 2.0'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
lib = File.dirname(__FILE__) + '/../lib/'
|
3
|
+
$:.unshift lib unless $:.include?(lib)
|
4
|
+
require "alias_metrics"
|
5
|
+
include AliasMetrics
|
6
|
+
|
7
|
+
@alias_list = AliasList.load_from_stdin
|
8
|
+
@history = CommandHistory.load_from_zsh_history(@alias_list)
|
9
|
+
fragments = @history.fragment.values.select{|a| a.count >= 5}
|
10
|
+
max_fragment_size = fragments.map{|a| a.body.size }.max
|
11
|
+
puts "types\tcount\tcommand#{" " * (max_fragment_size - "command".size)} => shorten command"
|
12
|
+
fragments.sort{|a, b| a.types <=> b.types }.reverse.each do |value|
|
13
|
+
if @alias_list.shortenable?(value.body)
|
14
|
+
puts "#{value.types}\t#{value.count}\t#{value.body + " " * (max_fragment_size - value.body.size)} => #{@alias_list.shorten_command(value.body).map{|h| "\"#{h}\""}.join(",")}"
|
15
|
+
else
|
16
|
+
puts "#{value.types}\t#{value.count}\t#{value.body + " " * (max_fragment_size - value.body.size)} => no alias"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
data/bin/alias_metrics
CHANGED
data/lib/alias_metrics.rb
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
module AliasLineParser
|
2
|
+
class Zsh
|
3
|
+
def parse(line)
|
4
|
+
key, value = line.split(/=/)
|
5
|
+
value = remove_single_quotes(value)
|
6
|
+
[key, value]
|
7
|
+
end
|
8
|
+
|
9
|
+
def remove_single_quotes(real)
|
10
|
+
if real[0, 1] == "'" and real[-1, 1] == "'"
|
11
|
+
real = real[1..-2]
|
12
|
+
end
|
13
|
+
real
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,88 +1,94 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module AliasMetrics
|
2
|
+
class AliasList
|
3
|
+
attr_accessor :alias_hash
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
class << AliasList
|
6
|
+
def load(io, alias_line_parser)
|
7
|
+
alias_hash = Hash::new
|
8
|
+
io.each do |line|
|
9
|
+
line.chomp!
|
10
|
+
alias_, real = alias_line_parser.parse(line)
|
11
|
+
alias_hash[alias_] = real
|
12
|
+
end
|
13
|
+
AliasList.new(alias_hash)
|
14
|
+
end
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
16
|
+
def load_from_lines(lines, alias_line_parser=AliasLineParser::Zsh.new)
|
17
|
+
alias_hash = Hash::new
|
18
|
+
lines.each do |line|
|
19
|
+
alias_, real = alias_line_parser.parse(line)
|
20
|
+
alias_hash[alias_] = real
|
21
|
+
end
|
22
|
+
AliasList.new(alias_hash)
|
23
|
+
end
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
if used_subcommand?(command, key)
|
27
|
-
command = command.sub(key, value)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
command
|
31
|
-
end
|
25
|
+
def load_from_stdin(alias_line_parser=AliasLineParser::Zsh.new)
|
26
|
+
AliasList.load(STDIN, alias_line_parser)
|
27
|
+
end
|
32
28
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
command = command.sub(key, value)
|
39
|
-
ret << [key, value]
|
40
|
-
end
|
41
|
-
end
|
42
|
-
ret
|
43
|
-
end
|
29
|
+
def load_from_file(file, alias_line_parser=AliasLineParser::Zsh.new)
|
30
|
+
open(file) do |fh|
|
31
|
+
AliasList.load(fh, alias_line_parser)
|
32
|
+
end
|
33
|
+
end
|
44
34
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
35
|
+
end
|
36
|
+
|
37
|
+
#NOTE: Since #command >> #alias, this process do fastly
|
38
|
+
def expand_command(command)
|
39
|
+
@alias_hash.each_pair do |alias_, real|
|
40
|
+
if used_subcommand?(command, alias_)
|
41
|
+
command = command.sub(alias_, real)
|
42
|
+
end
|
50
43
|
end
|
44
|
+
command
|
51
45
|
end
|
52
|
-
false
|
53
|
-
end
|
54
46
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
ret << [key, value]
|
60
|
-
end
|
61
|
-
end
|
62
|
-
ret
|
63
|
-
end
|
47
|
+
def appliable_alias(command)
|
48
|
+
alias_ = command.split(/\s/).first
|
49
|
+
@alias_hash.has_key?(alias_) ? alias_ : nil
|
50
|
+
end
|
64
51
|
|
65
|
-
|
52
|
+
#NOTE: Since #command >> #alias, this process do fastly
|
53
|
+
def shortenable?(command)
|
54
|
+
@alias_hash.each_pair do |alias_, real|
|
55
|
+
if used_subcommand?(command, real)
|
56
|
+
return true if real.length > alias_.length
|
57
|
+
end
|
58
|
+
end
|
59
|
+
false
|
60
|
+
end
|
66
61
|
|
67
|
-
|
68
|
-
|
69
|
-
|
62
|
+
def shortenable_alias(command)
|
63
|
+
ret = []
|
64
|
+
@alias_hash.each_pair do |alias_, real|
|
65
|
+
if used_subcommand?(command, real)
|
66
|
+
ret << alias_ if real.length > alias_.length
|
67
|
+
end
|
68
|
+
end
|
69
|
+
ret
|
70
|
+
end
|
70
71
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
72
|
+
def shorten_command(command)
|
73
|
+
expanded = expand_command(command)
|
74
|
+
ret = Array.new
|
75
|
+
@alias_hash.each_pair do |alias_, real|
|
76
|
+
if used_subcommand?(expanded, real)
|
77
|
+
ret << expanded.sub(real, alias_) if real.length > alias_.length
|
78
|
+
end
|
79
|
+
end
|
80
|
+
ret
|
81
|
+
end
|
76
82
|
|
77
|
-
|
78
|
-
|
79
|
-
|
83
|
+
private
|
84
|
+
|
85
|
+
def initialize(alias_hash)
|
86
|
+
@alias_hash = alias_hash.freeze
|
80
87
|
end
|
81
|
-
value
|
82
|
-
end
|
83
88
|
|
84
|
-
|
85
|
-
|
89
|
+
def used_subcommand?(command, alias_)
|
90
|
+
command == alias_ || command.start_with?(alias_+ " ")
|
91
|
+
end
|
86
92
|
end
|
87
93
|
end
|
88
94
|
|
@@ -1,13 +1,13 @@
|
|
1
|
+
module AliasMetrics
|
2
|
+
class AliasUsage
|
3
|
+
attr_accessor :alias
|
4
|
+
attr_accessor :command
|
5
|
+
attr_accessor :count
|
1
6
|
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
def initialize(alias_, command)
|
8
|
-
self.alias = alias_.freeze
|
9
|
-
self.command = command.freeze
|
10
|
-
self.count = 0
|
7
|
+
def initialize(alias_, command)
|
8
|
+
self.alias = alias_.freeze
|
9
|
+
self.command = command.freeze
|
10
|
+
self.count = 0
|
11
|
+
end
|
11
12
|
end
|
12
|
-
|
13
13
|
end
|
@@ -1,79 +1,115 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
attr_accessor :shortenables
|
5
|
-
attr_accessor :alias_usages
|
6
|
-
attr_accessor :alias_list
|
1
|
+
module AliasMetrics
|
2
|
+
class CommandHistory
|
3
|
+
ZSH_HISTORY_FILE = "#{ENV["HOME"]}/.zsh_history"
|
7
4
|
|
8
|
-
|
5
|
+
class << CommandHistory
|
6
|
+
def load_from_zsh_history(alias_list, history_file = ZSH_HISTORY_FILE)
|
7
|
+
commands = []
|
8
|
+
open(history_file) do |fh|
|
9
|
+
fh.each do |line|
|
10
|
+
line.chomp!
|
11
|
+
next if line == ""
|
12
|
+
begin
|
13
|
+
command = parse_command_by_zsh_history_line(line)
|
14
|
+
commands << command if command
|
15
|
+
rescue ArgumentError #invalid byte sequence in UTF-8
|
16
|
+
#do nothing
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
CommandHistory.new(commands, alias_list)
|
21
|
+
end
|
9
22
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
self.alias_usages = Hash.new
|
16
|
-
alias_list.alias_hash.each_pair do |alias_, value|
|
17
|
-
self.alias_usages[alias_] = AliasUsage.new(alias_, value)
|
18
|
-
self.shortenables[value] = Shortenable.new(alias_, value)
|
23
|
+
private
|
24
|
+
def parse_command_by_zsh_history_line(line)
|
25
|
+
command = line.split(/;/)[1]
|
26
|
+
return command
|
27
|
+
end
|
19
28
|
end
|
20
29
|
|
21
|
-
commands
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
30
|
+
attr_accessor :commands
|
31
|
+
attr_accessor :shorten_count
|
32
|
+
attr_accessor :shortenables
|
33
|
+
attr_accessor :alias_usages
|
34
|
+
attr_accessor :alias_list
|
35
|
+
attr_accessor :fragment
|
36
|
+
|
37
|
+
def initialize(commands, alias_list)
|
38
|
+
self.alias_list = alias_list
|
39
|
+
self.commands = []
|
40
|
+
self.shorten_count = 0
|
41
|
+
self.shortenables = Hash.new
|
42
|
+
self.alias_usages = Hash.new
|
43
|
+
alias_list.alias_hash.each_pair do |alias_, value|
|
44
|
+
self.alias_usages[alias_] = AliasUsage.new(alias_, value)
|
45
|
+
self.shortenables[alias_] = Shortenable.new(alias_, value)
|
46
|
+
end
|
47
|
+
self.fragment = Hash.new{|h, key| h[key] = Fragment.new(key)}
|
48
|
+
|
49
|
+
commands.each do |command|
|
50
|
+
update_shortenables(command)
|
51
|
+
update_alias_usages(command)
|
52
|
+
command_expanded = self.alias_list.expand_command(command)
|
53
|
+
self.shorten_count += [0, command_expanded.length - command.length].max
|
54
|
+
self.commands << command_expanded
|
55
|
+
fragments(command_expanded).each do |fragment_body|
|
56
|
+
self.fragment[fragment_body].count += 1
|
57
|
+
end
|
58
|
+
end
|
59
|
+
self.alias_list = self.alias_list.freeze
|
60
|
+
self.commands = self.commands.freeze
|
61
|
+
self.shorten_count = self.shorten_count.freeze
|
62
|
+
self.shortenables = self.shortenables.freeze
|
63
|
+
self.alias_usages = self.alias_usages.freeze
|
27
64
|
end
|
28
|
-
self.alias_list = self.alias_list.freeze
|
29
|
-
self.commands = self.commands.freeze
|
30
|
-
self.shorten_count = self.shorten_count.freeze
|
31
|
-
self.shortenables = self.shortenables.freeze
|
32
|
-
self.alias_usages = self.alias_usages.freeze
|
33
|
-
end
|
34
65
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
rescue ArgumentError #invalid byte sequence in UTF-8
|
45
|
-
#do nothing
|
66
|
+
private
|
67
|
+
|
68
|
+
|
69
|
+
def update_shortenables(command)
|
70
|
+
if alias_list.shortenable?(command)
|
71
|
+
shortenable_alias_list = alias_list.shortenable_alias(command)
|
72
|
+
shortenable_alias_list.each do |alias_|
|
73
|
+
extension = alias_list.alias_hash[alias_]
|
74
|
+
self.shortenables[alias_].count += 1 if shortenable?(alias_, extension)
|
46
75
|
end
|
47
76
|
end
|
48
77
|
end
|
49
|
-
CommandHistory.new(commands, alias_list)
|
50
|
-
end
|
51
78
|
|
52
|
-
|
79
|
+
def update_alias_usages(command)
|
80
|
+
alias_ = self.alias_list.appliable_alias(command)
|
81
|
+
self.alias_usages[alias_].count += 1 if alias_
|
82
|
+
end
|
53
83
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
84
|
+
def shortenable?(alias_, command)
|
85
|
+
command.size > alias_.size
|
86
|
+
end
|
58
87
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
88
|
+
def fragments(command)
|
89
|
+
ret = Array.new
|
90
|
+
units = command.split(/\s/)
|
91
|
+
substr = units.shift
|
92
|
+
if command_fragment?(substr)
|
93
|
+
ret << substr
|
94
|
+
units.each do |unit|
|
95
|
+
break if not command_fragment?(unit)
|
96
|
+
substr = substr + " " + unit
|
97
|
+
ret << substr if fragment?(substr, unit)
|
98
|
+
end
|
64
99
|
end
|
100
|
+
ret
|
65
101
|
end
|
66
|
-
end
|
67
102
|
|
68
|
-
|
69
|
-
|
70
|
-
applied_alias.each do |alias_, value|
|
71
|
-
self.alias_usages[alias_].count += 1
|
103
|
+
def command_fragment?(unit)
|
104
|
+
unit =~ /^[a-zA-Z\-|]+$/
|
72
105
|
end
|
73
|
-
end
|
74
106
|
|
75
|
-
|
76
|
-
|
77
|
-
|
107
|
+
def fragment?(substr, last_unit)
|
108
|
+
!pipe?(last_unit)
|
109
|
+
end
|
78
110
|
|
111
|
+
def pipe?(unit)
|
112
|
+
unit == "|"
|
113
|
+
end
|
114
|
+
end
|
79
115
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module AliasMetrics
|
2
|
+
class Fragment
|
3
|
+
attr_accessor :body
|
4
|
+
attr_accessor :count
|
5
|
+
|
6
|
+
def initialize(body)
|
7
|
+
self.body = body
|
8
|
+
self.count = 0
|
9
|
+
end
|
10
|
+
|
11
|
+
def types
|
12
|
+
body.size * count
|
13
|
+
end
|
14
|
+
|
15
|
+
def shorten_types(alias_)
|
16
|
+
(body.size - alias_.size) * count
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,11 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module AliasMetrics
|
2
|
+
class Shortenable
|
3
|
+
attr_accessor :command
|
4
|
+
attr_accessor :alias
|
5
|
+
attr_accessor :count
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
def initialize(alias_, command)
|
8
|
+
self.alias = alias_.freeze
|
9
|
+
self.command = command.freeze
|
10
|
+
self.count = 0
|
11
|
+
end
|
10
12
|
end
|
11
13
|
end
|
data/spec/alias_list_spec.rb
CHANGED
@@ -1,46 +1,92 @@
|
|
1
1
|
require "alias_metrics"
|
2
|
+
include AliasMetrics
|
2
3
|
|
3
4
|
describe AliasList do
|
4
|
-
|
5
|
-
@alias_list = AliasList.load_from_lines(["l='ls -la'", "sl=ls", "grhh='git reset --hard HEAD\^'"])
|
6
|
-
end
|
5
|
+
let(:alias_list){ AliasList.load_from_lines(["l='ls -la'", "sl=ls", "grhh='git reset --hard HEAD\^'"]) }
|
7
6
|
describe "expand_command" do
|
8
|
-
it "should
|
9
|
-
|
7
|
+
it "should expand the command `l` to the command `ls -la`" do
|
8
|
+
alias_list.expand_command("l").should == "ls -la"
|
10
9
|
end
|
11
10
|
|
12
|
-
it "should
|
13
|
-
|
11
|
+
it "should expand the command `l -h` to the command `ls -la -h`" do
|
12
|
+
alias_list.expand_command("l -h").should == "ls -la -h"
|
14
13
|
end
|
15
14
|
|
16
|
-
it "should
|
17
|
-
|
15
|
+
it "should expand the command `sl` to the command `ls`" do
|
16
|
+
alias_list.expand_command("sl").should == "ls"
|
18
17
|
end
|
19
18
|
|
20
|
-
it "should
|
21
|
-
|
19
|
+
it "should expand the command `sl -l` to the command `ls -l`" do
|
20
|
+
alias_list.expand_command("sl -l").should == "ls -l"
|
22
21
|
end
|
23
22
|
|
24
|
-
it "should
|
25
|
-
|
23
|
+
it "should not expand the command `slope` to the command `lsope` because this command is not `sl`" do
|
24
|
+
alias_list.expand_command("slope").should == "slope"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "applied_alias" do
|
29
|
+
it "should get the fact that command `l` can use alias `l`" do
|
30
|
+
alias_list.appliable_alias("l").should == "l"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should get the fact that command `l -h` can use alias `l`" do
|
34
|
+
alias_list.appliable_alias("l -h").should == "l"
|
26
35
|
end
|
27
36
|
end
|
28
37
|
|
29
38
|
describe "shortenable" do
|
30
|
-
it "should
|
31
|
-
|
39
|
+
it "should get the fact that `ls -la` can be shortenable" do
|
40
|
+
alias_list.shortenable?("ls -la").should == true
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should get the fact that `ls -la -h` can be shortenable" do
|
44
|
+
alias_list.shortenable?("ls -la -h").should == true
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should get the fact that `git reset --hard` can not be shortenable" do
|
48
|
+
alias_list.shortenable?("git reset --hard").should == false
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should get the fact that `git reset HEAD\^ --hard` can not be shortenable" do
|
52
|
+
alias_list.shortenable?("git reset HEAD\^ --hard").should == false
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should get the fact that `git reset --hard HEAD\^` can be shortenable" do
|
56
|
+
alias_list.shortenable?("git reset --hard HEAD\^").should == true
|
32
57
|
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "shortenable_alias" do
|
61
|
+
it "should get the fact the command `ls -la` can be shortenable by the alias `l`" do
|
62
|
+
aliass = alias_list.shortenable_alias("ls -la")
|
63
|
+
aliass.size.should == 1
|
64
|
+
aliass.should include "l"
|
65
|
+
end
|
66
|
+
end
|
33
67
|
|
34
|
-
|
35
|
-
|
68
|
+
describe "shorten_command" do
|
69
|
+
it "should shorten the command `git reset --hard HEAD\^` to `grhh` or `g reset --hard HEAD\^`" do
|
70
|
+
alias_list = AliasList.load_from_lines(["g=git", "grhh='git reset --hard HEAD\^'"])
|
71
|
+
shorten_commands = alias_list.shorten_command("git reset --hard HEAD\^")
|
72
|
+
shorten_commands.size.should == 2
|
73
|
+
shorten_commands.should include "grhh"
|
74
|
+
shorten_commands.should include "g reset --hard HEAD\^"
|
36
75
|
end
|
37
76
|
|
38
|
-
it "should
|
39
|
-
|
77
|
+
it "should shorten the command `g reset --hard HEAD\^` to `grhh` or `g reset --hard HEAD\^`" do
|
78
|
+
alias_list = AliasList.load_from_lines(["g=git", "grhh='git reset --hard HEAD\^'"])
|
79
|
+
shorten_commands = alias_list.shorten_command("g reset --hard HEAD\^")
|
80
|
+
shorten_commands.size.should == 2
|
81
|
+
shorten_commands.should include "grhh"
|
82
|
+
shorten_commands.should include "g reset --hard HEAD\^"
|
40
83
|
end
|
41
84
|
|
42
|
-
it "should
|
43
|
-
|
85
|
+
it "should shorten the command `git reset --hard HEAD\^` to `grhh` or `g reset --hard HEAD\^`" do
|
86
|
+
alias_list = AliasList.load_from_lines(["l='ls -la'", "sl=ls"])
|
87
|
+
shorten_commands = alias_list.shorten_command("ls -la")
|
88
|
+
shorten_commands.size.should == 1
|
89
|
+
shorten_commands.should include "l"
|
44
90
|
end
|
45
91
|
end
|
46
92
|
|
@@ -1,35 +1,43 @@
|
|
1
1
|
require "alias_metrics"
|
2
|
+
include AliasMetrics
|
2
3
|
|
3
4
|
describe CommandHistory do
|
4
5
|
before do
|
5
|
-
@alias_list = AliasList.load_from_lines(["l='ls -la'", "ga=git add", "run-help=man"])
|
6
|
-
@history = CommandHistory.new(["l", "l -h", "ls -la", "ls -la -h", "man"], @alias_list)
|
6
|
+
@alias_list = AliasList.load_from_lines(["l='ls -la'", "g=git", "ga=git add", "run-help=man"])
|
7
|
+
@history = CommandHistory.new(["l", "l -h", "ls -la", "ls -la -h", "ga", "git add", "man"], @alias_list)
|
7
8
|
end
|
8
9
|
|
9
10
|
it "can get the number of commands" do
|
10
|
-
@history.commands.size.should ==
|
11
|
+
@history.commands.size.should == 7
|
11
12
|
end
|
12
13
|
|
13
14
|
it "can count the number of chars shorten" do
|
14
|
-
@history.shorten_count.should ==
|
15
|
+
@history.shorten_count.should == 15 #because (`ls -la` => `l`) * 2 + (`git add` => `ga`)
|
15
16
|
end
|
16
17
|
|
17
18
|
it "should be count is 2 when ls -la" do
|
18
|
-
shortenable = @history.shortenables["
|
19
|
+
shortenable = @history.shortenables["l"]
|
19
20
|
shortenable.alias.should == "l"
|
20
21
|
shortenable.command.should == "ls -la"
|
21
22
|
shortenable.count.should == 2
|
22
23
|
end
|
23
24
|
|
24
|
-
it "should be count is
|
25
|
-
shortenable = @history.shortenables["
|
25
|
+
it "should be count is 1 when git" do
|
26
|
+
shortenable = @history.shortenables["g"]
|
27
|
+
shortenable.alias.should == "g"
|
28
|
+
shortenable.command.should == "git"
|
29
|
+
shortenable.count.should == 1
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should be count is 1 when git add" do
|
33
|
+
shortenable = @history.shortenables["ga"]
|
26
34
|
shortenable.alias.should == "ga"
|
27
35
|
shortenable.command.should == "git add"
|
28
|
-
shortenable.count.should ==
|
36
|
+
shortenable.count.should == 1
|
29
37
|
end
|
30
38
|
|
31
39
|
it "should be count is 0 when ls -la because run-help is longer than man" do
|
32
|
-
shortenable = @history.shortenables["
|
40
|
+
shortenable = @history.shortenables["run-help"]
|
33
41
|
shortenable.alias.should == "run-help"
|
34
42
|
shortenable.command.should == "man"
|
35
43
|
shortenable.count.should == 0
|
@@ -42,11 +50,18 @@ describe CommandHistory do
|
|
42
50
|
alias_usage.count.should == 2
|
43
51
|
end
|
44
52
|
|
53
|
+
it "should be alias usage is 0 when g" do
|
54
|
+
alias_usage = @history.alias_usages["g"]
|
55
|
+
alias_usage.alias.should == "g"
|
56
|
+
alias_usage.command.should == "git"
|
57
|
+
alias_usage.count.should == 0
|
58
|
+
end
|
59
|
+
|
45
60
|
it "should be alias usage is 0 when ga" do
|
46
61
|
alias_usage = @history.alias_usages["ga"]
|
47
62
|
alias_usage.alias.should == "ga"
|
48
63
|
alias_usage.command.should == "git add"
|
49
|
-
alias_usage.count.should ==
|
64
|
+
alias_usage.count.should == 1
|
50
65
|
end
|
51
66
|
|
52
67
|
it "should be alias usage is 0 when run-help" do
|
@@ -65,6 +80,26 @@ describe CommandHistory do
|
|
65
80
|
@history.commands[1].should == "ls -la -h"
|
66
81
|
@history.commands[2].should == "ls -la"
|
67
82
|
@history.commands[3].should == "ls -la -h"
|
68
|
-
@history.commands[4].should == "
|
83
|
+
@history.commands[4].should == "git add"
|
84
|
+
@history.commands[5].should == "git add"
|
85
|
+
@history.commands[6].should == "man"
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should get count for fragment" do
|
89
|
+
@history.fragment["ls"].count.should == 4
|
90
|
+
@history.fragment["ls -la"].count.should == 4
|
91
|
+
@history.fragment["ls -la -h"].count.should == 2
|
92
|
+
@history.fragment["l"].count.should == 0
|
93
|
+
@history.fragment["ga"].count.should == 0
|
94
|
+
@history.fragment["git"].count.should == 2
|
95
|
+
@history.fragment["git add"].count.should == 2
|
96
|
+
@history.fragment["man"].count.should == 1
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should get count for fragment" do
|
100
|
+
@history.fragment["ls -la -h"].types.should == 9 * 2
|
101
|
+
@history.fragment["ls -la -h"].shorten_types("ll").should == (9 - 2) * 2
|
102
|
+
@history.fragment["ls -la"].types.should == 6 * 4
|
103
|
+
@history.fragment["ls -la"].shorten_types("l").should == (6 - 1) * 4
|
69
104
|
end
|
70
105
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alias_metrics
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-07-14 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &70176108328560 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '2.0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70176108328560
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: fuubar
|
27
|
-
requirement: &
|
27
|
+
requirement: &70176108327740 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 1.0.0
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70176108327740
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rake
|
38
|
-
requirement: &
|
38
|
+
requirement: &70176108327180 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,27 +43,31 @@ dependencies:
|
|
43
43
|
version: 0.9.2.2
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70176108327180
|
47
47
|
description:
|
48
48
|
email: tommy.fmale@gmail.com
|
49
49
|
executables:
|
50
50
|
- alias_metrics
|
51
|
+
- alias_candidates
|
51
52
|
extensions: []
|
52
53
|
extra_rdoc_files: []
|
53
54
|
files:
|
54
55
|
- .gitignore
|
55
56
|
- .rspec
|
56
57
|
- Gemfile
|
57
|
-
- Gemfile.lock
|
58
58
|
- README
|
59
59
|
- Rakefile
|
60
60
|
- alias_metrics.gemspec
|
61
|
+
- bin/alias_candidates
|
61
62
|
- bin/alias_metrics
|
63
|
+
- gems/alias_metrics-0.1.1.gem
|
62
64
|
- gems/alias_metrics-0.1.gem
|
63
65
|
- lib/alias_metrics.rb
|
66
|
+
- lib/alias_metrics/alias_line_parser/zsh.rb
|
64
67
|
- lib/alias_metrics/alias_list.rb
|
65
68
|
- lib/alias_metrics/alias_usage.rb
|
66
69
|
- lib/alias_metrics/command_history.rb
|
70
|
+
- lib/alias_metrics/fragment.rb
|
67
71
|
- lib/alias_metrics/shortenable.rb
|
68
72
|
- spec/alias_list_spec.rb
|
69
73
|
- spec/command_history_spec.rb
|
@@ -87,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
91
|
version: '0'
|
88
92
|
requirements: []
|
89
93
|
rubyforge_project:
|
90
|
-
rubygems_version: 1.8.
|
94
|
+
rubygems_version: 1.8.17
|
91
95
|
signing_key:
|
92
96
|
specification_version: 3
|
93
97
|
summary: This tool is to visualize alias usage to parse command history. You can evaluate
|
data/Gemfile.lock
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
GEM
|
2
|
-
remote: http://rubygems.org/
|
3
|
-
specs:
|
4
|
-
diff-lcs (1.1.3)
|
5
|
-
fuubar (1.0.0)
|
6
|
-
rspec (~> 2.0)
|
7
|
-
rspec-instafail (~> 0.2.0)
|
8
|
-
ruby-progressbar (~> 0.0.10)
|
9
|
-
rake (0.9.2.2)
|
10
|
-
rspec (2.8.0)
|
11
|
-
rspec-core (~> 2.8.0)
|
12
|
-
rspec-expectations (~> 2.8.0)
|
13
|
-
rspec-mocks (~> 2.8.0)
|
14
|
-
rspec-core (2.8.0)
|
15
|
-
rspec-expectations (2.8.0)
|
16
|
-
diff-lcs (~> 1.1.2)
|
17
|
-
rspec-instafail (0.2.2)
|
18
|
-
rspec-mocks (2.8.0)
|
19
|
-
ruby-progressbar (0.0.10)
|
20
|
-
|
21
|
-
PLATFORMS
|
22
|
-
ruby
|
23
|
-
|
24
|
-
DEPENDENCIES
|
25
|
-
fuubar (~> 1.0.0)
|
26
|
-
rake (~> 0.9.2.2)
|
27
|
-
rspec (~> 2.0)
|