rake-commander 0.2.12 → 0.3.3

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
  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