mycommands 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/Gemfile +4 -0
  2. data/Gemfile.lock +28 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +50 -0
  5. data/Rakefile +21 -0
  6. data/bin/mycommands +16 -0
  7. data/lib/mycommands.rb +31 -0
  8. data/lib/mycommands/application.rb +43 -0
  9. data/lib/mycommands/categories.yml +11 -0
  10. data/lib/mycommands/commands.yml +127 -0
  11. data/lib/mycommands/controllers/application_controller.rb +15 -0
  12. data/lib/mycommands/controllers/category_controller.rb +15 -0
  13. data/lib/mycommands/controllers/command_controller.rb +28 -0
  14. data/lib/mycommands/controllers/controller.rb +27 -0
  15. data/lib/mycommands/controllers/param_controller.rb +25 -0
  16. data/lib/mycommands/factory.rb +13 -0
  17. data/lib/mycommands/models/category.rb +77 -0
  18. data/lib/mycommands/models/command.rb +72 -0
  19. data/lib/mycommands/models/model.rb +10 -0
  20. data/lib/mycommands/models/param.rb +51 -0
  21. data/lib/mycommands/router.rb +31 -0
  22. data/lib/mycommands/version.rb +3 -0
  23. data/lib/mycommands/views/application_view.rb +8 -0
  24. data/lib/mycommands/views/category_view.rb +16 -0
  25. data/lib/mycommands/views/command_view.rb +21 -0
  26. data/lib/mycommands/views/param_view.rb +9 -0
  27. data/lib/mycommands/views/view.rb +57 -0
  28. data/mycommands.gemspec +25 -0
  29. data/test/categories.yml +6 -0
  30. data/test/commands.yml +16 -0
  31. data/test/integration/integration_test.rb +42 -0
  32. data/test/test_helper.rb +3 -0
  33. data/test/units/category_test.rb +27 -0
  34. data/test/units/command_model_test.rb +15 -0
  35. data/test/units/command_test.rb +29 -0
  36. data/test/units/factory_test.rb +9 -0
  37. data/test/units/param_model_test.rb +13 -0
  38. data/test/units/param_test.rb +23 -0
  39. data/test/units/router_test.rb +18 -0
  40. metadata +149 -0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mycommands.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,28 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ mycommands (1.0.0)
5
+ clipboard (~> 1.0.1)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ clipboard (1.0.1)
11
+ coderay (1.0.8)
12
+ method_source (0.8.1)
13
+ minitest (4.5.0)
14
+ pry (0.9.11.4)
15
+ coderay (~> 1.0.5)
16
+ method_source (~> 0.8)
17
+ slop (~> 3.4)
18
+ rake (10.0.3)
19
+ slop (3.4.3)
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ minitest (~> 4.5.0)
26
+ mycommands!
27
+ pry (~> 0.9.11.4)
28
+ rake (~> 10.0.3)
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Nils Eriksson
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,50 @@
1
+ README
2
+ =================
3
+
4
+ About
5
+ -----
6
+
7
+ Often when I need a solution for a specific task I do a google search to find out what command I can use. Before I made this script I had a text file with commands saved that I wanted to rember.
8
+ This script makes it easier to fetch and organize my favourite commands.
9
+
10
+ Screenshot
11
+ ----------
12
+
13
+ <img src="http://img190.imageshack.us/img190/521/mycommands.png" />
14
+
15
+ Installing
16
+ ----------
17
+
18
+ <pre>
19
+ gem install mycommands
20
+ </pre>
21
+
22
+ Usage
23
+ -----
24
+
25
+ $ mycommands
26
+
27
+ Use "0" (zero) to go back to the previous listing of categories and commands.
28
+ "q" will quit the script while browsing for commands.
29
+
30
+ Choose the command you need and fill in the parameters if there are any.
31
+ You can use tab expansion while filling in the parameters.
32
+
33
+ Parameters can have a default value in (). If you just press enter the default value will be used.
34
+
35
+ About the yml files
36
+ -------------------
37
+
38
+ If the script finds categories.yml or commands.yml in ~/Mycommands
39
+ those files will be used instead of the default ones.
40
+
41
+ Categories in categories.yml that has no subcategories has to end with a trailing blank space.
42
+
43
+ The format of commands in commands.yml:
44
+ <pre>
45
+ Command description:
46
+ - Category
47
+ - command PARAM1 PARAM2 PARAM3
48
+ - PARAM1: Example param1
49
+ - PARAM2: Example param2 (default value)
50
+ </pre>
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+ Rake::TestTask.new do |t|
4
+ t.libs << "test"
5
+ t.test_files = FileList['test/**/*_test.rb']
6
+ t.verbose = true
7
+ end
8
+
9
+ namespace 'test' do
10
+ Rake::TestTask.new(:units) do |t|
11
+ t.libs << "test"
12
+ t.test_files = FileList['test/units/*_test.rb']
13
+ t.verbose = true
14
+ end
15
+
16
+ Rake::TestTask.new(:integration) do |t|
17
+ t.libs << "test"
18
+ t.test_files = FileList['test/integration/*_test.rb']
19
+ t.verbose = true
20
+ end
21
+ end
data/bin/mycommands ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ module Mycommands
3
+
4
+ DEBUG = ARGV.include? '-d'
5
+ TEST = ARGV.include? '-t'
6
+
7
+ Bundler.require(:default)
8
+
9
+ action = :print_version if ARGV.include?('-v')
10
+
11
+ action = :sort_yaml_files if ARGV.include?('-s')
12
+
13
+ action ||= :run
14
+
15
+ Factory::get(:Application).send(action)
16
+ end
data/lib/mycommands.rb ADDED
@@ -0,0 +1,31 @@
1
+ module Mycommands
2
+ LIBPATH = File.expand_path(File.dirname( __FILE__ ))
3
+ ROOTPATH = File.expand_path("..", LIBPATH)
4
+ YMLPATH = (defined?(TEST) && TEST) ? ROOTPATH + '/test' : LIBPATH + '/mycommands'
5
+ $: << LIBPATH
6
+
7
+ require 'yaml'
8
+ require 'erb'
9
+ require 'readline'
10
+ require "mycommands/version"
11
+ require 'mycommands/application'
12
+ require 'mycommands/router'
13
+ require 'mycommands/factory'
14
+ autoload :Controller, "mycommands/controllers/controller"
15
+ autoload :ApplicationController, "mycommands/controllers/application_controller"
16
+ autoload :CategoryController, "mycommands/controllers/category_controller"
17
+ autoload :CommandController, "mycommands/controllers/command_controller"
18
+ autoload :ParamController, "mycommands/controllers/param_controller"
19
+ autoload :CategoryModel, "mycommands/models/category"
20
+ autoload :Model, "mycommands/models/model"
21
+ autoload :Category, "mycommands/models/category"
22
+ autoload :CommandModel, "mycommands/models/command"
23
+ autoload :Command, "mycommands/models/command"
24
+ autoload :Params, "mycommands/models/param"
25
+ autoload :Param, "mycommands/models/param"
26
+ autoload :View, "mycommands/views/view"
27
+ autoload :ApplicationView, "mycommands/views/application_view"
28
+ autoload :CategoryView, "mycommands/views/category_view"
29
+ autoload :CommandView, "mycommands/views/command_view"
30
+ autoload :ParamView, "mycommands/views/param_view"
31
+ end
@@ -0,0 +1,43 @@
1
+ module Mycommands
2
+ class Application
3
+ def initialize
4
+ @router = Factory::get(:Router)
5
+ end
6
+
7
+ def print_version
8
+ puts "Mycommands #{VERSION}"
9
+ end
10
+
11
+ def sort_yaml_files
12
+ dispatch ['Application', 'sort_yaml_files']
13
+ end
14
+
15
+ def run
16
+ dispatch ['Category', 'index']
17
+ get_input
18
+ end
19
+
20
+ def dispatch args
21
+ controller, action, input= args.map &:to_s
22
+ puts "Dispatching: #{controller}, #{action}, #{input}" if DEBUG
23
+ if input.nil?
24
+ Factory::get(controller+'Controller').send action
25
+ else
26
+ Factory::get(controller+'Controller').send action, input
27
+ end
28
+ end
29
+
30
+ private
31
+ def get_input
32
+ while input = Readline.readline('--> ', true)
33
+ route = @router.route input
34
+ @router.clear_routes
35
+ unless route
36
+ puts "Bye!"
37
+ exit
38
+ end
39
+ dispatch route
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,11 @@
1
+ ---
2
+ Dev:
3
+ Files:
4
+ - ! '':
5
+ - ! '':
6
+ - ! '':
7
+ Git:
8
+ Images:
9
+ SVN:
10
+ Search:
11
+ Sysadmin:
@@ -0,0 +1,127 @@
1
+ ---
2
+ Add bandwidth limit pipe:
3
+ - Dev
4
+ - sudo ipfw pipe 1 config bw 250Kbit/s delay 350ms
5
+ Add pipe:
6
+ - Dev
7
+ - sudo ipfw add 1 pipe 1 src-port PORT
8
+ - PORT: Port to add the pipe to
9
+ Delete pipe:
10
+ - Dev
11
+ - sudo ipfw delete 1
12
+ Delete specific files in cwd recursive:
13
+ - Files
14
+ - find . -name \FILES -CONFIRM rm {} \;
15
+ - FILES: Files to remove (*.svn)
16
+ - CONFIRM: Confirm exec/ok (ok)
17
+ List the size of sub folders:
18
+ - Files
19
+ - du -h --max-depth=1
20
+ Count lines in git repository:
21
+ - Git
22
+ - git ls-files | xargs wc -l
23
+ Reset changed and new files in working directory:
24
+ - Git
25
+ - git reset --hard && git clean -fd
26
+ Downsize images and crop to a certain size:
27
+ - Images
28
+ - mogrify -resize "WIDTHxHEIGHT^" -gravity Center -crop "WIDTHxHEIGHT+0+0" IMAGES
29
+ - WIDTH: Width
30
+ - HEIGHT: Height
31
+ - IMAGES: Images
32
+ Downsize images and crop to a certain size and put in a sub directory:
33
+ - Images
34
+ - mkdir DIR && mogrify -path DIR -resize "WIDTHxHEIGHT^" -gravity Center -crop "WIDTHxHEIGHT+0+0" IMAGES
35
+ - WIDTH: Width
36
+ - HEIGHT: Height
37
+ - DIR: Directory
38
+ - IMAGES: Images
39
+ Change permissons on directories:
40
+ - Permissions
41
+ - find . -type d -name \* -exec chmod RIGHTS {} \;
42
+ - RIGHTS: Permissions (775)
43
+ Change permissons on files:
44
+ - Permissions
45
+ - find . -type f -name \* -exec chmod RIGHTS {} \;
46
+ - RIGHTS: Permissions (775)
47
+ Create branch:
48
+ - SVN
49
+ - SVN copy SOURCE BRANCH_URL -m "Creating a private branch, BRANCH_NAME, of SOURCE."
50
+ - SOURCE: Source url
51
+ - BRANCH_URL: Branch url
52
+ - BRANCH_NAME: Branch name
53
+ Delete branch:
54
+ - SVN
55
+ - SVN delete BRANCH_URL -m "MESSAGE"
56
+ - BRANCH_URL: Url to branch
57
+ - MESSAGE: Commit message
58
+ Get revision for creation of branch:
59
+ - SVN
60
+ - SVN log --stop-on-copy BRANCH_URL
61
+ - BRANCH_URL: Url for branch
62
+ Merge branch:
63
+ - SVN
64
+ - SVN merge -rCOPY_REV:TRUNK_REV BRANCH_URL
65
+ - BRANCH_URL: Branch url
66
+ - TRUNK_REV: Trunk revision
67
+ - COPY_REV: Copy revision
68
+ Find and ignore errors:
69
+ - Search
70
+ - find PATH -name "PATTERN" |& grep -v "Permission denied"
71
+ - PATH: Path to search in
72
+ - PATTERN: Pattern to search for
73
+ Find in files and list files:
74
+ - Search
75
+ - find . -iname 'FILETYPE' | xargs grep 'STRING' -sl
76
+ - STRING: String to search for
77
+ - FILETYPE: In what files (*)
78
+ Search in files and show context:
79
+ - Search
80
+ - find . -iname 'FILETYPE' | xargs grep --color=auto -i -b1 -a1 'STRING'
81
+ - STRING: String to search for
82
+ - FILETYPE: In what files (*)
83
+ Create symlink:
84
+ - Symlinks
85
+ - ln -s TARGET NAME
86
+ - TARGET: Target to link to
87
+ - NAME: Name of link
88
+ Remove broken links:
89
+ - Symlinks
90
+ - find -L . -type l -delete
91
+ Add existing user to existing group:
92
+ - Sysadmin
93
+ - sudo usermod -a -G GROUP USER
94
+ - GROUP: Group
95
+ - USER: User
96
+ Display linux release:
97
+ - Sysadmin
98
+ - cat /etc/lsb-release
99
+ Duplicate database:
100
+ - Sysadmin
101
+ - mysqladmin create NEW -u USER -p && mysqldump -u USER OLD | mysql -u USER -h localhost NEW
102
+ - USER: User
103
+ - OLD: Database to duplicate
104
+ - NEW: Name of new database
105
+ Restart apache:
106
+ - Sysadmin
107
+ - sudo /etc/init.d/apache2 restart
108
+ Restore mysql dump:
109
+ - Sysadmin
110
+ - mysql --user=USER --password=PASSWORD DATABASE < SQL
111
+ - USER: User
112
+ - PASSWORD: Password
113
+ - DATABASE: Database
114
+ - SQL: .sql file
115
+ Show process on port:
116
+ - Sysadmin
117
+ - sudo lsof -i:PORT -P
118
+ - PORT: Port (3000)
119
+ Tar exclude:
120
+ - Tar
121
+ - tar --exclude="EXCLUDE" -czvf NAME FILES
122
+ - EXCLUDE: What to exclude
123
+ - NAME: Name of archive
124
+ - FILES: Files to archive
125
+ Tar exclude example:
126
+ - Tar
127
+ - tar --exclude="dir_to_exclude*" --exclude="exclude_contents/*" -czvf ../backup.tgz .
@@ -0,0 +1,15 @@
1
+ module Mycommands
2
+ class ApplicationController < Controller
3
+ def sort_yaml_files
4
+ @category_file = Factory.get(:CategoryModel).sort_yaml_file!
5
+ @command_file = Factory.get(:CommandModel).sort_yaml_file!
6
+ render
7
+ end
8
+
9
+ private
10
+ def set_model
11
+ false
12
+ end
13
+ end
14
+ end
15
+
@@ -0,0 +1,15 @@
1
+ module Mycommands
2
+ class CategoryController < Controller
3
+ def index choice = nil
4
+ if choice == '0'
5
+ @model.go_back
6
+ elsif !choice.nil?
7
+ @model.choose choice
8
+ end
9
+ @categories = @model.categories
10
+ render if @categories
11
+ Factory::get(:CommandController).index(@model.category)
12
+ end
13
+ end
14
+ end
15
+
@@ -0,0 +1,28 @@
1
+ module Mycommands
2
+ class CommandController < Controller
3
+ def index category
4
+ @category = category
5
+ @commands = @model.commands(category)
6
+ render unless @commands.empty?
7
+ end
8
+
9
+ def show choice
10
+ require 'clipboard'
11
+ @command = @model.command @category, choice
12
+ if @command.has_params?
13
+ Factory::get(:ParamController).show(@command.params)
14
+ return
15
+ end
16
+ render
17
+ Clipboard.copy @command.command_string
18
+ exit
19
+ end
20
+
21
+ def update
22
+ render :show
23
+ Clipboard.copy @command.finished_command
24
+ exit
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,27 @@
1
+ module Mycommands
2
+ class Controller
3
+ def initialize
4
+ @name = self.class.to_s.gsub('Controller', '')
5
+ set_model
6
+ @view = Factory::get(@name+'View')
7
+ @application = Factory::get(:Application)
8
+ end
9
+
10
+ def render action = nil
11
+ instance_variables.each do |i|
12
+ @view.instance_variable_set i, eval(i.to_s) unless %w(@model view application).include? i
13
+ end
14
+ if action
15
+ @view.send(action)
16
+ else
17
+ @view.send(caller(1).first[/`.*'/][1..-2].to_sym)
18
+ end
19
+ end
20
+
21
+ private
22
+ def set_model
23
+ @model = Factory::get(@name+'Model')
24
+ end
25
+ end
26
+ end
27
+
@@ -0,0 +1,25 @@
1
+ module Mycommands
2
+ class ParamController < Controller
3
+ def show params = nil
4
+ @params ||= params
5
+ @param = @params.current_param.description
6
+ render
7
+ end
8
+
9
+ def update input
10
+ @params.current_param.substitute input
11
+ @params.next_param
12
+ if @params.all_substituted?
13
+ @application.dispatch([:Command, :update])
14
+ else
15
+ @application.dispatch([:Param, :show])
16
+ end
17
+ end
18
+
19
+ private
20
+ def set_model
21
+ false
22
+ end
23
+ end
24
+ end
25
+
@@ -0,0 +1,13 @@
1
+ module Mycommands
2
+ class Factory
3
+ @@objects = []
4
+ def self.get _class
5
+ for object in @@objects
6
+ return object if object.class == eval(_class.to_s)
7
+ end
8
+ object = eval(_class.to_s).new
9
+ @@objects.push object
10
+ object
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,77 @@
1
+ module Mycommands
2
+ class CategoryModel < Model
3
+ def initialize
4
+ @choices = []
5
+ end
6
+
7
+ def choose choice
8
+ @choices.push choice.to_i - 1
9
+ self
10
+ end
11
+
12
+ def go_back
13
+ @choices.pop
14
+ self
15
+ end
16
+
17
+ def categories choices = @choices
18
+ categories = choices.inject(all_categories) {|categories, choice| categories = categories[choice].children}
19
+ return nil if categories.nil?
20
+ categories
21
+ end
22
+
23
+ def category
24
+ return nil if @choices.empty?
25
+ categories(@choices[0..-2])[@choices[-1]].name
26
+ end
27
+
28
+ def sort_yaml_file!
29
+ category_hash = all_categories.inject({}) {|category_hash, c| category_hash.merge!(c.to_hash)}
30
+ file = File.open(default_or_user_yml('categories.yml'), 'w')
31
+ file.write(category_hash.to_yaml)
32
+ file.path
33
+ end
34
+
35
+ private
36
+ def all_categories
37
+ @all_categories ||= load_categories.sort
38
+ end
39
+
40
+ def load_categories
41
+ YAML::load(File.open(default_or_user_yml('categories.yml'))).map {|c| Category.new(c)}
42
+ end
43
+ end
44
+
45
+ class Category
46
+ def initialize category
47
+ @category = category
48
+ if has_children?
49
+ self.children = children.to_a.map{|c| Category.new(c)}.sort
50
+ end
51
+ end
52
+
53
+ def children
54
+ @category[1]
55
+ end
56
+
57
+ def children= children
58
+ @category[1] = children
59
+ end
60
+
61
+ def has_children?
62
+ !children.nil?
63
+ end
64
+
65
+ def name
66
+ @category[0]
67
+ end
68
+
69
+ def <=> other
70
+ self.name <=> other.name
71
+ end
72
+
73
+ def to_hash
74
+ {@category[0] => has_children? ? children.map(&:to_hash) : nil }
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,72 @@
1
+ module Mycommands
2
+ class CommandModel < Model
3
+ def commands category
4
+ all_commands.select {|c| c.category == category}
5
+ end
6
+
7
+ def command category, index
8
+ commands(category)[index.to_i]
9
+ end
10
+
11
+ def sort_yaml_file!
12
+ command_hash = all_commands.inject({}) {|command_hash, c| command_hash.merge!(c.to_hash) }
13
+ file = File.open(default_or_user_yml('commands.yml'), 'w')
14
+ file.write(command_hash.to_yaml(line_width: -1))
15
+ file.path
16
+ end
17
+
18
+ private
19
+ def all_commands
20
+ @all_commands ||= begin
21
+ YAML::load(File.open(default_or_user_yml('commands.yml'))).to_a.map {|c| Command.new(c)}.sort
22
+ end
23
+ end
24
+ end
25
+
26
+ class Command
27
+ attr_accessor :params
28
+
29
+ def initialize command
30
+ @command = command
31
+ end
32
+
33
+ def description
34
+ @command[0]
35
+ end
36
+
37
+ def category
38
+ @command[1][0]
39
+ end
40
+
41
+ def command_string
42
+ @command[1][1]
43
+ end
44
+
45
+ def params
46
+ return nil unless has_params?
47
+ @params ||= Params.new(@command[1][2..-1].reverse)
48
+ end
49
+
50
+ def has_params?
51
+ @has_params ||= @command[1].size > 2
52
+ end
53
+
54
+ def finished_command
55
+ finished_command = command_string
56
+ if has_params?
57
+ @params.each do |param|
58
+ finished_command = finished_command.gsub(param.value, param.substituted)
59
+ end
60
+ end
61
+ finished_command
62
+ end
63
+
64
+ def to_hash
65
+ {@command[0] => @command[1]}
66
+ end
67
+
68
+ def <=> other
69
+ [self.category, self.description] <=> [other.category, other.description]
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,10 @@
1
+ module Mycommands
2
+ class Model
3
+ private
4
+ def default_or_user_yml file
5
+ default_yml = "#{YMLPATH}/#{file}"
6
+ user_yml = "#{ENV['HOME']}/Mycommands/#{file}"
7
+ File.exist?(user_yml) ? user_yml : default_yml
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,51 @@
1
+ module Mycommands
2
+ class Params
3
+ include Enumerable
4
+ attr_reader :params, :param, :current_param_index
5
+ def initialize params
6
+ @current_param_index = 0
7
+ @params = params.map {|p| Param.new(p)}
8
+ end
9
+
10
+ def current_param
11
+ @params.reverse[@current_param_index]
12
+ end
13
+
14
+ def next_param
15
+ @current_param_index += 1
16
+ end
17
+
18
+ def all_substituted?
19
+ @current_param_index == @params.size
20
+ end
21
+
22
+ def each
23
+ for p in @params do
24
+ yield p
25
+ end
26
+ end
27
+ end
28
+
29
+ class Param
30
+ attr_reader :substituted
31
+
32
+ def initialize param
33
+ @param = param
34
+ end
35
+
36
+ def description
37
+ @param.values.flatten.first.to_s
38
+ end
39
+
40
+ def value
41
+ @param.keys.first.to_s
42
+ end
43
+
44
+ def substitute input
45
+ if input.empty? and description.include? "("
46
+ input = description[/\((.*?)\)/, 1]
47
+ end
48
+ @substituted = input
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,31 @@
1
+ module Mycommands
2
+ class Router
3
+ def initialize
4
+ @routes = []
5
+ @choice = 1
6
+ end
7
+
8
+ def add_route route
9
+ if route[:match].nil?
10
+ route.merge!(:match => @choice.to_s)
11
+ @choice += 1
12
+ end
13
+ @routes.push route
14
+ return @choice - 1
15
+ end
16
+
17
+ def clear_routes
18
+ @routes = []
19
+ @choice = 1
20
+ end
21
+
22
+ def route input
23
+ @routes.each do |route|
24
+ if input.match route[:match]
25
+ return route[:controller], route[:action], route[:input].nil? ? input : route[:input]
26
+ end
27
+ end
28
+ false
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ module Mycommands
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,8 @@
1
+ module Mycommands
2
+ class ApplicationView < View
3
+ def sort_yaml_files
4
+ print "#{@category_file} has been sorted."
5
+ print "#{@command_file} has been sorted."
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,16 @@
1
+ module Mycommands
2
+ class CategoryView < View
3
+ def index
4
+ add_default_routes
5
+ if @category
6
+ header "Categories in \"#{@category}\""
7
+ else
8
+ header "Categories"
9
+ end
10
+ @categories.each_with_index do |(category, value), index|
11
+ choice = @router.add_route(:controller => :Category, :action => :index, :input => (index+1).to_s)
12
+ print "#{choice} - #{category.name.cyan}"
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,21 @@
1
+ module Mycommands
2
+ class CommandView < View
3
+ def index
4
+ add_default_routes
5
+ header "Commands in \"#{@category}\""
6
+ @commands.each_with_index do |(command, value), index|
7
+ choice = @router.add_route(:controller => :Command, :action => :show, :input => index.to_s)
8
+ print "#{choice} - #{command.description.green}"
9
+ end
10
+ end
11
+
12
+ def show
13
+ print "\nThe command below has been copied to the clipboard
14
+ #{@command.finished_command.green}\n\n"
15
+ end
16
+
17
+ def empty_category category
18
+ print "No commands or categories in \"#{category}\""
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,9 @@
1
+ module Mycommands
2
+ class ParamView < View
3
+ def show
4
+ header :"Parameters for command" if @params.current_param_index == 0
5
+ print " #{@param}?".yellow
6
+ @router.add_route(:match => '.|^', :controller => :Param, :action => :update, :input => @result)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,57 @@
1
+ # For more formating options:
2
+ # http://en.wikipedia.org/wiki/ANSI_escape_code#Codes
3
+
4
+ class String
5
+ def normal
6
+ self
7
+ end
8
+ def underline
9
+ "\e[4m#{self}\e[0m"
10
+ end
11
+ def black
12
+ "\e[30m#{self}\e[0m"
13
+ end
14
+ def red
15
+ "\e[91m#{self}\e[0m"
16
+ end
17
+ def green
18
+ "\e[92m#{self}\e[0m"
19
+ end
20
+ def yellow
21
+ "\e[93m#{self}\e[0m"
22
+ end
23
+ def blue
24
+ "\e[94m#{self}\e[0m"
25
+ end
26
+ def cyan
27
+ "\e[96m#{self}\e[0m"
28
+ end
29
+ end
30
+
31
+ module Mycommands
32
+
33
+ class Printer
34
+ def print string
35
+ puts string
36
+ end
37
+ end
38
+
39
+ class View
40
+ def initialize printer = Factory::get(:Printer)
41
+ @router = Factory::get(:Router)
42
+ @printer = printer
43
+ end
44
+
45
+ def print string
46
+ @printer.print string
47
+ end
48
+
49
+ def header text
50
+ print "\n "+"#{text}".underline
51
+ end
52
+
53
+ def add_default_routes
54
+ @router.add_route(:match => '0', :controller => "Category", :action => "index", :input => '0')
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ require 'mycommands/version'
6
+
7
+ Gem::Specification.new do |gem|
8
+ gem.name = "mycommands"
9
+ gem.version = Mycommands::VERSION
10
+ gem.authors = ["Nils Eriksson"]
11
+ gem.email = ["nils.epost@gmail.com"]
12
+ gem.description = %q{Often when I need a solution for a specific task I do a google search to find out what command I can use. Before I made this script I had a text file with commands saved that I wanted to rember. This script makes it easier to fetch and organize my favourite commands.}
13
+ gem.summary = %q{Small console app to manage your favourite commands}
14
+ gem.homepage = "https://github.com/nilseriksson/Mycommands"
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
20
+ gem.add_dependency "clipboard", "~> 1.0.1"
21
+ gem.add_development_dependency "minitest", "~> 4.5.0"
22
+ gem.add_development_dependency "pry", "~> 0.9.11.4"
23
+ gem.add_development_dependency "rake", "~> 10.0.3"
24
+
25
+ end
@@ -0,0 +1,6 @@
1
+ Files:
2
+ Tar:
3
+ Symlinks:
4
+ Permissions:
5
+ Search:
6
+ Images:
data/test/commands.yml ADDED
@@ -0,0 +1,16 @@
1
+ List the size of sub folders:
2
+ - Files
3
+ - du -h --max-depth=1
4
+ Delete specific files in cwd recursive:
5
+ - Files
6
+ - find . -name \FILES -CONFIRM rm {} \;
7
+ - FILES: Files to remove (*.svn)
8
+ - CONFIRM: Confirm exec/ok (ok)
9
+ Remove broken links:
10
+ - Symlinks
11
+ - find -L . -type l -delete
12
+ Create symlink:
13
+ - Symlinks
14
+ - ln -s TARGET NAME
15
+ - TARGET: Target to link to
16
+ - NAME: Name of link
@@ -0,0 +1,42 @@
1
+ require_relative '../test_helper'
2
+ require 'open3'
3
+ require 'io/wait'
4
+
5
+ class TestIntegration < MiniTest::Unit::TestCase
6
+ def test_command_with_params
7
+ output = run_app(%w(1 4 *.exe ok))
8
+ assert_equal("\n \e[4mCategories\e[0m\n1 - \e[96mFiles\e[0m\n2 - \e[96mImages\e[0m\n3 - \e[96mSearch\e[0m\n\n \e[4mCategories\e[0m\n1 - \e[96mPermissions\e[0m\n2 - \e[96mSymlinks\e[0m\n3 - \e[96mTar\e[0m\n\n \e[4mCommands in \"Files\"\e[0m\n4 - \e[92mDelete specific files in cwd recursive\e[0m\n5 - \e[92mList the size of sub folders\e[0m\n\n \e[4mParameters for command\e[0m\n\e[93m Files to remove (*.svn)?\e[0m\n\e[93m Confirm exec/ok (ok)?\e[0m\n\nThe command below has been copied to the clipboard\n\e[92mfind . -name \\*.exe -ok rm {} \\;\e[0m\n\n", output)
9
+ end
10
+
11
+ def test_command_without_params
12
+ output = run_app(%w(1 5))
13
+ assert_equal("\n \e[4mCategories\e[0m\n1 - \e[96mFiles\e[0m\n2 - \e[96mImages\e[0m\n3 - \e[96mSearch\e[0m\n\n \e[4mCategories\e[0m\n1 - \e[96mPermissions\e[0m\n2 - \e[96mSymlinks\e[0m\n3 - \e[96mTar\e[0m\n\n \e[4mCommands in \"Files\"\e[0m\n4 - \e[92mDelete specific files in cwd recursive\e[0m\n5 - \e[92mList the size of sub folders\e[0m\n\nThe command below has been copied to the clipboard\n\e[92mdu -h --max-depth=1\e[0m\n\n", output)
14
+ end
15
+
16
+ def test_go_back_and_quit
17
+ output = run_app(%w(1 0 r))
18
+ assert_equal("\n \e[4mCategories\e[0m\n1 - \e[96mFiles\e[0m\n2 - \e[96mImages\e[0m\n3 - \e[96mSearch\e[0m\n\n \e[4mCategories\e[0m\n1 - \e[96mPermissions\e[0m\n2 - \e[96mSymlinks\e[0m\n3 - \e[96mTar\e[0m\n\n \e[4mCommands in \"Files\"\e[0m\n4 - \e[92mDelete specific files in cwd recursive\e[0m\n5 - \e[92mList the size of sub folders\e[0m\n\n \e[4mCategories\e[0m\n1 - \e[96mFiles\e[0m\n2 - \e[96mImages\e[0m\n3 - \e[96mSearch\e[0m\nBye!\n", output)
19
+ end
20
+
21
+ private
22
+ def run_app input
23
+ output = ''
24
+
25
+ stdin, stdout = Open3.popen2( Mycommands::ROOTPATH + "/bin/mycommands -t")
26
+
27
+ while stdout.ready?
28
+ output << stdout.readline
29
+ end
30
+
31
+ for i in input
32
+ stdin.puts i
33
+ end
34
+
35
+ # Now get whatever else we still have to read:
36
+ stdin.close
37
+ stdout.each_line do |line|
38
+ output << line
39
+ end
40
+ output
41
+ end
42
+ end
@@ -0,0 +1,3 @@
1
+ TEST = true
2
+ require 'minitest/autorun'
3
+ Bundler.require(:default, :development)
@@ -0,0 +1,27 @@
1
+ require_relative '../test_helper'
2
+
3
+ class TestCategoryModel < MiniTest::Unit::TestCase
4
+ def setup
5
+ @category = Mycommands::CategoryModel.new
6
+ end
7
+
8
+ def test_init
9
+ assert_equal ["Files", "Images", "Search"], @category.categories.map(&:name)
10
+ end
11
+
12
+ def test_choice
13
+ @category.choose(1)
14
+ assert_equal ["Permissions", "Symlinks", "Tar"], @category.categories.map(&:name)
15
+ end
16
+
17
+ def test_back
18
+ @category.choose(1)
19
+ @category.go_back
20
+ assert_equal ["Files", "Images", "Search"], @category.categories.map(&:name)
21
+ end
22
+
23
+ def test_category
24
+ @category.choose(1).choose(1)
25
+ assert_equal("Permissions", @category.category)
26
+ end
27
+ end
@@ -0,0 +1,15 @@
1
+ require_relative '../test_helper'
2
+
3
+ class TestCommandModel < MiniTest::Unit::TestCase
4
+ def setup
5
+ @commands = Mycommands::CommandModel.new
6
+ end
7
+
8
+ def test_commands
9
+ assert(@commands.commands('Files').all? {|c| c.is_a?(Mycommands::Command)})
10
+ end
11
+
12
+ def test_command
13
+ assert_equal('Delete specific files in cwd recursive', @commands.command('Files', 0).description)
14
+ end
15
+ end
@@ -0,0 +1,29 @@
1
+ require_relative '../test_helper'
2
+
3
+ class TestCommand < MiniTest::Unit::TestCase
4
+ def setup
5
+ @command = Mycommands::Command.new(["Delete specific files in cwd recursive", ["Files", "find . -name \\FILES -CONFIRM rm {} \\;", {"FILES"=>"Files to remove (*.svn)"}, {"CONFIRM"=>"Confirm exec/ok (ok)"}]])
6
+ @command.params.map {|p| p.substitute ''}
7
+ end
8
+
9
+ def test_description
10
+ assert_equal("Delete specific files in cwd recursive", @command.description)
11
+ end
12
+
13
+ def test_category
14
+ assert_equal("Files", @command.category)
15
+ end
16
+
17
+ def test_command_string
18
+ assert_equal("find . -name \\FILES -CONFIRM rm {} \\;", @command.command_string)
19
+ end
20
+
21
+ def test_command_params
22
+ assert(@command.has_params?)
23
+ end
24
+
25
+ def test_finished_command
26
+ assert_equal("find . -name \\*.svn -ok rm {} \\;", @command.finished_command)
27
+ end
28
+
29
+ end
@@ -0,0 +1,9 @@
1
+ require_relative '../test_helper'
2
+
3
+ class TestFactory < MiniTest::Unit::TestCase
4
+ def test_get
5
+ category = Mycommands::Factory.get(:CategoryModel)
6
+ assert_equal(Mycommands::CategoryModel, category.class)
7
+ assert_equal(category.object_id, Mycommands::Factory.get(:CategoryModel).object_id)
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ require_relative '../test_helper'
2
+
3
+ class TestParamModel < MiniTest::Unit::TestCase
4
+ def setup
5
+ @param = Mycommands::Params.new([{"CONFIRM"=>"Confirm exec/ok (ok)"}, {"FILES"=>"Files to remove (*.svn)"}])
6
+ end
7
+
8
+ def test_current_param
9
+ assert_equal("Files to remove (*.svn)", @param.current_param.description)
10
+ assert_equal("FILES", @param.current_param.value)
11
+ end
12
+
13
+ end
@@ -0,0 +1,23 @@
1
+ require_relative '../test_helper'
2
+
3
+ class TestParam < MiniTest::Unit::TestCase
4
+ def setup
5
+ @param = Mycommands::Param.new({"CONFIRM"=>"Confirm exec/ok (ok)"})
6
+ end
7
+
8
+ def test_description
9
+ assert_equal("Confirm exec/ok (ok)", @param.description)
10
+ end
11
+
12
+ def test_value
13
+ assert_equal("CONFIRM", @param.value)
14
+ end
15
+
16
+ def test_substitute
17
+ @param.substitute('')
18
+ assert_equal('ok', @param.substituted)
19
+ @param.substitute('test')
20
+ assert_equal('test', @param.substituted)
21
+ end
22
+
23
+ end
@@ -0,0 +1,18 @@
1
+ require_relative '../test_helper'
2
+
3
+ class TestRouter < MiniTest::Unit::TestCase
4
+ def setup
5
+ @router = Mycommands::Router.new
6
+ end
7
+
8
+ def test_init
9
+ assert_equal(false, @router.route('1'))
10
+ end
11
+
12
+ def test_add_and_clear_route
13
+ @router.add_route(:controller => :Category, :action => :index, :input => '1')
14
+ assert_equal([:Category, :index, "1"], @router.route('1'))
15
+ @router.clear_routes
16
+ assert_equal(false, @router.route('1'))
17
+ end
18
+ end
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mycommands
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nils Eriksson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: clipboard
16
+ requirement: &70213291412740 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.0.1
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70213291412740
25
+ - !ruby/object:Gem::Dependency
26
+ name: minitest
27
+ requirement: &70213291412040 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 4.5.0
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70213291412040
36
+ - !ruby/object:Gem::Dependency
37
+ name: pry
38
+ requirement: &70213291411040 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 0.9.11.4
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70213291411040
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: &70213291401420 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 10.0.3
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70213291401420
58
+ description: Often when I need a solution for a specific task I do a google search
59
+ to find out what command I can use. Before I made this script I had a text file
60
+ with commands saved that I wanted to rember. This script makes it easier to fetch
61
+ and organize my favourite commands.
62
+ email:
63
+ - nils.epost@gmail.com
64
+ executables:
65
+ - mycommands
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - Gemfile
70
+ - Gemfile.lock
71
+ - LICENSE.txt
72
+ - README.md
73
+ - Rakefile
74
+ - bin/mycommands
75
+ - lib/mycommands.rb
76
+ - lib/mycommands/application.rb
77
+ - lib/mycommands/categories.yml
78
+ - lib/mycommands/commands.yml
79
+ - lib/mycommands/controllers/application_controller.rb
80
+ - lib/mycommands/controllers/category_controller.rb
81
+ - lib/mycommands/controllers/command_controller.rb
82
+ - lib/mycommands/controllers/controller.rb
83
+ - lib/mycommands/controllers/param_controller.rb
84
+ - lib/mycommands/factory.rb
85
+ - lib/mycommands/models/category.rb
86
+ - lib/mycommands/models/command.rb
87
+ - lib/mycommands/models/model.rb
88
+ - lib/mycommands/models/param.rb
89
+ - lib/mycommands/router.rb
90
+ - lib/mycommands/version.rb
91
+ - lib/mycommands/views/application_view.rb
92
+ - lib/mycommands/views/category_view.rb
93
+ - lib/mycommands/views/command_view.rb
94
+ - lib/mycommands/views/param_view.rb
95
+ - lib/mycommands/views/view.rb
96
+ - mycommands.gemspec
97
+ - test/categories.yml
98
+ - test/commands.yml
99
+ - test/integration/integration_test.rb
100
+ - test/test_helper.rb
101
+ - test/units/category_test.rb
102
+ - test/units/command_model_test.rb
103
+ - test/units/command_test.rb
104
+ - test/units/factory_test.rb
105
+ - test/units/param_model_test.rb
106
+ - test/units/param_test.rb
107
+ - test/units/router_test.rb
108
+ homepage: https://github.com/nilseriksson/Mycommands
109
+ licenses: []
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ segments:
121
+ - 0
122
+ hash: 1221253465243075765
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ none: false
125
+ requirements:
126
+ - - ! '>='
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ segments:
130
+ - 0
131
+ hash: 1221253465243075765
132
+ requirements: []
133
+ rubyforge_project:
134
+ rubygems_version: 1.8.10
135
+ signing_key:
136
+ specification_version: 3
137
+ summary: Small console app to manage your favourite commands
138
+ test_files:
139
+ - test/categories.yml
140
+ - test/commands.yml
141
+ - test/integration/integration_test.rb
142
+ - test/test_helper.rb
143
+ - test/units/category_test.rb
144
+ - test/units/command_model_test.rb
145
+ - test/units/command_test.rb
146
+ - test/units/factory_test.rb
147
+ - test/units/param_model_test.rb
148
+ - test/units/param_test.rb
149
+ - test/units/router_test.rb