duty 0.1.0 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5b04eb166b84df79f038e4cd1f03181ff7294049
4
- data.tar.gz: 8cec611a0d0fcbf8ae02de1ea3ed798633fed7e7
3
+ metadata.gz: 8859b7cf5b79a37d5fcb1fa2f23b05905b287b15
4
+ data.tar.gz: e338d56cb5912651b49f34217eed860b189820b8
5
5
  SHA512:
6
- metadata.gz: 1fd3ce618dcc3c2e631715efcb138558345e7b7b6481e9655443f14c668b4de115f66983239e3cb769cd2ff73c9cec63f543c68e0c2c326a10505af9bf6ecff4
7
- data.tar.gz: 4b7e91969a5d696d976c3d7ea0739fdbec15e16fef9c89a74f62f7e215a4a468e466419c7f58943406ccd9ba06a280f9fe7139420afc1cb1d392851af52be0d5
6
+ metadata.gz: c6923f6199cf0001806a1f3259feb89fd2fecdb9128319a92c299966528adc2393705eecb41101764936e6bd817e73366cc473fdd8183900a3d14d5ed392266e
7
+ data.tar.gz: afda6ff19cdca9f23cbfc7b2ea044163b9f6d7fd9931f3134e1c9af9fa386edf194a76348c5f3273936de8fdf40a6cc0593b003e750cf34da68f87afa6da974d
data/README.md CHANGED
@@ -17,7 +17,6 @@ $ gem install duty
17
17
  ```
18
18
  $ export PATH="$PATH:$HOME/path/to/duty/bin"
19
19
  ```
20
- ```
21
20
 
22
21
  ## Add shell completion
23
22
 
data/lib/duty/cli.rb CHANGED
@@ -1,6 +1,8 @@
1
+ require 'duty/io'
1
2
  require 'duty/registry'
2
3
  require 'duty/plugins'
3
- require 'duty/meta'
4
+ require 'duty/task_runner'
5
+ require 'duty/views'
4
6
 
5
7
  module Duty
6
8
  class CLI
@@ -8,208 +10,61 @@ module Duty
8
10
  attr_reader :registry
9
11
 
10
12
  def initialize(args)
11
- @input = Input.new(args)
12
- @output = Output.new
13
- @registry = Duty::Registry.load(plugins)
13
+ @input = Duty::IO::CLI::Input.new(args)
14
+ @output = Duty::IO::CLI::Output.new($stdout, $stderr)
15
+ @registry = Duty::Registry.register(Duty::Plugins.load(DUTY_CONFIG_FILENAME))
14
16
  end
15
17
 
16
18
  def exec
17
- stdout usage if help?
18
- stdout completion if completion?
19
- run_task
19
+ explain_duty if needs_help?
20
+ complete_task if needs_completion?
21
+ execute_task
20
22
  end
21
23
 
22
24
  private
23
25
 
24
26
  attr_reader :input, :output
25
27
 
26
- def plugins
27
- Duty::Plugins.load(DUTY_CONFIG_FILENAME)
28
- end
29
-
30
- def stdout(string)
31
- $stdout.puts string
28
+ def explain_duty
29
+ view.duty_explain
32
30
  exit 0
33
31
  end
34
32
 
35
- def help?
36
- input.help?
33
+ def needs_help?
34
+ input.needs_help?
37
35
  end
38
36
 
39
- def usage
40
- Duty::Meta::Help.new(self).to_s
41
- end
42
-
43
- def completion?
44
- input.completion?
37
+ def complete_task
38
+ view.task_complete
39
+ exit 0
45
40
  end
46
41
 
47
- def completion
48
- Duty::Meta::Completion.new(self, input.drop(1)).to_s
42
+ def needs_completion?
43
+ input.needs_completion?
49
44
  end
50
45
 
51
- def run_task
46
+ def execute_task
52
47
  begin
53
- task.run
54
- rescue NameError => e
55
- stdout invalid_task(e.message)
48
+ try_to_run_task
49
+ rescue NameError => error
50
+ view.task_invalid(error)
56
51
  end
57
52
  end
58
53
 
59
- def task
60
- input.task_class.new(input.task_input, view)
61
- end
62
-
63
- def invalid_task(error_message)
64
- "duty: `#{input.join(' ')}` is not a duty task. Failed with: #{error_message}"
54
+ def try_to_run_task
55
+ Duty::TaskRunner.run(view, input, registry)
65
56
  end
66
57
 
67
58
  def view
68
59
  if verbose?
69
- VerboseView.new(output)
60
+ Duty::Views::CLI::Verbose.new(self, input, output)
70
61
  else
71
- View.new(output)
62
+ Duty::Views::CLI::Normal.new(self, input, output)
72
63
  end
73
64
  end
74
65
 
75
66
  def verbose?
76
67
  input.verbose?
77
68
  end
78
-
79
- class Input
80
- def initialize(args)
81
- @args = [args].flatten
82
- end
83
-
84
- def[](index)
85
- @args[index]
86
- end
87
-
88
- def drop(index)
89
- @args.drop(1)
90
- end
91
-
92
- def task_name
93
- task, *rest = @args
94
- task
95
- end
96
-
97
- def task_class
98
- name = task_name.split('-').collect(&:capitalize).join
99
- Object.const_get("Duty::Tasks::#{name}")
100
- end
101
-
102
- def task_input
103
- task, *rest = @args
104
- rest
105
- end
106
-
107
- def join(seperator='')
108
- @args.join(seperator)
109
- end
110
-
111
- def verbose?
112
- @args.include?('-v') || @args.include?('--verbose')
113
- end
114
-
115
- def completion?
116
- @args.first == '--cmplt'
117
- end
118
-
119
- def help?
120
- @args.empty? || @args == %w(-h) || @args == %w(--help)
121
- end
122
- end
123
-
124
- class Output
125
- def print(*args)
126
- $stdout.puts(*args)
127
- end
128
-
129
- def error(*args)
130
- $stderr.puts(*args)
131
- end
132
- end
133
-
134
- class View
135
- def initialize(output)
136
- @output = output
137
- end
138
-
139
- def task_explain(task)
140
- task_class = task.class
141
- description = task_class.description
142
- usage = task_class.usage
143
-
144
- @output.print(description)
145
- @output.print(usage)
146
- end
147
-
148
- def task_success(task)
149
- task_name = task.class.name
150
- success("#{task_name} task executed")
151
- end
152
-
153
- def task_failure(task)
154
- task_name = task.class.name
155
- failure("#{task_name} task aborted")
156
- end
157
-
158
- def command_success(command)
159
- description = command.description
160
- success(description)
161
- end
162
-
163
- def command_failure(command)
164
- description = command.description
165
- failure(description)
166
- end
167
-
168
- private
169
-
170
- def success(msg)
171
- @output.print([check_mark, msg].join(' '))
172
- end
173
-
174
- def failure(msg)
175
- @output.error([cross_mark, msg].join(' '))
176
- end
177
-
178
- def cross_mark
179
- unicode("2715")
180
- end
181
-
182
- def check_mark
183
- unicode("2713")
184
- end
185
-
186
- def unicode(code)
187
- ["0x#{code}".hex].pack('U')
188
- end
189
- end
190
-
191
- class VerboseView < View
192
- def command_success(command)
193
- success(command_msg(command))
194
- end
195
-
196
- def command_failure(command)
197
- failure(command_msg(command))
198
- end
199
-
200
- private
201
-
202
- def command_msg(command)
203
- [command.description, command_logs(command)].join(' ')
204
- end
205
-
206
- def command_logs(command)
207
- elements = command.logger.flatten
208
-
209
- if elements.any?
210
- ["|>", elements.join(' | ')].join(' ')
211
- end
212
- end
213
- end
214
69
  end
215
70
  end
@@ -0,0 +1,68 @@
1
+ module Duty
2
+ module IO
3
+ module CLI
4
+ class Input
5
+ def initialize(args)
6
+ @args = [args].flatten
7
+ end
8
+
9
+ def[](index)
10
+ args[index]
11
+ end
12
+
13
+ def task_name
14
+ task, *rest = args
15
+ task
16
+ end
17
+
18
+ def task_input
19
+ task, *rest = args
20
+ rest
21
+ end
22
+
23
+ def drop(index)
24
+ args.drop(1)
25
+ end
26
+
27
+ def join(seperator='')
28
+ args.join(seperator)
29
+ end
30
+
31
+ def verbose?
32
+ args.include?('-v') || args.include?('--verbose')
33
+ end
34
+
35
+ def needs_completion?
36
+ args.first == '--cmplt'
37
+ end
38
+
39
+ def needs_help?
40
+ args.empty? || args == %w(-h) || args == %w(--help)
41
+ end
42
+
43
+ private
44
+
45
+ attr_reader :args
46
+ end
47
+
48
+ class Output
49
+ def initialize(stdout, stderr)
50
+ @stdout = stdout
51
+ @stderr = stderr
52
+ end
53
+
54
+ def print(*args)
55
+ stdout.puts(*args)
56
+ end
57
+
58
+ def error(*args)
59
+ stderr.puts(*args)
60
+ end
61
+
62
+ private
63
+
64
+ attr_reader :stdout, :stderr
65
+ end
66
+ end
67
+ end
68
+ end
data/lib/duty/io.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'duty/io/cli'
2
+
3
+ module Duty
4
+ module IO
5
+ end
6
+ end
data/lib/duty/plugins.rb CHANGED
@@ -4,46 +4,64 @@ require 'yaml'
4
4
  module Duty
5
5
  module Plugins
6
6
  def self.load(filename)
7
- if File.exists?(filename)
8
- duty_config = YAML.load(File.read(filename))
9
- tasks = duty_config["tasks"]
10
- tasks.map do |namespace, task_dir|
11
- Plugin.new(namespace, task_dir) if Dir.exists?(task_dir)
7
+ Duty::Plugins::List.new.tap do |list|
8
+ if File.exists?(filename)
9
+ duty_config = YAML.load(File.read(filename))
10
+ tasks = duty_config["tasks"]
11
+ tasks.each do |namespace, plugin_entry_point|
12
+ list << Plugin.new(namespace, plugin_entry_point)
13
+ end
12
14
  end
13
15
  end
14
16
  end
15
17
 
18
+ class List
19
+ require 'forwardable'
20
+ include Enumerable
21
+ extend Forwardable
22
+ def_delegators :@plugins, :each, :<<
23
+ def initialize
24
+ @plugins = []
25
+ end
26
+ end
27
+
16
28
  class Plugin
17
- TASK_NAMESPACE = Duty::Tasks
18
- def initialize(namespace, task_dir)
29
+ def initialize(namespace, entry)
19
30
  @namespace = namespace
20
- @task_dir = task_dir
31
+ @entry = entry
32
+ @tasks = []
21
33
  end
22
34
 
23
35
  def namespace
24
36
  @namespace
25
37
  end
26
38
 
27
- def require_tasks
28
- task_files = File.expand_path(File.join(@task_dir, "*.rb"))
29
- Dir[task_files].each do |path|
30
- require path.gsub(/(\.rb)$/, '')
39
+ def tasks
40
+ @task_classes.select do |task_class|
41
+ valid?(task_class)
31
42
  end
32
43
  end
33
44
 
34
- def tasks
35
- task_names = TASK_NAMESPACE.constants - [:Base]
36
- task_names.reduce([]) do |task_classes, task_name|
37
- task_class = TASK_NAMESPACE.const_get(task_name)
38
- task_classes << task_class if valid?(task_class)
39
- task_classes
40
- end
45
+ def load_tasks
46
+ require_tasks
47
+ expose_tasks
48
+ end
49
+
50
+ private
51
+
52
+ def require_tasks
53
+ path = @entry.gsub(/\.rb/,'')
54
+ require path
55
+ end
56
+
57
+ def expose_tasks
58
+ @task_classes = eval(File.read(@entry)).tasks
41
59
  end
42
60
 
43
61
  private
44
62
 
45
63
  def valid?(task_class)
46
- task_class.superclass == TASK_NAMESPACE::Base
64
+ task_class.ancestors.include? ::Duty::Tasks::Base
47
65
  end
48
66
  end
49
67
  end
data/lib/duty/registry.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Duty
2
2
  class Registry
3
- def self.load(plugins = [])
4
- new(plugins).tap {|registry| registry.require_tasks }
3
+ def self.register(plugins = [])
4
+ new(plugins).tap {|registry| registry.load_tasks }
5
5
  end
6
6
 
7
7
  attr_reader :plugins
@@ -9,8 +9,8 @@ module Duty
9
9
  @plugins = plugins
10
10
  end
11
11
 
12
- def require_tasks
13
- plugins.each {|plugin| plugin.require_tasks }
12
+ def load_tasks
13
+ plugins.each {|plugin| plugin.load_tasks }
14
14
  end
15
15
  end
16
16
  end
@@ -0,0 +1,41 @@
1
+ module Duty
2
+ class TaskRunner
3
+ def initialize(view, input, registry)
4
+ @view = view
5
+ @input = input
6
+ @plugins = registry.plugins
7
+ end
8
+
9
+ def self.run(view, input, plugins)
10
+ self.new(view, input, plugins).run
11
+ end
12
+
13
+ def run
14
+ task_class.new(task_input, view).run
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :view
20
+
21
+ def task_class
22
+ name = task_name.split('-').collect(&:capitalize).join
23
+ @plugins.each do |plugin|
24
+ plugin.tasks.each do |task_class|
25
+ if task_class.to_s.split("::").last == name
26
+ @task_class = task_class
27
+ end
28
+ end
29
+ end
30
+ @task_class
31
+ end
32
+
33
+ def task_input
34
+ @input.task_input
35
+ end
36
+
37
+ def task_name
38
+ @input.task_name
39
+ end
40
+ end
41
+ end
data/lib/duty/tasks.rb CHANGED
@@ -35,9 +35,9 @@ module Duty
35
35
  end
36
36
 
37
37
  def execute
38
- ruby(Proc.new{},'Describe your task')
39
- ruby(Proc.new{},'Explain your task')
40
- ruby(Proc.new{ raise ExecutionError.new },'TODO: Implement your task by overwriting `execute`')
38
+ ruby('Describe your task') {}
39
+ ruby('Explain your task') {}
40
+ ruby('TODO: Implement your task by overwriting `execute`') { raise ExecutionError.new }
41
41
  end
42
42
 
43
43
  private
data/lib/duty/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Duty
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,113 @@
1
+ require 'duty/meta'
2
+
3
+ module Duty
4
+ module Views
5
+ module CLI
6
+ class Normal
7
+ def initialize(cli, input, output)
8
+ @cli = cli
9
+ @input = input
10
+ @output = output
11
+ end
12
+
13
+ def duty_explain
14
+ output.print meta_help_message
15
+ end
16
+
17
+ def task_complete
18
+ output.print meta_completion_message
19
+ end
20
+
21
+ def task_explain(task)
22
+ task_class = task.class
23
+ description = task_class.description
24
+ usage = task_class.usage
25
+
26
+ output.print(description)
27
+ output.print(usage)
28
+ end
29
+
30
+ def task_success(task)
31
+ task_name = task.class.name
32
+ success("#{task_name} task executed")
33
+ end
34
+
35
+ def task_failure(task)
36
+ task_name = task.class.name
37
+ failure("#{task_name} task aborted")
38
+ end
39
+
40
+ def task_invalid(error)
41
+ error_message = "duty: `#{input.join(' ')}` is not a duty task. Failed with: #{error.message}"
42
+ output.print error_message
43
+ end
44
+
45
+ def command_success(command)
46
+ description = command.description
47
+ success(description)
48
+ end
49
+
50
+ def command_failure(command)
51
+ description = command.description
52
+ failure(description)
53
+ end
54
+
55
+ private
56
+
57
+ attr_reader :cli, :input, :output
58
+
59
+ def success(msg)
60
+ output.print([check_mark, msg].join(' '))
61
+ end
62
+
63
+ def failure(msg)
64
+ output.error([cross_mark, msg].join(' '))
65
+ end
66
+
67
+ def cross_mark
68
+ unicode("2715")
69
+ end
70
+
71
+ def check_mark
72
+ unicode("2713")
73
+ end
74
+
75
+ def unicode(code)
76
+ ["0x#{code}".hex].pack('U')
77
+ end
78
+
79
+ def meta_help_message
80
+ Duty::Meta::Help.new(cli).to_s
81
+ end
82
+
83
+ def meta_completion_message
84
+ Duty::Meta::Completion.new(cli, input.drop(1)).to_s
85
+ end
86
+ end
87
+
88
+ class Verbose < Normal
89
+ def command_success(command)
90
+ success(command_msg(command))
91
+ end
92
+
93
+ def command_failure(command)
94
+ failure(command_msg(command))
95
+ end
96
+
97
+ private
98
+
99
+ def command_msg(command)
100
+ [command.description, command_logs(command)].join(' ')
101
+ end
102
+
103
+ def command_logs(command)
104
+ elements = command.logger.flatten
105
+
106
+ if elements.any?
107
+ ["|>", elements.join(' | ')].join(' ')
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
data/lib/duty/views.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'duty/views/cli'
2
+
3
+ module Duty
4
+ module Views
5
+ end
6
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: duty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Owiesniak
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-25 00:00:00.000000000 Z
11
+ date: 2015-11-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -62,14 +62,19 @@ files:
62
62
  - duty.gemspec
63
63
  - lib/duty.rb
64
64
  - lib/duty/cli.rb
65
+ - lib/duty/io.rb
66
+ - lib/duty/io/cli.rb
65
67
  - lib/duty/meta.rb
66
68
  - lib/duty/meta/completion.rb
67
69
  - lib/duty/meta/help.rb
68
70
  - lib/duty/meta/humanizer.rb
69
71
  - lib/duty/plugins.rb
70
72
  - lib/duty/registry.rb
73
+ - lib/duty/task_runner.rb
71
74
  - lib/duty/tasks.rb
72
75
  - lib/duty/version.rb
76
+ - lib/duty/views.rb
77
+ - lib/duty/views/cli.rb
73
78
  homepage: https://github.com/JanOwiesniak/duty
74
79
  licenses:
75
80
  - MIT