command-line-favs 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +50 -0
- data/LICENSE.txt +8 -0
- data/README.md +108 -0
- data/README.rdoc +23 -0
- data/Rakefile +61 -0
- data/bin/fav +42 -0
- data/command-line-favs.gemspec +28 -0
- data/features/command-line-favs.feature +138 -0
- data/features/step_definitions/command-line-favs_steps.rb +25 -0
- data/features/support/env.rb +22 -0
- data/lib/fav/version.rb +3 -0
- data/lib/fav.rb +179 -0
- data/test/tc_something.rb +7 -0
- metadata +163 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6bd5d33d21e6787c2c179a69d1f9fc8eec6f210c
|
4
|
+
data.tar.gz: 1d56cca67075349dc1a2ae72255e4150ab39a099
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0e4c8b52eae961faafdf53d09df3b6f27f29fd29ef81239844a55f8265eea051aea1ed053773838c228696da830b1af6884200e7325eea5f825b662109d572ab
|
7
|
+
data.tar.gz: a34a21249d9765193e709570dcbc48947881ccc075ba686493e245542ff1a874e360589d27f7ba182e11a8f09803cacb9a9327775674306e5b8eb7dd15b61591
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
command-line-favs (0.0.1)
|
5
|
+
highline (~> 1.6)
|
6
|
+
methadone (~> 1.4)
|
7
|
+
parseconfig (~> 1.0)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
aruba (0.5.4)
|
13
|
+
childprocess (>= 0.3.6)
|
14
|
+
cucumber (>= 1.1.1)
|
15
|
+
rspec-expectations (>= 2.7.0)
|
16
|
+
builder (3.2.2)
|
17
|
+
childprocess (0.5.3)
|
18
|
+
ffi (~> 1.0, >= 1.0.11)
|
19
|
+
cucumber (1.3.14)
|
20
|
+
builder (>= 2.1.2)
|
21
|
+
diff-lcs (>= 1.1.3)
|
22
|
+
gherkin (~> 2.12)
|
23
|
+
multi_json (>= 1.7.5, < 2.0)
|
24
|
+
multi_test (>= 0.1.1)
|
25
|
+
diff-lcs (1.2.5)
|
26
|
+
ffi (1.9.3)
|
27
|
+
gherkin (2.12.2)
|
28
|
+
multi_json (~> 1.3)
|
29
|
+
highline (1.6.21)
|
30
|
+
json (1.8.1)
|
31
|
+
methadone (1.4.0)
|
32
|
+
bundler
|
33
|
+
multi_json (1.10.0)
|
34
|
+
multi_test (0.1.1)
|
35
|
+
parseconfig (1.0.4)
|
36
|
+
rake (0.9.6)
|
37
|
+
rdoc (4.1.1)
|
38
|
+
json (~> 1.4)
|
39
|
+
rspec-expectations (2.14.5)
|
40
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
41
|
+
|
42
|
+
PLATFORMS
|
43
|
+
ruby
|
44
|
+
|
45
|
+
DEPENDENCIES
|
46
|
+
aruba (~> 0.5)
|
47
|
+
bundler (~> 1.6)
|
48
|
+
command-line-favs!
|
49
|
+
rake (~> 0.9)
|
50
|
+
rdoc (~> 4.1)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
Name: command-line-favs
|
2
|
+
Copyright (c) 2014 Jon Bake
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
5
|
+
|
6
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
7
|
+
|
8
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
# Command Line Favs
|
2
|
+
|
3
|
+
Command Line Favs is a CLI utility for organizing your commonly used shell commands. Commands are stored as a **Command Name** (think Alias) to **Command** map within your ~/.favs file and can be organized into groups.
|
4
|
+
|
5
|
+
A *~/.favs* file might look something like:
|
6
|
+
|
7
|
+
```
|
8
|
+
#comments are supported so are un-grouped commands like this one
|
9
|
+
#positional-based substitution is also suported
|
10
|
+
pr = "echo $0"
|
11
|
+
|
12
|
+
#a group for all your ssh commands
|
13
|
+
[ssh]
|
14
|
+
google = "ssh -P 25001 jonmbake@74.125.225.224"
|
15
|
+
work = "ssh jbake@207.171.189.228"
|
16
|
+
|
17
|
+
[dev]
|
18
|
+
build = "mvn -Pdev -U clean install"
|
19
|
+
arq = "mvn -Parq-jbossas-remote clean verify -Pdev"
|
20
|
+
|
21
|
+
[Demo]
|
22
|
+
files_mod = "hg status | awk 'NR>2{print $2}' | xargs cat"
|
23
|
+
```
|
24
|
+
|
25
|
+
You get the idea.
|
26
|
+
|
27
|
+
## Getting help
|
28
|
+
|
29
|
+
A CLI utility is not complete without some decent help/documentation. Running *fav* with the *--help* flag will display all available options:
|
30
|
+
|
31
|
+
```
|
32
|
+
$ fav --help
|
33
|
+
```
|
34
|
+
|
35
|
+
The typically format for running a fav command is *fav [options] command_name*, where *options* usually contains an *Action* flag:
|
36
|
+
|
37
|
+
## Fav a command
|
38
|
+
|
39
|
+
A command is added as a *Fav* by using the *-a* action flag. The following command will add a command as a *Fav*:
|
40
|
+
|
41
|
+
```
|
42
|
+
$ fav -a 'echo I am a Test Command' tc
|
43
|
+
```
|
44
|
+
|
45
|
+
Or to *Fav* a command to a group;
|
46
|
+
|
47
|
+
```
|
48
|
+
$ fav -a 'echo I am a Test Command in a group' -g Demo tgc
|
49
|
+
```
|
50
|
+
|
51
|
+
**In the event that the group does not yet exist when adding a *Fav* to group, the group will be automatically added.**
|
52
|
+
|
53
|
+
You can also always manually add a *Fav* by modifying your *~/.favs* file.
|
54
|
+
|
55
|
+
### String Substitution
|
56
|
+
|
57
|
+
There is support for position string substitution; the syntax is '$<position>' (see the *pr* command in the examle .favs file).
|
58
|
+
|
59
|
+
## Remove a Fav
|
60
|
+
|
61
|
+
A command is removed as a *Fav* by using the *-r* action flag. The following command will remove a command as a *Fav*:
|
62
|
+
|
63
|
+
```
|
64
|
+
$ fav -r tc
|
65
|
+
```
|
66
|
+
|
67
|
+
Or remove a group command:
|
68
|
+
|
69
|
+
```
|
70
|
+
$ fav -r -g Demo files_mod
|
71
|
+
```
|
72
|
+
|
73
|
+
You can also always manually remove a *Fav* by modifying your *~/.favs* file.
|
74
|
+
|
75
|
+
## List Avaliable Favs
|
76
|
+
|
77
|
+
List favs within a group:
|
78
|
+
|
79
|
+
```
|
80
|
+
fav -ls -g ssh
|
81
|
+
```
|
82
|
+
|
83
|
+
List all commands:
|
84
|
+
|
85
|
+
```
|
86
|
+
fav -ls -g
|
87
|
+
```
|
88
|
+
## Run a Fav
|
89
|
+
|
90
|
+
To run a *non-grouped* command:
|
91
|
+
|
92
|
+
```
|
93
|
+
fav tc
|
94
|
+
```
|
95
|
+
|
96
|
+
To run a *single* grouped command:
|
97
|
+
|
98
|
+
```
|
99
|
+
$ fav -g TestGroup tgc
|
100
|
+
```
|
101
|
+
|
102
|
+
Or run the *entire* group of commands:
|
103
|
+
|
104
|
+
```
|
105
|
+
$ fav -g TestGroup --no_prompt
|
106
|
+
```
|
107
|
+
|
108
|
+
When running an entire group of commands the default behavior is to prompt on each command. This can be overridden by supplying the *--no_prompt* flag.
|
data/README.rdoc
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
= command-line-favs - DESCRIBE YOUR GEM
|
2
|
+
|
3
|
+
Author:: YOUR NAME (YOUR EMAIL)
|
4
|
+
Copyright:: Copyright (c) 2014 YOUR NAME
|
5
|
+
|
6
|
+
|
7
|
+
License:: mit, see LICENSE.txt
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
DESCRIBE YOUR GEM HERE
|
12
|
+
|
13
|
+
== Links
|
14
|
+
|
15
|
+
* {Source on Github}[LINK TO GITHUB]
|
16
|
+
* RDoc[LINK TO RDOC.INFO]
|
17
|
+
|
18
|
+
== Install
|
19
|
+
|
20
|
+
== Examples
|
21
|
+
|
22
|
+
== Contributing
|
23
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
def dump_load_path
|
2
|
+
puts $LOAD_PATH.join("\n")
|
3
|
+
found = nil
|
4
|
+
$LOAD_PATH.each do |path|
|
5
|
+
if File.exists?(File.join(path,"rspec"))
|
6
|
+
puts "Found rspec in #{path}"
|
7
|
+
if File.exists?(File.join(path,"rspec","core"))
|
8
|
+
puts "Found core"
|
9
|
+
if File.exists?(File.join(path,"rspec","core","rake_task"))
|
10
|
+
puts "Found rake_task"
|
11
|
+
found = path
|
12
|
+
else
|
13
|
+
puts "!! no rake_task"
|
14
|
+
end
|
15
|
+
else
|
16
|
+
puts "!!! no core"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
if found.nil?
|
21
|
+
puts "Didn't find rspec/core/rake_task anywhere"
|
22
|
+
else
|
23
|
+
puts "Found in #{path}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
require 'bundler'
|
27
|
+
require 'rake/clean'
|
28
|
+
|
29
|
+
require 'rake/testtask'
|
30
|
+
|
31
|
+
require 'cucumber'
|
32
|
+
require 'cucumber/rake/task'
|
33
|
+
gem 'rdoc' # we need the installed RDoc gem, not the system one
|
34
|
+
require 'rdoc/task'
|
35
|
+
|
36
|
+
include Rake::DSL
|
37
|
+
|
38
|
+
Bundler::GemHelper.install_tasks
|
39
|
+
|
40
|
+
|
41
|
+
Rake::TestTask.new do |t|
|
42
|
+
t.pattern = 'test/tc_*.rb'
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
CUKE_RESULTS = 'results.html'
|
47
|
+
CLEAN << CUKE_RESULTS
|
48
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
49
|
+
t.cucumber_opts = "features --format html -o #{CUKE_RESULTS} --format pretty --no-source -x"
|
50
|
+
t.fork = false
|
51
|
+
end
|
52
|
+
|
53
|
+
Rake::RDocTask.new do |rd|
|
54
|
+
|
55
|
+
rd.main = "README.rdoc"
|
56
|
+
|
57
|
+
rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
|
58
|
+
end
|
59
|
+
|
60
|
+
task :default => [:test,:features]
|
61
|
+
|
data/bin/fav
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'methadone'
|
5
|
+
require 'fav.rb'
|
6
|
+
|
7
|
+
class App
|
8
|
+
include Methadone::Main
|
9
|
+
include Methadone::CLILogging
|
10
|
+
include Methadone::SH
|
11
|
+
|
12
|
+
main do |command_name, *command_args|
|
13
|
+
cmd = Fav::CommandFactory.makeCommand(options, command_name, command_args)
|
14
|
+
cmd.run!
|
15
|
+
end
|
16
|
+
|
17
|
+
description "A utility for organizing your commonly used shell commands. Commands are stored in ~/.favs."
|
18
|
+
|
19
|
+
#Define flags
|
20
|
+
on("-a COMMAND_TEXT","--add", "Add a command to the list of favorites")
|
21
|
+
on("-ls", "--list", "List available commands")
|
22
|
+
on("-g GROUP_NAME","--group", "If used with -a flag, will add command to group. Otherwise will run command within group")
|
23
|
+
on("-r","--remove", "Remove a command from the list of favorites")
|
24
|
+
#
|
25
|
+
# Specify switches via:
|
26
|
+
on("--no_prompt", "Skip prompting when running a group of commands")
|
27
|
+
#
|
28
|
+
# Or, just call OptionParser methods on opts
|
29
|
+
#
|
30
|
+
# Require an argument
|
31
|
+
arg :command_name, "Name of command", :optional
|
32
|
+
#
|
33
|
+
# # Make an argument optional
|
34
|
+
# arg :optional_arg, :optional
|
35
|
+
|
36
|
+
version Fav::VERSION
|
37
|
+
|
38
|
+
@log_level = Logger::DEBUG
|
39
|
+
logger.level = Logger::DEBUG
|
40
|
+
|
41
|
+
go!
|
42
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'fav/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "command-line-favs"
|
8
|
+
spec.version = Fav::VERSION
|
9
|
+
spec.authors = ["Jon Bake"]
|
10
|
+
spec.email = ["jmb@jonbake.com"]
|
11
|
+
spec.summary = %q{A CLI utility for organizing your commonly used shell commands.}
|
12
|
+
spec.description = %q{Commands are stored as a Command Name to Command map within your ~/.favs file and can be organized into groups. Stored commands can then be easily ran.}
|
13
|
+
spec.homepage = "https://github.com/jonmbake/command-line-favs"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
22
|
+
spec.add_development_dependency('rdoc', '~> 4.1')
|
23
|
+
spec.add_development_dependency('aruba', '~> 0.5')
|
24
|
+
spec.add_development_dependency('rake', '~> 0.9')
|
25
|
+
spec.add_dependency('methadone', '~> 1.4')
|
26
|
+
spec.add_dependency('parseconfig', '~> 1.0')
|
27
|
+
spec.add_dependency('highline', '~> 1.6')
|
28
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
Feature: Run and save commands
|
2
|
+
In order to organize and run commonly-used commands
|
3
|
+
I want to save commands in an organized fashion
|
4
|
+
And to be able to invoke any saved command easily
|
5
|
+
So I don't have the hassle of creating a bunch of unorganized aliases
|
6
|
+
|
7
|
+
Scenario: Basic UI
|
8
|
+
When I get help for "fav"
|
9
|
+
Then the exit status should be 0
|
10
|
+
And the banner should be present
|
11
|
+
And there should be a one line summary of what the app does
|
12
|
+
And the banner should include the version
|
13
|
+
And the banner should document that this app takes options
|
14
|
+
And the banner should document that this app's arguments are:
|
15
|
+
|command_name|which is required|
|
16
|
+
|
17
|
+
Scenario: Add a Command
|
18
|
+
When I run `fav -a 'man cp' mc`
|
19
|
+
Then the ungrouped command "man cp" is added with name "mc"
|
20
|
+
|
21
|
+
Scenario: Add a Command to a Group
|
22
|
+
When I run `fav -a 'ls -l' -g TestGroup gr`
|
23
|
+
Then the command "ls -l" is added with name "gr" to the group "TestGroup"
|
24
|
+
|
25
|
+
Scenario: Remove an Ungrouped Command
|
26
|
+
Given a file named "/tmp/home/.favs" with:
|
27
|
+
"""
|
28
|
+
ef = "echo Foo"
|
29
|
+
eb = "echo Bar"
|
30
|
+
"""
|
31
|
+
When I run `fav -r ef`
|
32
|
+
Then the command with name "ef" no longer exists as a fav
|
33
|
+
And the ungrouped command "echo Bar" is added with name "eb"
|
34
|
+
|
35
|
+
Scenario: Remove a Grouped Command
|
36
|
+
Given a file named "/tmp/home/.favs" with:
|
37
|
+
"""
|
38
|
+
[test]
|
39
|
+
ef = "echo Foo"
|
40
|
+
eb = "echo Bar"
|
41
|
+
"""
|
42
|
+
When I run `fav -g test -r ef`
|
43
|
+
Then the command with name "ef" no longer exists as a fav in the group "test"
|
44
|
+
And the command "echo Bar" is added with name "eb" to the group "test"
|
45
|
+
|
46
|
+
Scenario: Run a Command
|
47
|
+
Given a file named "/tmp/home/.favs" with:
|
48
|
+
"""
|
49
|
+
cpt = "touch /tmp/home/test.txt"
|
50
|
+
"""
|
51
|
+
When I run `fav cpt`
|
52
|
+
Then the file "test.txt" exists in "/tmp/home"
|
53
|
+
|
54
|
+
Scenario: Run a Grouped Command
|
55
|
+
Given a file named "/tmp/home/.favs" with:
|
56
|
+
"""
|
57
|
+
[test]
|
58
|
+
cpt = "touch /tmp/home/test2.txt"
|
59
|
+
"""
|
60
|
+
When I run `fav -g test cpt`
|
61
|
+
Then the file "test2.txt" exists in "/tmp/home"
|
62
|
+
|
63
|
+
Scenario: Run an entire group of commands
|
64
|
+
Given a file named "/tmp/home/.favs" with:
|
65
|
+
"""
|
66
|
+
[test]
|
67
|
+
cpt2 = "touch /tmp/home/test2.txt"
|
68
|
+
cpt = "touch /tmp/home/test.txt"
|
69
|
+
"""
|
70
|
+
When I run `fav -g test --no_prompt`
|
71
|
+
Then the file "test2.txt" exists in "/tmp/home"
|
72
|
+
And the file "test.txt" exists in "/tmp/home"
|
73
|
+
|
74
|
+
Scenario: Run a command that prepends text to the end
|
75
|
+
Given a file named "/tmp/home/.favs" with:
|
76
|
+
"""
|
77
|
+
e = "echo $0"
|
78
|
+
"""
|
79
|
+
When I run `fav e 'foo'`
|
80
|
+
Then it should pass with:
|
81
|
+
"""
|
82
|
+
foo
|
83
|
+
"""
|
84
|
+
|
85
|
+
Scenario: Add a Command without a Command Name
|
86
|
+
When I run `fav -a 'echo I am a command'`
|
87
|
+
Then it should fail with:
|
88
|
+
"""
|
89
|
+
Must specify command name when adding a fav.
|
90
|
+
"""
|
91
|
+
|
92
|
+
Scenario: Remove a Command without a Command Name
|
93
|
+
When I run `fav -r`
|
94
|
+
Then it should fail with:
|
95
|
+
"""
|
96
|
+
Must specify command name when removing a fav.
|
97
|
+
"""
|
98
|
+
|
99
|
+
Scenario: Run a command for a group that doesn't exist
|
100
|
+
When I run `fav -g NotAGroup cmd`
|
101
|
+
Then it should fail with:
|
102
|
+
"""
|
103
|
+
Specified group does not exist.
|
104
|
+
"""
|
105
|
+
|
106
|
+
Scenario: List commands within a group
|
107
|
+
Given a file named "/tmp/home/.favs" with:
|
108
|
+
"""
|
109
|
+
ug = "echo ungrouped"
|
110
|
+
[test]
|
111
|
+
ef = "echo Foo"
|
112
|
+
eb = "echo Bar"
|
113
|
+
"""
|
114
|
+
When I run `fav -ls -g test`
|
115
|
+
Then it should pass with exactly:
|
116
|
+
"""
|
117
|
+
ef = "echo Foo"
|
118
|
+
eb = "echo Bar"
|
119
|
+
|
120
|
+
"""
|
121
|
+
|
122
|
+
Scenario: List all commands
|
123
|
+
Given a file named "/tmp/home/.favs" with:
|
124
|
+
"""
|
125
|
+
ug = "echo ungrouped"
|
126
|
+
[test]
|
127
|
+
ef = "echo Foo"
|
128
|
+
eb = "echo Bar"
|
129
|
+
"""
|
130
|
+
When I run `fav -ls`
|
131
|
+
Then it should pass with exactly:
|
132
|
+
"""
|
133
|
+
ug = "echo ungrouped"
|
134
|
+
[test]
|
135
|
+
ef = "echo Foo"
|
136
|
+
eb = "echo Bar"
|
137
|
+
|
138
|
+
"""
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'parseconfig'
|
2
|
+
|
3
|
+
Then(/^the ungrouped command "(.*?)" is added with name "(.*?)"$/) do |command, name|
|
4
|
+
config = ParseConfig.new("#{ENV['HOME']}/.favs")
|
5
|
+
expect(config[name]).to eq(command)
|
6
|
+
end
|
7
|
+
|
8
|
+
Then(/^the command "(.*?)" is added with name "(.*?)" to the group "(.*?)"$/) do |command, name, group|
|
9
|
+
config = ParseConfig.new("#{ENV['HOME']}/.favs")
|
10
|
+
expect(config[group][name]).to eq(command)
|
11
|
+
end
|
12
|
+
|
13
|
+
Then(/^the file "(.*?)" exists in "(.*?)"$/) do |file_name, dir|
|
14
|
+
expect(File.exist?("#{dir}/#{file_name}")).to be true
|
15
|
+
end
|
16
|
+
|
17
|
+
Then(/^the command with name "(.*?)" no longer exists as a fav in the group "(.*?)"$/) do |name, group|
|
18
|
+
config = ParseConfig.new("#{ENV['HOME']}/.favs")
|
19
|
+
expect(config[group][name]).to be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
Then(/^the command with name "(.*?)" no longer exists as a fav$/) do |name|
|
23
|
+
config = ParseConfig.new("#{ENV['HOME']}/.favs")
|
24
|
+
expect(config[name]).to be_nil
|
25
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'aruba/cucumber'
|
2
|
+
require 'methadone/cucumber'
|
3
|
+
|
4
|
+
ENV['PATH'] = "#{File.expand_path(File.dirname(__FILE__) + '/../../bin')}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
|
5
|
+
LIB_DIR = File.join(File.expand_path(File.dirname(__FILE__)),'..','..','lib')
|
6
|
+
|
7
|
+
Before do
|
8
|
+
# Using "announce" causes massive warnings on 1.9.2
|
9
|
+
@puts = true
|
10
|
+
@original_rubylib = ENV['RUBYLIB']
|
11
|
+
ENV['RUBYLIB'] = LIB_DIR + File::PATH_SEPARATOR + ENV['RUBYLIB'].to_s
|
12
|
+
|
13
|
+
@original_home = ENV['HOME']
|
14
|
+
ENV['HOME'] = "/tmp/home"
|
15
|
+
FileUtils.rm_rf "/tmp/home"
|
16
|
+
FileUtils.mkdir "/tmp/home"
|
17
|
+
end
|
18
|
+
|
19
|
+
After do
|
20
|
+
ENV['RUBYLIB'] = @original_rubylib
|
21
|
+
ENV['HOME'] = @original_home
|
22
|
+
end
|
data/lib/fav/version.rb
ADDED
data/lib/fav.rb
ADDED
@@ -0,0 +1,179 @@
|
|
1
|
+
require "fav/version"
|
2
|
+
require 'methadone'
|
3
|
+
require 'parseconfig'
|
4
|
+
require "highline/import"
|
5
|
+
|
6
|
+
module Fav
|
7
|
+
|
8
|
+
# A Factory to Create Commands.
|
9
|
+
#
|
10
|
+
# The type of command that is created is based on the "action" cli option passed in;
|
11
|
+
# These include: Add (-a), Remove (-r), List (-ls). The default action is the Run Command.
|
12
|
+
class CommandFactory
|
13
|
+
# Static Factory Method
|
14
|
+
def self.makeCommand(cli_options, command_name, command_args)
|
15
|
+
if cli_options[:add]
|
16
|
+
command_name_check(command_name, 'adding')
|
17
|
+
AddCommand.new(cli_options, command_name, command_args, {bypass_group_check: true})
|
18
|
+
elsif cli_options[:remove]
|
19
|
+
command_name_check(command_name, 'removing')
|
20
|
+
RemoveCommand.new(cli_options, command_name, command_args)
|
21
|
+
elsif cli_options [:list]
|
22
|
+
ListCommand.new(cli_options, command_name, command_args)
|
23
|
+
else
|
24
|
+
RunCommand.new(cli_options, command_name, command_args)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Checks that command name is given, if it is not raise an exception
|
29
|
+
def self.command_name_check(command_name, operation)
|
30
|
+
raise "Must specify command name when #{operation} a fav." unless command_name
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Base class for all commands
|
35
|
+
class FavCommand
|
36
|
+
include Methadone::CLILogging
|
37
|
+
include Methadone::SH
|
38
|
+
|
39
|
+
attr_reader :favs_file, :config, :cli_options, :command_name, :command_args, :command_options
|
40
|
+
|
41
|
+
def initialize(cli_options, command_name, command_args, command_options={})
|
42
|
+
@favs_file = "#{ENV['HOME']}/.favs"
|
43
|
+
# if ~/.favs file does not exist, create it
|
44
|
+
FileUtils.touch self.favs_file unless File.exist?(self.favs_file)
|
45
|
+
|
46
|
+
# parse ~/.favs
|
47
|
+
@config = ParseConfig.new(self.favs_file)
|
48
|
+
|
49
|
+
@cli_options = cli_options
|
50
|
+
@command_name = command_name
|
51
|
+
@command_args = command_args
|
52
|
+
@command_options = command_options
|
53
|
+
end
|
54
|
+
|
55
|
+
# Run the Command!
|
56
|
+
def run!
|
57
|
+
# specify callbacks for when the command is grouped or ungrouped
|
58
|
+
if self.cli_options[:group]
|
59
|
+
#raise error if group doesn't exist, unless bypass is specified
|
60
|
+
raise "Specified group does not exist." unless self.config[self.cli_options[:group]] || self.command_options[:bypass_group_check]
|
61
|
+
on_group(self.cli_options[:group])
|
62
|
+
else
|
63
|
+
on_non_group
|
64
|
+
end
|
65
|
+
post_group
|
66
|
+
end
|
67
|
+
|
68
|
+
# A hook called after the "grouping" method
|
69
|
+
def post_group
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Run a command specified as a Fav.
|
74
|
+
class RunCommand < FavCommand
|
75
|
+
# Run grouped command
|
76
|
+
def on_group(group)
|
77
|
+
# If we are running a grouped command, we must check if we are running the entire group or an individual command within a group.
|
78
|
+
if self.command_name
|
79
|
+
run_cmd self.config[group][self.command_name]
|
80
|
+
else
|
81
|
+
input = self.cli_options[:no_prompt] ? 'C' : 'N'
|
82
|
+
self.config[group].each do |key, value|
|
83
|
+
# don't re-prompt if they have chosen to continue
|
84
|
+
input = ask "Run command: #{value}? [(Y)es, (N)o, (C)ontinue, (B)reak]" unless input == 'C'
|
85
|
+
case input
|
86
|
+
when 'Y', 'C'
|
87
|
+
sh value
|
88
|
+
when 'B'
|
89
|
+
puts 'Breaking the execution of all remaining commands in group.'
|
90
|
+
break
|
91
|
+
else #'N' or some unrecognized option
|
92
|
+
puts "Skipping the execution of #{value}"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Run non-grouped command
|
99
|
+
def on_non_group
|
100
|
+
run_cmd self.config[self.command_name]
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
def run_cmd(cmd)
|
105
|
+
unless cmd
|
106
|
+
error "Command does not exist"
|
107
|
+
return
|
108
|
+
end
|
109
|
+
cmd = cmd.gsub(/\$\d+/) do |d|
|
110
|
+
cmd_arg = command_args[d[1..-1].to_i]
|
111
|
+
error "Missing command argument at position #{d[1..-1]}" unless cmd_arg
|
112
|
+
cmd_arg
|
113
|
+
end
|
114
|
+
sh cmd
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# A command to list commands
|
119
|
+
class ListCommand < FavCommand
|
120
|
+
# List commands in the group
|
121
|
+
def on_group(group)
|
122
|
+
self.config[group].each { |cmd_name, cmd_value| print_command(cmd_name, cmd_value) }
|
123
|
+
end
|
124
|
+
|
125
|
+
# List all commands
|
126
|
+
def on_non_group
|
127
|
+
file = File.open(self.favs_file, "rb")
|
128
|
+
puts file.read
|
129
|
+
end
|
130
|
+
|
131
|
+
private
|
132
|
+
# Print command name/value to console
|
133
|
+
def print_command(cmd_name, cmd_val)
|
134
|
+
puts "#{cmd_name} = \"#{cmd_val}\""
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# A command that writes back to the Favs file
|
139
|
+
class WritableCommand < FavCommand
|
140
|
+
# Write the contents after performing the command
|
141
|
+
def post_group
|
142
|
+
file = File.open("#{ENV['HOME']}/.favs", 'w')
|
143
|
+
self.config.write(file)
|
144
|
+
file.close
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# A command to add a Fav
|
149
|
+
class AddCommand < WritableCommand
|
150
|
+
# Add a grouped fav
|
151
|
+
def on_group(group)
|
152
|
+
self.config.add_to_group(group, self.command_name, self.cli_options[:add])
|
153
|
+
puts "Successfully added #{self.command_name} to the '#{group}' group!"
|
154
|
+
end
|
155
|
+
|
156
|
+
# Add a non-grouped fav
|
157
|
+
def on_non_group
|
158
|
+
self.config.add(self.command_name, self.cli_options[:add])
|
159
|
+
puts "Successfully added #{self.command_name}"
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# A command to remove a fav
|
164
|
+
class RemoveCommand < WritableCommand
|
165
|
+
# Remove a grouped fav
|
166
|
+
def on_group(group)
|
167
|
+
#raise error if command they are attempting to remove doesn't exist
|
168
|
+
raise "Can not remove command because it doesn't exist" unless self.config[group][self.command_name]
|
169
|
+
self.config[group].delete(self.command_name)
|
170
|
+
puts "Successfully removed #{self.command_name} from the '#{group}' group!"
|
171
|
+
end
|
172
|
+
|
173
|
+
# Remove a non-grouped fav
|
174
|
+
def on_non_group
|
175
|
+
self.config.params.delete(self.command_name)
|
176
|
+
puts "Successfully removed #{self.command_name}"
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
metadata
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: command-line-favs
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jon Bake
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-05-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rdoc
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.1'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: aruba
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.5'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.5'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.9'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.9'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: methadone
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.4'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.4'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: parseconfig
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: highline
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ~>
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.6'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.6'
|
111
|
+
description: Commands are stored as a Command Name to Command map within your ~/.favs
|
112
|
+
file and can be organized into groups. Stored commands can then be easily ran.
|
113
|
+
email:
|
114
|
+
- jmb@jonbake.com
|
115
|
+
executables:
|
116
|
+
- fav
|
117
|
+
extensions: []
|
118
|
+
extra_rdoc_files: []
|
119
|
+
files:
|
120
|
+
- .gitignore
|
121
|
+
- Gemfile
|
122
|
+
- Gemfile.lock
|
123
|
+
- LICENSE.txt
|
124
|
+
- README.md
|
125
|
+
- README.rdoc
|
126
|
+
- Rakefile
|
127
|
+
- bin/fav
|
128
|
+
- command-line-favs.gemspec
|
129
|
+
- features/command-line-favs.feature
|
130
|
+
- features/step_definitions/command-line-favs_steps.rb
|
131
|
+
- features/support/env.rb
|
132
|
+
- lib/fav.rb
|
133
|
+
- lib/fav/version.rb
|
134
|
+
- test/tc_something.rb
|
135
|
+
homepage: https://github.com/jonmbake/command-line-favs
|
136
|
+
licenses:
|
137
|
+
- MIT
|
138
|
+
metadata: {}
|
139
|
+
post_install_message:
|
140
|
+
rdoc_options: []
|
141
|
+
require_paths:
|
142
|
+
- lib
|
143
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
144
|
+
requirements:
|
145
|
+
- - '>='
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
version: '0'
|
148
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - '>='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
requirements: []
|
154
|
+
rubyforge_project:
|
155
|
+
rubygems_version: 2.2.2
|
156
|
+
signing_key:
|
157
|
+
specification_version: 4
|
158
|
+
summary: A CLI utility for organizing your commonly used shell commands.
|
159
|
+
test_files:
|
160
|
+
- features/command-line-favs.feature
|
161
|
+
- features/step_definitions/command-line-favs_steps.rb
|
162
|
+
- features/support/env.rb
|
163
|
+
- test/tc_something.rb
|