rake-commander 0.2.12 → 0.3.3

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
  SHA256:
3
- metadata.gz: 00c13e58c8b9c78ac538ca0100d714a7c3f72ca98a655ae564ebbca13cacf2f6
4
- data.tar.gz: bfbf686120c4245ba541605db6fbb46e14455b77553948827946fb1417cb376b
3
+ metadata.gz: 3b93ede4d58a5bc19446930380b5f9a785f7bcc404a93c1db63360dff78da2fd
4
+ data.tar.gz: 8113a37d4d4301b7028923aaab04734dfa38c8e3979a272750d0e0b35fb649bd
5
5
  SHA512:
6
- metadata.gz: 1d7941181f5ea5b4bd1210bcb3e5a1307bbedbd0a503636144af350a320a6a7ed4a5d8948d2212c81b401513bb383c37ad4645825e544cb952a73bbdf3d62110
7
- data.tar.gz: 41a29e32b0536d073c4481df467ff65351bd84c5782db961398ea6ac66c73d6652d623df7d1c363e321130182f32db78368528996b7331478c16505b1b059c76
6
+ metadata.gz: 1255ab72c7599bc831aa08ca375c4b9c4563698c9e91223184b4348c7ace025b67f0f7b11e6c9818b83774d58099c8cb14be9173f67665b96b228c22a421ad70
7
+ data.tar.gz: 2bac8657f4b0b43523f5343617067fb371e1a4b5ea36d0aea32679e46b523cbf497e7a0af7ef7abaaf1b3fa02c89dd0cdd8f492df2dab5ef0e1150059b4aabd0
data/CHANGELOG.md CHANGED
@@ -32,13 +32,18 @@ All notable changes to this project will be documented in this file.
32
32
  - Option to globally enable/disable the 2nd patch?
33
33
  * That would make this gem completely useless.
34
34
 
35
- ## [0.2.13] - 2023-05-xx
35
+ ## [0.3.2] - 2023-05-xx
36
36
 
37
37
  ### Added
38
38
  ### Fixed
39
39
  ### Changed
40
40
 
41
- ## [0.2.12] - 2023-05-xx
41
+ ## [0.3.2] - 2023-05-01
42
+
43
+ ### Changed
44
+ - Replaced the patching method, so the `Rake` application doesn't need re-launch.
45
+
46
+ ## [0.2.12] - 2023-05-01
42
47
 
43
48
  ### Fixed
44
49
  - `RakeCommander::Option#type_coercion` wasn't correctly captured.
data/README.md CHANGED
@@ -69,6 +69,27 @@ rspec logging and results
69
69
 
70
70
  ### Syntax
71
71
 
72
+ ```ruby
73
+ RakeCommander::Custom::Base < RakeCommander
74
+ include Rake::DSL
75
+ end
76
+ ```
77
+ * `include Rake::DSL` for backwards compatibility
78
+
79
+ ```ruby
80
+ RakeCommander::Custom::MyTask < RakeCommander::Custom::Base
81
+ desc "it does some stuff"
82
+ task :do_stuff
83
+
84
+ option :s, '--do-stuff [SOMETHING]', default: 'nothing'
85
+
86
+ def task(*_args)
87
+ puts "Doing #{options[:s]}" if options[:s]
88
+ end
89
+ end
90
+ ```
91
+
92
+
72
93
  ### Declaring and using Task Options
73
94
 
74
95
  It supports most of options syntax of the native `OptionParser` but for a couple of exceptions perhaps:
@@ -106,10 +127,7 @@ To preserve `rake` as invocation command, though, the patch needs to relaunch th
106
127
 
107
128
  ### Patching `Rake`
108
129
 
109
- The two patches:
110
-
111
- 1. Rake commander does come with a neat patch to the [`Rake::Application#run` method](https://github.com/ruby/rake/blob/48e798484babf725b0562cc417986da513e5d0ae/lib/rake/application.rb#L79) to clean up the `ARGV` before the rake application starts. But it kicks in too late...
112
- 2. For this reason a more arguable patch has been applied to [`Rake::Application#top_level` method](https://github.com/ruby/rake/blob/48e798484babf725b0562cc417986da513e5d0ae/lib/rake/application.rb#L131), where the rake application is relaunched.
130
+ There is only one patch onto [`Rake::Application#top_level` method](https://github.com/ruby/rake/blob/48e798484babf725b0562cc417986da513e5d0ae/lib/rake/application.rb#L131), [`collect_command_line_tasks`](https://github.com/ruby/rake/blob/48e798484babf725b0562cc417986da513e5d0ae/lib/rake/application.rb#L782) is recalled with the arguments cut (so it does not interpret task option arguments as tasks).
113
131
 
114
132
  For further details please see [`RakeCommander::Patcher`](https://github.com/rellampec/rake-commander/blob/main/lib/rake-commander/patcher).
115
133
 
@@ -88,8 +88,6 @@ class RakeCommander
88
88
  # @param method [Symbol] the parsing method (default is `:parse`; others: `:order`)
89
89
  # @return [Array<String>] the **leftovers** of the `OptionParser#parse` call.
90
90
  def parse_options(argv = ARGV, method: :parse, &middleware)
91
- RakeCommander.rake_comm_debug "(#{name}) P A R S E O P T I O N S !", "\n", num: 5, pid: true
92
- RakeCommander.rake_comm_debug " ---> ARGV: [#{argv.map {|a| a.nil?? "nil" : "'#{a}'"}.join(', ')}]"
93
91
  options_parser(&middleware).send(method, argv)
94
92
  end
95
93
 
@@ -6,12 +6,7 @@ Let's say that when we invoke `rake` from the command line, `rake-commander` is
6
6
 
7
7
  ### Challenges encountered with the `rake` executable
8
8
 
9
- Let's say you require/load `rake-commander` in a `Rakefile`, and invoke the [`rake` executable](https://github.com/ruby/rake/blob/master/exe/rake). By the time rake commander is loaded, `Rake` has already captured the `ARGV`, parsed its own options, and pre-parsed possible task(s) invokations.
10
-
11
- The **two main problems** to deal with are:
12
-
13
- 1. Rake has it's own `OptionsParser`. If any of your rake `task` options matches any of those, you will be unintentionally invoking `rake` functionality.
14
- 2. Let's say you require/load `rake-commander` in a `Rakefile`. By the time rake commander is loaded, `rake` has already collected as `top_level_tasks` the arguments of your task options; so those that do not start with dash `-` ([see private method `collect_command_line_tasks` in `Rake::Application`](https://github.com/ruby/rake/blob/48e798484babf725b0562cc417986da513e5d0ae/lib/rake/application.rb#L782)).
9
+ Let's say you require/load `rake-commander` in a `Rakefile`, and invoke the [`rake` executable](https://github.com/ruby/rake/blob/master/exe/rake). By the time rake commander is loaded, `Rake` has already captured the `ARGV`, parsed its own options, and pre-parsed possible task(s) invokations; it has already collected as `top_level_tasks` the arguments of your task options; so those that do not start with dash `-` ([see private method `collect_command_line_tasks` in `Rake::Application`](https://github.com/ruby/rake/blob/48e798484babf725b0562cc417986da513e5d0ae/lib/rake/application.rb#L782)).
15
10
 
16
11
  This is also true when you invoke `rake` via _shell_ from within another task.
17
12
 
@@ -28,40 +23,8 @@ rake aborted!
28
23
  Don't know how to build task 'Just saying...' (See the list of available tasks with `rake --tasks`)
29
24
  ```
30
25
 
31
- ### The alternative of a `raked` executable
32
-
33
- **`raked` executable is not necessary and is not provided for prod environments. The current patch allows to start directly from `rake`**.
34
-
35
- * This has been kept to the only purpose of documentation.
36
-
37
- The `raked` executable would be a modified version of the `rake` executable, where `rake_commander` is loaded right after requiring `rake` and before `Rake.application.run` is invoked.
38
-
39
- ```ruby
40
- #!/usr/bin/env ruby
41
-
42
- require "rake"
43
- require "rake-commander"
44
- Rake.application.run
45
- ```
46
-
47
- This would allow the patch to be active right at the beginning, preventing this way the patch to kick in after the `rake` application has been firstly launched (it saves to rake one loop of parsing arguments and loading rake files).
48
-
49
- ```
50
- $ raked examples:chainer -- --chain --say "Just saying..." --with raked
51
- Calling --> 'bin\raked examples:chained -- --say "Just saying..."'
52
- Chained task has been called!!
53
- Just saying...
54
- ```
55
-
56
- Using `raked` as separate namespace vs `rake` is completely optional. Most will prefer to keep on just with the main `rake` executable and `rake-commander` as enhancement to it. This is the rational behind the second patch (explained in detail in the next section).
57
-
58
-
59
26
  ## Reload `Rake` application
60
27
 
61
- The target is to be able to use `rake` indistinctly (rather than having to rewrite rake commands as `raked`). Unfortunately the **only way around** to the _application-has-started_ is to just **relaunch/reload the application** when the patch kicks in (wouldn't know how to and shouldn't try to reuse the current running application: i.e. task options parsed as rake option modifiers that have already done some stuff).
62
-
63
- Fortunately, the target of `rake-commander` is just to **enhance** existing syntax, which gives a very specific target when it comes to **patching**. The key factor to reach a clean patch is to design the syntax in a fixed way where there is no much flexibility but clearly stated delimiters (i.e. no fancy guessing where dependencies are introduced on defined task options).
64
-
65
28
  Relaunching the application to a new instance requires very little:
66
29
 
67
30
  ```ruby
@@ -69,11 +32,14 @@ Rake.application = Rake::Application.new
69
32
  Rake.application.run
70
33
  exit(0) # abort previous application run
71
34
  ```
35
+ But this approach has been discarded (since `v 0.3.1`), as it loses task definitions loaded via `require`.
72
36
 
73
- ## Missing tasks on reload
37
+ ### Missing tasks on reload
74
38
 
75
39
  Relaunching the `rake` application entails issues with `require` in the chain of `Rakefile` files that have already been loaded. Apparently some tasks of some gems are installed during the `require` runtime, rather than explicitly declaring them in the rake file.
76
40
 
77
41
  This is the case for `bundler/gem_tasks` (i.e. `require "bundler/gem_tasks"`), where all these `tasks` will be missing: build, build:checksum, clean, clobber, install, install:local, release, release:guard_clean, release:rubygem_push, release:source_control_push.
78
42
 
79
- It can potentially be looked at, if ever this shows up to new review.
43
+ ## Re-call `collect_command_line_tasks` from `top_level` method
44
+
45
+ This showed up to solve all the known problems mentioned above. It allow the application to just keep running with whatever it got.
@@ -0,0 +1,38 @@
1
+ class RakeCommander
2
+ module Patcher
3
+ module Application
4
+ module TopLevelResume
5
+ include RakeCommander::Patcher::Base
6
+
7
+ class << self
8
+ def target
9
+ Rake::Application
10
+ end
11
+
12
+ def patch_prepend(_invoked_by)
13
+ return unless target_defined?
14
+ Rake::Application.prepend Patch
15
+ end
16
+
17
+ def target_defined?
18
+ return true if defined?(target)
19
+ puts "Warning (#{self}): undefined target #{target}"
20
+ false
21
+ end
22
+ end
23
+
24
+ module Patch
25
+ # To preserve `rake` as main executable, as the `RunMethod::Patch` is applied only
26
+ # when `Rake::Application` requires the `Rakefile` that loads `rake-commander`,
27
+ # we technically only need to fix the `top_level_tasks` that have been detected.
28
+ def top_level
29
+ RakeCommander.self_load_reset
30
+ argv = RakeCommander.argv_rake_native_arguments(ARGV)
31
+ Rake.application.send(:collect_command_line_tasks, argv)
32
+ super
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -2,13 +2,11 @@ class RakeCommander
2
2
  module Patcher
3
3
  module Application
4
4
  include RakeCommander::Patcher::Base
5
- require_relative 'application/run_method'
6
- require_relative 'application/top_level_method'
5
+ require_relative 'application/top_level_resume'
7
6
 
8
7
  class << self
9
8
  def patch_include(base)
10
- base.send :include, RunMethod
11
- base.send :include, TopLevelMethod
9
+ base.send :include, TopLevelResume
12
10
  end
13
11
  end
14
12
  end
@@ -1,3 +1,3 @@
1
1
  class RakeCommander
2
- VERSION = '0.2.12'.freeze
2
+ VERSION = '0.3.3'.freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rake-commander
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.12
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oscar Segura Samper
@@ -201,8 +201,7 @@ files:
201
201
  - lib/rake-commander/patcher.rb
202
202
  - lib/rake-commander/patcher/README.md
203
203
  - lib/rake-commander/patcher/application.rb
204
- - lib/rake-commander/patcher/application/run_method.rb
205
- - lib/rake-commander/patcher/application/top_level_method.rb
204
+ - lib/rake-commander/patcher/application/top_level_resume.rb
206
205
  - lib/rake-commander/patcher/base.rb
207
206
  - lib/rake-commander/patcher/debug.rb
208
207
  - lib/rake-commander/patcher/helpers.rb
@@ -1,46 +0,0 @@
1
- class RakeCommander
2
- module Patcher
3
- module Application
4
- module RunMethod
5
- include RakeCommander::Patcher::Base
6
-
7
- class << self
8
- def target
9
- Rake::Application
10
- end
11
-
12
- def patch_prepend(_invoked_by)
13
- return unless target_defined?
14
- Rake::Application.prepend Patch
15
- end
16
-
17
- def target_defined?
18
- return true if defined?(target)
19
- puts "Warning (#{self}): undefined target #{target}"
20
- false
21
- end
22
- end
23
-
24
- module Patch
25
- include RakeCommander::Patcher::Debug
26
-
27
- # To extend the command line syntax we need to patch `Rake`, provided that
28
- # this gem's extended options are not in `argv` when `Rake` processes it.
29
- # @note we define an instance variable so we can know if the patch was applied when it started.
30
- # @note This patch only works fine if `Rake::Application#run` is **invoked after****
31
- # **`RakeCommander` has been required**.
32
- # * So by itself alone it allows to use `raked` executable that this gem provides.
33
- def run(argv = ARGV)
34
- @rake_commander_run_argv_patch = true unless instance_variable_defined?(:@rake_commander_run_argv_patch)
35
- RakeCommander.self_load
36
- rake_comm_debug "R U N !", "\n", num: 1, pid: true
37
- rake_comm_debug " ---> Command: #{$PROGRAM_NAME}"
38
- rake_comm_debug " ---> ARGV: [#{argv.map {|a| "'#{a}'"}.join(', ')}]"
39
- argv = RakeCommander.argv_rake_native_arguments(argv)
40
- super(argv)
41
- end
42
- end
43
- end
44
- end
45
- end
46
- end
@@ -1,74 +0,0 @@
1
- class RakeCommander
2
- module Patcher
3
- module Application
4
- module TopLevelMethod
5
- include RakeCommander::Patcher::Base
6
-
7
- class << self
8
- def target
9
- Rake::Application
10
- end
11
-
12
- def patch_prepend(_invoked_by)
13
- return unless target_defined?
14
- Rake::Application.prepend Patch
15
- end
16
-
17
- def target_defined?
18
- return true if defined?(target)
19
- puts "Warning (#{self}): undefined target #{target}"
20
- false
21
- end
22
- end
23
-
24
- module Patch
25
- include RakeCommander::Patcher::Debug
26
-
27
- # To preserve `rake` as main executable, as the `RunMethod::Patch` is applied only
28
- # when `Rake::Application` requires the `Rakefile` that loads `rake-commander`,
29
- # we need to:
30
- # 1. Intercept the execution on the next stage of the `Rake::Application#run` command,
31
- # [the `top_level` call](https://github.com/ruby/rake/blob/48e798484babf725b0562cc417986da513e5d0ae/lib/rake/application.rb#L82),
32
- # and **re-launch** the rake application (so it only receives the `ARGV` cut that the main patch provides)
33
- # 2. Ensure that **re-launch** is done only once.
34
- # 3. Ensure that it does `exit(0)` to the original running application.
35
- def top_level
36
- unless @rake_commander_run_argv_patch
37
- @rake_commander_run_argv_patch = true
38
- RakeCommander.relaunch_rake_application
39
- # Should not reach this point
40
- end
41
- rake_comm_debug "T O P L E V E L ( p a t c h a c t i v e )", "\n", num: 2, pid: true
42
- rake_comm_debug " ---> Known tasks: #{tasks.map(&:name).join(", ")}"
43
- super
44
- end
45
- end
46
-
47
- module ClassMethods
48
- include RakeCommander::Patcher::Debug
49
-
50
- # Reloading `Rakefile` has drawbacks around `require` only being launched once per
51
- # dependency. Apparently some tasks of some gems are installed at `require` run-time.
52
- # This requires to keep known tasks when we switch the application.
53
- def relaunch_rake_application
54
- prev_rake_app = Rake.application
55
- rake_comm_debug "R A K E R E L A U N C H ( p a t c h i n a c t i v e )", "\n", num: 2, pid: true
56
- rake_comm_debug " ---> Known tasks: #{prev_rake_app.tasks.map(&:name).join(", ")}"
57
- Rake.application = Rake::Application.new
58
- rake_comm_debug "N e w R a k e A p p", "\n", num: 4, pid: true
59
- RakeCommander.self_load_reset
60
- Rake.application.run #RakeCommander.argv_rake_native_arguments(ARGV)
61
- rake_comm_debug "T e r m i n a t i n g R U N", "\n", num: 3, pid: true
62
- exit(0)
63
- end
64
-
65
- private
66
-
67
- def rake_reparse_argv(argv = ARGV)
68
- RakeCommander.argv_rake_native_arguments(argv)
69
- end
70
- end
71
- end
72
- end
73
- end
74
- end