rake-commander 0.1.2

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.
@@ -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: []