rake-commander 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,39 @@
1
+ class RakeCommander
2
+ module RakeContext
3
+ class Wrapper
4
+ # Allows to interact with rake
5
+ # @note this prevents subclass overlap methods to be used
6
+ def context(object = global_instance, &block)
7
+ raise ArgumentError, "Block required" unless block_given?
8
+ object.instance_eval(&block)
9
+ end
10
+
11
+ def respond_to_missing?(meth, *args)
12
+ global_instance.send(:respond_to_missing?, meth, *args) || super
13
+ end
14
+
15
+ def respond_to?(meth, with_private = true)
16
+ global_instance.respond_to?(meth, with_private) || super
17
+ end
18
+
19
+ # Forward
20
+ def method_missing(meth, *args, **kargs, &block)
21
+ if respond_to?(meth)
22
+ context do
23
+ send(meth, *args, **kargs, &block)
24
+ end
25
+ else
26
+ super
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+
33
+ # Refers to the top level object
34
+ def global_instance
35
+ @global_instance ||= eval('self', TOPLEVEL_BINDING, __FILE__, __LINE__)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,157 @@
1
+ require_relative 'rake_context/wrapper'
2
+
3
+ class RakeCommander
4
+ module RakeTask
5
+ NAMESPACE_DELIMITER = /:/.freeze
6
+ RAKE_END_COMMAND = '--'.freeze
7
+ INHERITABLE_ATTRS = [:namespace].freeze
8
+
9
+ class << self
10
+ def included(base)
11
+ super(base)
12
+ base.extend ClassMethods
13
+ base.inheritable_attrs(*INHERITABLE_ATTRS)
14
+ end
15
+ end
16
+
17
+ module ClassMethods
18
+ include RakeCommander::Base::ClassHelpers
19
+
20
+ # The rake context wrapper (to invoke rake commands)
21
+ def rake
22
+ @rake ||= RakeCommander::RakeContext::Wrapper.new
23
+ end
24
+
25
+ # Does the final rake `task` definition
26
+ def install_task(&task_method)
27
+ raise "Expected task_block." unless task_method
28
+
29
+ # ensure options are parsed before calling task
30
+ # and that ARGV is only parsed after `--`
31
+ task_method = invoke_options_before_task(&task_method) if options?
32
+
33
+ if namespaced?
34
+ namespaced do
35
+ rake.desc desc
36
+ rake.task task, &task_method
37
+ end
38
+ else
39
+ rake.desc desc
40
+ rake.task task, &task_method
41
+ end
42
+ end
43
+
44
+ # Give a name to the task
45
+ # @return [Symbol] the task name
46
+ def task(name = nil)
47
+ return @task if name.nil?
48
+ @task = name.to_sym
49
+ end
50
+
51
+ # Give a description to the task
52
+ # @return [String] the description of the task
53
+ def desc(str = nil)
54
+ return @desc if str.nil?
55
+ @desc = str.to_s
56
+ end
57
+
58
+ # It can be hierarchical by using `NAMESPACE_DELIMITER`
59
+ # @return [String] the namespace defined for this `RakeCommander` class.
60
+ def namespace(name = nil)
61
+ return @namespace if name.nil?
62
+ @namespace = namespace_str(name)
63
+ end
64
+
65
+ # Is this rake context namespaced?
66
+ # @note Rake allows to namespace tasks (i.e. `task :"run:this"`)
67
+ # Although supported by this integration, namespace detection
68
+ # is left to the core `rake` gem. This method will return `false`.
69
+ # @return [Boolean]
70
+ def namespaced?
71
+ !!namespace
72
+ end
73
+
74
+ # It builds the nested `namespace` **rake** blocks
75
+ def namespaced(name = namespace, &block)
76
+ spaces = namespace_split(name)
77
+ top = spaces.shift
78
+ block = spaces.reverse.reduce(block) do |blk, nm|
79
+ namespace_block(nm, &blk)
80
+ end
81
+ rake.namespace top, &block
82
+ end
83
+
84
+ protected
85
+
86
+ # Converstion of `namespace` name to string
87
+ # @return [String]
88
+ def namespace_str(name)
89
+ name = name.to_s if name.is_a?(Symbol)
90
+ name = name.to_str if name.respond_to?(:to_str)
91
+ raise ArgumentError, "Expected a String or Symbol for a namespace name. Given: #{name.class}" unless name.is_a?(String)
92
+ name
93
+ end
94
+
95
+ # @return [String, NilClass] generic banner for options
96
+ def task_options_banner
97
+ str_space = respond_to?(:namespace)? "#{namespace}:" : ''
98
+ str_task = respond_to?(:task) ? "Usage: #{str_space}#{task} -- [options]" : nil
99
+ end
100
+
101
+ private
102
+
103
+ # Split into `Array` the namespace based on `NAMESPACE_DELIMITER`
104
+ # @return [Array<String>]
105
+ def namespace_split(name)
106
+ namespace_str(name).split(NAMESPACE_DELIMITER)
107
+ end
108
+
109
+ # Helper to build the rake `namespace` blocks
110
+ # @return [Proc] which will invoke `namspace name` from the global context when called.
111
+ def namespace_block(name, &block)
112
+ rake.context do
113
+ proc { namespace name, &block }
114
+ end
115
+ end
116
+
117
+ # Rake command ends at `--` (`RAKE_END_COMMAND`).
118
+ # We only want to parse the options that come afterwards
119
+ # @note without this approach, it will throw `OptionParser::InvalidOption` error
120
+ # @return [Proc]
121
+ def invoke_options_before_task(&task_method)
122
+ object = eval('self', task_method.binding, __FILE__, __LINE__)
123
+ return task_method unless object.is_a?(self)
124
+ proc do |*args|
125
+ argv = ARGV
126
+ if idx = argv.index(RAKE_END_COMMAND)
127
+ argv = argv[idx+1..-1]
128
+ end
129
+ object.options(argv)
130
+ task_method.call(*args)
131
+ end
132
+ end
133
+ end
134
+
135
+ def initialize
136
+ super if defined?(super)
137
+ install_task
138
+ end
139
+
140
+ # def task
141
+ # raise "You should override/define this method"
142
+ # end
143
+
144
+ protected
145
+
146
+ def install_task
147
+ return unless task_block = task_method
148
+ self.class.install_task(&task_block)
149
+ end
150
+
151
+ def task_method
152
+ method(:task)
153
+ rescue NameError
154
+ nil
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,3 @@
1
+ class RakeCommander
2
+ VERSION = '0.1.2'.freeze
3
+ end
@@ -0,0 +1,9 @@
1
+ require 'rake'
2
+ require_relative 'rake-commander/base'
3
+
4
+ class RakeCommander
5
+ include RakeCommander::Base
6
+ end
7
+
8
+ require_relative 'rake-commander/version'
9
+ require_relative 'rake-commander/custom'
@@ -0,0 +1,29 @@
1
+ lib = File.expand_path('lib', __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "rake-commander/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "rake-commander"
7
+ spec.version = RakeCommander::VERSION
8
+ spec.authors = ["Oscar Segura Samper"]
9
+ spec.email = ["oscar@ecoportal.co.nz"]
10
+
11
+ spec.summary = 'The classed version of rake with task options. Create re-usable tasks and samples.'
12
+ spec.homepage = "https://www.ecoportal.com"
13
+ spec.licenses = %w[MIT]
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
16
+ f.match(%r{^(test|spec|features)/})
17
+ end
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.required_ruby_version = '>= 2.7.2'
23
+
24
+ spec.add_development_dependency "bundler", ">= 2.4.9", "< 3"
25
+ spec.add_development_dependency "rake", ">= 13.0.6", "< 14"
26
+ spec.add_development_dependency "redcarpet", ">= 3.6.0", "< 4"
27
+ spec.add_development_dependency "rspec", ">= 3.10.0", "< 4"
28
+ spec.add_development_dependency "yard", ">= 0.9.34", "< 1"
29
+ end
metadata ADDED
@@ -0,0 +1,169 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rake-commander
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Oscar Segura Samper
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-04-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 2.4.9
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '3'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 2.4.9
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '3'
33
+ - !ruby/object:Gem::Dependency
34
+ name: rake
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 13.0.6
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: '14'
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 13.0.6
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '14'
53
+ - !ruby/object:Gem::Dependency
54
+ name: redcarpet
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 3.6.0
60
+ - - "<"
61
+ - !ruby/object:Gem::Version
62
+ version: '4'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: 3.6.0
70
+ - - "<"
71
+ - !ruby/object:Gem::Version
72
+ version: '4'
73
+ - !ruby/object:Gem::Dependency
74
+ name: rspec
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: 3.10.0
80
+ - - "<"
81
+ - !ruby/object:Gem::Version
82
+ version: '4'
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 3.10.0
90
+ - - "<"
91
+ - !ruby/object:Gem::Version
92
+ version: '4'
93
+ - !ruby/object:Gem::Dependency
94
+ name: yard
95
+ requirement: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: 0.9.34
100
+ - - "<"
101
+ - !ruby/object:Gem::Version
102
+ version: '1'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: 0.9.34
110
+ - - "<"
111
+ - !ruby/object:Gem::Version
112
+ version: '1'
113
+ description:
114
+ email:
115
+ - oscar@ecoportal.co.nz
116
+ executables: []
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - ".gitignore"
121
+ - ".rspec"
122
+ - ".rubocop.yml"
123
+ - ".yardopts"
124
+ - CHANGELOG.md
125
+ - Gemfile
126
+ - README.md
127
+ - Rakefile
128
+ - examples/basic.rb
129
+ - lib/rake-commander.rb
130
+ - lib/rake-commander/base.rb
131
+ - lib/rake-commander/base/class_auto_loader.rb
132
+ - lib/rake-commander/base/class_helpers.rb
133
+ - lib/rake-commander/custom.rb
134
+ - lib/rake-commander/option.rb
135
+ - lib/rake-commander/options.rb
136
+ - lib/rake-commander/options/arguments.rb
137
+ - lib/rake-commander/options/error.rb
138
+ - lib/rake-commander/options/error_rely.rb
139
+ - lib/rake-commander/options/name.rb
140
+ - lib/rake-commander/options/set.rb
141
+ - lib/rake-commander/rake_context/wrapper.rb
142
+ - lib/rake-commander/rake_task.rb
143
+ - lib/rake-commander/version.rb
144
+ - rake-commander.gemspec
145
+ homepage: https://www.ecoportal.com
146
+ licenses:
147
+ - MIT
148
+ metadata: {}
149
+ post_install_message:
150
+ rdoc_options: []
151
+ require_paths:
152
+ - lib
153
+ required_ruby_version: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ version: 2.7.2
158
+ required_rubygems_version: !ruby/object:Gem::Requirement
159
+ requirements:
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ version: '0'
163
+ requirements: []
164
+ rubygems_version: 3.1.4
165
+ signing_key:
166
+ specification_version: 4
167
+ summary: The classed version of rake with task options. Create re-usable tasks and
168
+ samples.
169
+ test_files: []