duty 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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