mycommands 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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