run_tasks 3.3.0 → 4.0.0

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: db5998bcac4e11397fd0abb44484d48dc78ce538cd31a5768ddadf4f23a3a6ae
4
- data.tar.gz: 8fc911ccdf1f057f3fb8c310185fdd3021eb293710b05b5cc0ce4bf16bd98c6c
3
+ metadata.gz: 18567c31d63e5cacb71de0cf93a2a988a36161add471ba464e0c76fc80e1a5ae
4
+ data.tar.gz: 5e1a9ca0f82fe57c4ebab2bafe9487f588fa436f0c2a14b4e2555bace0874000
5
5
  SHA512:
6
- metadata.gz: 5387ed714265c8705665e5012d1186fc148c87e85d5a6441e66edabc02515eb58c62c03ba71d4451b647d2a5c02f0fbc7ac46a1d8c414734eb2803eb39222559
7
- data.tar.gz: 42ace3eb70928ae2d509cbfa8b26f3696ba55f6cf2a797280957c98e0b7704cafefce72d2e375cc570360b896cc9d1905947d0bd8e8ec8892f7f5297e4067d66
6
+ metadata.gz: b70d57d950528c6182766218104938627b2b9469baccebd1e4472f3ef8ec1363283dd2432d898b4d89bc8173e3a249acfdc02b7fa7eeed99e5598323599cd5eb
7
+ data.tar.gz: 8ba35fe28b3ef9346ff031041b342d641975503d068f9e817df178a429a663a11af423b1f3e1f1c03622043013513603b5b98b57cf10cfbbc5cbf759d9fefd2f
data/README.md ADDED
@@ -0,0 +1,474 @@
1
+ # Run
2
+
3
+ Manage your Ruby projects with a straightforward syntax.
4
+
5
+ ## Compatibility
6
+
7
+ Run is known to work with Ruby >=2.4.
8
+
9
+ ## Installation
10
+
11
+ ```sh
12
+ gem install "run_tasks"
13
+ ```
14
+
15
+ To enable ZSH completions:
16
+
17
+ ```sh
18
+ run install_completions
19
+ ```
20
+
21
+ ## Running Run
22
+
23
+ ```sh
24
+ run your_task
25
+ ```
26
+
27
+ If you want to display the available tasks:
28
+
29
+ ```sh
30
+ run help
31
+ ```
32
+
33
+ > The help provides Run's version, so `run version` will display the same screen.
34
+
35
+ > Note that the command `run` displays the help screen by default when no task is specified.
36
+
37
+ ## Writing tasks
38
+
39
+ ```rb
40
+ # Displays hello.
41
+ task :hello do
42
+ puts "hello!"
43
+ end
44
+ ```
45
+
46
+ The comment is used by the Run to display the help. It must be placed directly above the task and can be multiline.
47
+
48
+ > Note that help verbatims support Markdown syntax.
49
+
50
+ `task` also support aliases, so you can call a task with different names:
51
+
52
+ ```rb
53
+ task [:console, :c] do
54
+ run "bundle exec rails c"
55
+ end
56
+ ```
57
+
58
+ Running `run c` or `run console` will then start the Rails console.
59
+
60
+ ## Running shell commands
61
+
62
+ ```rb
63
+ # Accessing a non-existent file.
64
+ task :boom do
65
+ run "stat foo"
66
+ run "echo 'hello!'"
67
+ end
68
+ ```
69
+
70
+ It outputs:
71
+
72
+ ```sh
73
+ $ run boom
74
+
75
+ > stat foo
76
+
77
+ stat: cannot stat 'foo': No such file or directory
78
+ ```
79
+
80
+ > As you can see, `run` captures errors and stops when something bad happens.
81
+
82
+ ## Calling other tasks
83
+
84
+ You can run tasks arbitrarily from any other task by passing a symbol:
85
+
86
+ ```rb
87
+ task :eslint do
88
+ run "npx eslint"
89
+ end
90
+
91
+ task :flow do
92
+ run "npx flow"
93
+ end
94
+
95
+ task :lint_js do
96
+ run :eslint
97
+ run :flow
98
+ end
99
+ ```
100
+
101
+ By running `run lint_js` you will call `eslint` and `flow` tasks.
102
+
103
+ ## Passing arguments
104
+
105
+ You can pass arguments to tasks from the CLI:
106
+
107
+ ```rb
108
+ task :hello do |name, age|
109
+ puts "Hello #{name}, you are #{age}."
110
+ end
111
+ ```
112
+
113
+ ```sh
114
+ $ run hello 'John Doe' 30
115
+ Hello John Doe, you are 30.
116
+ ```
117
+
118
+ But also from the Runfile itself:
119
+
120
+ ```rb
121
+ task :test do
122
+ run :hello, "John Doe", 30
123
+ end
124
+ ```
125
+
126
+ Every argument passed from the CLI is auto-converted, as a whole:
127
+
128
+ | Argument | Result |
129
+ |-----------------------------------------------------------|-----------|
130
+ | an integer: `42`, `-3`, `0` | `Integer` |
131
+ | a decimal: `1.5`, `0.5`, `-0.5` | `Float` |
132
+ | `true` / `false` | boolean |
133
+ | anything else, including superfluous zeros: `007`, `00.5` | `String` |
134
+
135
+ > Arguments never become symbols: if your task needs one, call `.to_sym`.
136
+
137
+ ### Named parameters
138
+
139
+ Tasks also support named parameters, from the Runfile:
140
+
141
+ ```rb
142
+ task :hello do |name:, age:|
143
+ puts "Hello #{name}, you are #{age}."
144
+ end
145
+
146
+ task :test do
147
+ run :hello, name: "John Doe", age: 30
148
+ end
149
+ ```
150
+
151
+ And from the CLI, with `name=value`:
152
+
153
+ ```sh
154
+ $ run hello name='John Doe' age=30
155
+ Hello John Doe, you are 30.
156
+ ```
157
+
158
+ The value is auto-converted like any other argument. Separate values with commas to pass an array, each element being auto-converted:
159
+
160
+ | Command | Received by the task |
161
+ |----------------------------------------|-------------------------------------|
162
+ | `run review reviewer=clement` | `reviewer: "clement"` |
163
+ | `run review reviewer=clement,morisset` | `reviewer: ["clement", "morisset"]` |
164
+ | `run build retries=3` | `retries: 3` |
165
+ | `run build ids=1,2,x` | `ids: [1, 2, "x"]` |
166
+ | `run build dry=true` | `dry: true` |
167
+ | `run build tag=` | `tag: ""` |
168
+
169
+ > A single value gives a scalar, not an array: if your task expects a list, use `Array(value)`. Commas cannot be escaped.
170
+
171
+ ### Named booleans
172
+
173
+ We also support named booleans. For example, imagine you want to run your server in tunnel mode:
174
+
175
+ ```rb
176
+ task :server do |tunnel: false|
177
+ run "my_server #{tunnel ? "--tunnel" : ""}"
178
+ end
179
+ ```
180
+
181
+ When you call...
182
+
183
+ ```sh
184
+ run server +tunnel
185
+ ```
186
+
187
+ ...the parameter `tunnel: true` will be passed to your task. The same if you pass `-tunnel`, it will pass `false`.
188
+
189
+ ### Additional notes
190
+
191
+ - Hyphens in names are replaced by underscores: `+dry-run` and `dry-run=1` give `dry_run:`.
192
+ - A name cannot be given twice (`a=1 a=2`, `+a -a`, `+a a=2`).
193
+ - A task receiving named parameters or booleans must declare keywords (`reviewer:`, `**options`…). A task declaring keywords and receiving an unknown one fails too, as with any Ruby block.
194
+
195
+ ## Quiet mode
196
+
197
+ If you want to run a task (or a command) without it to being able to write on STDOUT/STDERR, pass the quiet flag to true :
198
+
199
+ ```rb
200
+ task :echo do
201
+ run "echo 'test'", quiet: true
202
+ end
203
+ ```
204
+
205
+ It's useful, for example, when you want to delete a file at the beginning of a task without it to being verbose when the file does not exist.
206
+
207
+ ## Colorization & styles
208
+
209
+ It is often needed to colorize/stylize the messages sent to the user with `puts`. For this matter, Run is natively shipped with basic styles.
210
+
211
+ For example:
212
+
213
+ ```rb
214
+ puts "Please wait...".yellow.bold
215
+ ```
216
+
217
+ The available styles are :
218
+
219
+ - bold
220
+ - dim
221
+ - italic
222
+ - underline
223
+ - inverse
224
+ - strikethrough
225
+
226
+ And the available colors are :
227
+
228
+ - black
229
+ - red
230
+ - green
231
+ - yellow
232
+ - blue
233
+ - magenta
234
+ - cyan
235
+ - white
236
+ - bright_black
237
+ - bright_red
238
+ - bright_green
239
+ - bright_yellow
240
+ - bright_blue
241
+ - bright_magenta
242
+ - bright_cyan
243
+ - bright_white
244
+
245
+ ## Helpers
246
+
247
+ Run comes with a few helpers to help writing tasks quicker.
248
+
249
+ ### are_you_sure
250
+
251
+ When called, it asks a question to the user which has the choice to enter `y`, `yes`, `n` or `no` (the default answer). When `no` is selected, the task will exit with a `9` code.
252
+
253
+ ```rb
254
+ task :dangerous_task do
255
+ are_you_sure "This task will delete your hard drive. Are you sure about that?"
256
+ # Some dangerous actions.
257
+ end
258
+ ```
259
+
260
+ ### bind
261
+
262
+ `bind` lets you group several tasks/processes so when one stops all the other will stop as well.
263
+
264
+ ```rb
265
+ task :dev do
266
+ bind :rails, :vite
267
+ end
268
+
269
+ task :rails do
270
+ run "bundle exec unicorn -c config/unicorn.rb -p 3000"
271
+ end
272
+
273
+ task :vite do
274
+ run "bin/vite dev"
275
+ end
276
+ ```
277
+
278
+ ### catch_interruption
279
+
280
+ Alternatively, if you have a command that stays open until you hit `CTRL+C` (like a Docker container) and you need to catch the binding, you probably want to use `catch_interruption` instead so it lets the command handle the interruption gracefully and executes some actions afterwards.
281
+
282
+ ```rb
283
+ # Run server in development mode.
284
+ task :server do
285
+ catch_interruption("docker run -d -p 8080:80 web_server") do
286
+ # Run some clean up actions here after the command has been interrupted.
287
+ end
288
+ end
289
+ ```
290
+
291
+ ### exists
292
+
293
+ Handy helper to verify if a program exists.
294
+
295
+ ```rb
296
+ task :man do
297
+ command = exists("bat") ? "bat" : "cat"
298
+ run "#{command} #{__dir__}/README.md"
299
+ end
300
+ ```
301
+
302
+ ### expand
303
+
304
+ This one takes a glob string and process it to return a list of files.
305
+
306
+ ```rb
307
+ task :scan do |glob|
308
+ expand(glob).each do |file_path|
309
+ # Do something.
310
+ end
311
+ end
312
+ ```
313
+
314
+ ### menu
315
+
316
+ It displays an advanced menu where you can choose an element that will be returned by the function.
317
+
318
+ ```rb
319
+ # Array syntax
320
+ task :deploy_aws do
321
+ region = menu "Location?", ["us‑east‑2", "us-west-1", "eu-west-1"]
322
+ end
323
+ ```
324
+
325
+ ```rb
326
+ # Hash syntax
327
+ task :deploy_aws do
328
+ region = menu "Location?", {
329
+ "US East (Ohio)" => "us‑east‑2",
330
+ "US West (N. California)" => "us-west-1",
331
+ "Europe (Ireland)" => "eu-west-1",
332
+ }
333
+ end
334
+ ```
335
+
336
+ ### pause
337
+
338
+ You can pause a task if needed, waiting for the user to press any key.
339
+
340
+ ```rb
341
+ task :deploy do
342
+ puts "Press enter to continue.".yellow
343
+ pause
344
+ run :deploy_production
345
+ end
346
+ ```
347
+
348
+ ### question
349
+
350
+ Displays a question and returns the answer.
351
+
352
+ ```rb
353
+ task :survey do
354
+ comment = question "Did your meal was good?"
355
+ end
356
+ ```
357
+
358
+ You can also pass a regex to validation the entered value:
359
+
360
+ ```rb
361
+ task :age do
362
+ age = question "What is your age?", /^\d+$/
363
+ end
364
+ ```
365
+
366
+ A default value can be set, it will be returned if the user enters nothing:
367
+
368
+ ```rb
369
+ task :age do
370
+ age = question "What is your age?", /^\d+$/, default: "30"
371
+ end
372
+ ```
373
+
374
+ ### yesno
375
+
376
+ Asks a yes/no question and returns a boolean. The user can answer `y`, `yes`, `n` or `no`.
377
+
378
+ ```rb
379
+ task :deploy do
380
+ run :migrate if yesno "Run migrations?"
381
+ end
382
+ ```
383
+
384
+ Without a default value, an answer is required. With one, it is returned if the user enters nothing:
385
+
386
+ ```rb
387
+ task :deploy do
388
+ run :migrate if yesno "Run migrations?", default: true
389
+ end
390
+ ```
391
+
392
+ ### wait_for_interruption
393
+
394
+ If you need to wait for the user to interrupt a task of, for example, several running servers, you can use the `wait_for_interruption` helper.
395
+
396
+ ```rb
397
+ # Run server in development mode.
398
+ task :server do
399
+ Thread.new do
400
+ # Run first server.
401
+ end
402
+ Thread.new do
403
+ # Run second server.
404
+ end
405
+ # Wait for CTRL+C.
406
+ wait_for_interruption do
407
+ # Some actions to handle before terminating the task, like killing the servers.
408
+ end
409
+ end
410
+ ```
411
+
412
+ ## Base tasks
413
+
414
+ Run also comes with some generic tasks for recurring tasks.
415
+
416
+ ### publish
417
+
418
+ You can publish your library with:
419
+
420
+ ```sh
421
+ run publish
422
+ ```
423
+
424
+ > At the moment, this is only compatible with gems.
425
+
426
+ ### rspec
427
+
428
+ You can call directly `run rspec` or abstract the task like this:
429
+
430
+ ```rb
431
+ # Run the tests.
432
+ task [:specs, :s, :tests, :t] do |path = "spec/src"|
433
+ run :rspec, path
434
+ end
435
+ ```
436
+
437
+ > The `rspec` task will look into `spec/src` by default, so the above task is just explanatory is you want overload default behaviour.
438
+
439
+ ## Advanced usage
440
+
441
+ ### Specifying Runfile path
442
+
443
+ If you want to load Run from another directory, you have two choices :
444
+
445
+ - change the working directory in your script,
446
+ - or pass the Runfile path with `RUNFILE=/path/to/Runfile.rb run my_task`
447
+
448
+ ### Exit codes
449
+
450
+ Run has specific exit codes so you can handle it better in some environments, like in CI or in deployments:
451
+
452
+ - 1: Run has exited abnormally.
453
+ - 2: The required task does not exist.
454
+ - 3: Unhandled Interrupt error coming from a failed shell command.
455
+ - 4: An error has been raised in the Runfile.
456
+ - 5: The Runfile contains a syntax error.
457
+ - 6: Some parameters are invalid.
458
+ - 7: Runfile not found.
459
+ - 8: Unable to load a remote file.
460
+ - 9: The user has answered "No" to an "Are you sure?" question.
461
+ - 10: The required task already exists.
462
+ - 11: The required command is not running.
463
+ - 12: The required task does not exist.
464
+
465
+ ## Development
466
+
467
+ For test purposes, it's often needed to install Run from a development branch. For this, you'll need to follow these steps:
468
+
469
+ ```sh
470
+ gem install specific_install
471
+ gem specific_install http://github.com/pyrsmk/run.git <branch>
472
+ ```
473
+
474
+ Do not forget to uninstall other `run_tasks` packages if needed, to avoid conflicts. And if you're under Rbenv, you'll probably need to do `rbenv rehash` too.
data/src/bootstrap.rb CHANGED
@@ -7,7 +7,6 @@ require "readline"
7
7
  require "rubygems"
8
8
  require "securerandom"
9
9
  require "rb_monkey"
10
- require "rb_gemspec"
11
10
  require "rb_markdown"
12
11
 
13
12
  # Require all files.
@@ -77,11 +76,6 @@ task :publish do
77
76
  `rm #{gemspec.name}-#{gemspec.version}.gem`
78
77
  end
79
78
 
80
- # Display the manual.
81
- task :man do
82
- puts Markdown::Engine.new(File.read("#{__dir__}/../CHEATSHEET.md")).to_ansi
83
- end
84
-
85
79
  # Expose helpers.
86
80
  Dir.glob(File.join(__dir__, "run", "helper", "*.rb")) do |path|
87
81
  filename = File.basename(path, ".rb")
@@ -117,6 +111,9 @@ rescue Interrupt
117
111
  rescue SyntaxError => error
118
112
  format_error error
119
113
  exit 5
114
+ rescue Run::Error::DuplicateParameter, Run::Error::UnexpectedNamedParameters => error
115
+ puts error.message.red
116
+ exit 6
120
117
  rescue ArgumentError => error
121
118
  format_error error
122
119
  exit 6
data/src/run/core.rb CHANGED
@@ -4,6 +4,9 @@ module Run
4
4
  module Core
5
5
  RUNFILE_FILENAME = ENV.fetch('RUNFILE', 'Runfile.rb')
6
6
  RESERVED_TASK_NAMES = ["help", "version"]
7
+ NAME_PATTERN = /[a-zA-Z_]\w*(?:-\w+)*/
8
+ OPTION_PATTERN = /\A([+-])(#{NAME_PATTERN})\z/
9
+ NAMED_PARAMETER_PATTERN = /\A(#{NAME_PATTERN})=(.*)\z/m
7
10
  @@tasks = []
8
11
  @@runfile_version = nil
9
12
 
@@ -22,7 +25,7 @@ module Run
22
25
  end
23
26
  raise Run::Error::NonExistingRunfile.new if !File.file?(RUNFILE_FILENAME)
24
27
  if ARGV.size == 1 && ARGV[0] == "version"
25
- puts version
28
+ puts VERSION
26
29
  elsif ARGV.size == 0 || (ARGV.size == 1 && ARGV[0] == "help")
27
30
  require File.expand_path(RUNFILE_FILENAME)
28
31
  check_runfile_version!
@@ -73,16 +76,11 @@ module Run
73
76
 
74
77
  # @return [void]
75
78
  def self.check_runfile_version!
76
- if (@@runfile_version || 2) != version.to_s.split(".").first.to_i
79
+ if (@@runfile_version || 2) != VERSION.split(".").first.to_i
77
80
  raise Run::Error::RunfileVersionMismatch.new
78
81
  end
79
82
  end
80
83
 
81
- # @return [void]
82
- def self.display_version
83
- puts Gemspec::Metadata.new("run_tasks").read.version
84
- end
85
-
86
84
  # @return [void]
87
85
  def self.completions
88
86
  (@@tasks.flat_map{ |t| t[:names] }.map(&:to_s) + RESERVED_TASK_NAMES).sort.uniq
@@ -91,19 +89,13 @@ module Run
91
89
  # @return [void]
92
90
  def self.display_help
93
91
  puts
94
- puts " Run v#{version}".bright_blue
92
+ puts " Run v#{VERSION}".bright_blue
95
93
  contents = Run::Core::Help.run(File.read(File.join(Dir.pwd, RUNFILE_FILENAME)))
96
94
  if contents.strip.size > 0
97
- puts
98
- puts " Project tasks:".magenta
99
95
  puts
100
96
  puts contents
101
97
  end
102
98
  puts
103
- puts " Global tasks:".magenta
104
- puts
105
- puts Run::Core::Help.run(File.read(File.join(__dir__, "..", "bootstrap.rb")))
106
- puts
107
99
  end
108
100
 
109
101
  # @return [void]
@@ -111,32 +103,60 @@ module Run
111
103
  name = ARGV[0].gsub('-', '_').to_sym # Auto-replace hyphens to underscores.
112
104
  raise Run::Error::UnknownTask.new(name) if !task_exist?(name)
113
105
 
106
+ args, options = parse_arguments(ARGV.drop(1))
107
+ run name, *args, **options
108
+ end
109
+
110
+ # @param words [Array<String>]
111
+ # @return [Array(Array, Hash)]
112
+ def self.parse_arguments(words)
114
113
  args = []
115
114
  options = {}
116
115
 
117
- ARGV.slice(1, ARGV.size - 1).each do |arg|
118
- if (match = arg.match(/^\+([a-zA-Z_]\w*)$/))
119
- options[match[1].to_sym] = true
120
- next
121
- elsif (match = arg.match(/^-([a-zA-Z_]\w*)$/))
122
- options[match[1].to_sym] = false
123
- next
124
- elsif arg.match?(/^-?(?:0|[1-9]\d*)$/)
125
- args << Integer(arg, 10)
126
- next
127
- elsif arg.match?(/^-?\d+\.\d+$/)
128
- args << Float(arg)
129
- next
116
+ words.each do |word|
117
+ if (match = word.match(OPTION_PATTERN))
118
+ sign, name = match.captures
119
+ add_option(options, name, sign == "+")
120
+ elsif (match = word.match(NAMED_PARAMETER_PATTERN))
121
+ name, value = match.captures
122
+ add_option(options, name, convert_named_value(value))
123
+ else
124
+ args << convert_argument(word)
130
125
  end
131
- raise
132
- rescue
133
- next args << true if arg == "true"
134
- next args << false if arg == "false"
135
- next args << arg.to_sym if arg.match?(/^\w+$/)
136
- args << arg
137
126
  end
138
127
 
139
- run name, *args, **options
128
+ [args, options]
129
+ end
130
+
131
+ # @param value [String]
132
+ # @return [Integer, Float, Boolean, String]
133
+ def self.convert_argument(value)
134
+ case value
135
+ when /\A-?(?:0|[1-9]\d*)\z/ then Integer(value, 10)
136
+ when /\A-?(?:0|[1-9]\d*)\.\d+\z/ then Float(value)
137
+ when "true" then true
138
+ when "false" then false
139
+ else value
140
+ end
141
+ end
142
+
143
+ # @param value [String]
144
+ # @return [Object, Array]
145
+ def self.convert_named_value(value)
146
+ return convert_argument(value) if !value.include?(",")
147
+
148
+ value.split(",", -1).map { |item| convert_argument(item) }
149
+ end
150
+
151
+ # @param options [Hash]
152
+ # @param name [String]
153
+ # @param value [Object]
154
+ # @return [void]
155
+ def self.add_option(options, name, value)
156
+ key = name.tr("-", "_").to_sym
157
+ raise Run::Error::DuplicateParameter.new(key) if options.key?(key)
158
+
159
+ options[key] = value
140
160
  end
141
161
 
142
162
  # @param name [Symbol]
@@ -152,6 +172,9 @@ module Run
152
172
  def self.run_block_task(name, *args, **options)
153
173
  task = @@tasks.find{ |item| item[:names].include? name }
154
174
  raise Error::NonExistingTask.new(name) if task.nil?
175
+ if options.any? && !task[:task].accepts_keywords?
176
+ raise Error::UnexpectedNamedParameters.new(name, options.keys)
177
+ end
155
178
 
156
179
  task[:task].run(*args, **options)
157
180
  end
@@ -162,11 +185,6 @@ module Run
162
185
  Run::Task::SystemTask.new(command).run
163
186
  end
164
187
 
165
- # @return [String]
166
- def self.version
167
- Gemspec::Metadata.new("run_tasks").read.version
168
- end
169
-
170
188
  # @return [Boolean]
171
189
  def self.quiet?
172
190
  !!Thread.current[:quiet]
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Run
4
+ module Error
5
+ class DuplicateParameter < StandardError
6
+ # @param name [Symbol]
7
+ def initialize(name)
8
+ super "Parameter '#{name}' is given more than once"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Run
4
+ module Error
5
+ class UnexpectedNamedParameters < StandardError
6
+ # @param task_name [Symbol]
7
+ # @param names [Array<Symbol>]
8
+ def initialize(task_name, names)
9
+ super "Task '#{task_name}' does not accept named parameters: #{names.join(", ")}"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -8,15 +8,16 @@ module Run
8
8
  @block = block
9
9
  end
10
10
 
11
+ # @return [Boolean]
12
+ def accepts_keywords?
13
+ @block.parameters.any?{ |type, _| [:key, :keyreq, :keyrest].include?(type) }
14
+ end
15
+
11
16
  # @param arguments [Array]
12
17
  # @param options [Hash]
13
18
  # @return [void]
14
19
  def run(*arguments, **options)
15
- if options.size == 0
16
- @block.call *arguments
17
- else
18
- @block.call *arguments, **options
19
- end
20
+ @block.call(*arguments, **options)
20
21
  end
21
22
  end
22
23
  end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Run
4
+ VERSION = "4.0.0"
5
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: run_tasks
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aurélien Delogu
@@ -37,20 +37,6 @@ dependencies:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
39
  version: 0.1.0
40
- - !ruby/object:Gem::Dependency
41
- name: rb_gemspec
42
- requirement: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - "~>"
45
- - !ruby/object:Gem::Version
46
- version: 0.2.1
47
- type: :runtime
48
- prerelease: false
49
- version_requirements: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - "~>"
52
- - !ruby/object:Gem::Version
53
- version: 0.2.1
54
40
  - !ruby/object:Gem::Dependency
55
41
  name: rb_markdown
56
42
  requirement: !ruby/object:Gem::Requirement
@@ -71,18 +57,20 @@ executables:
71
57
  extensions: []
72
58
  extra_rdoc_files: []
73
59
  files:
74
- - CHEATSHEET.md
60
+ - README.md
75
61
  - bin/run
76
62
  - completions/_run
77
63
  - src/bootstrap.rb
78
64
  - src/run/core.rb
79
65
  - src/run/core/help.rb
80
66
  - src/run/error/aborted.rb
67
+ - src/run/error/duplicate_parameter.rb
81
68
  - src/run/error/existing_task.rb
82
69
  - src/run/error/non_existing_runfile.rb
83
70
  - src/run/error/non_existing_task.rb
84
71
  - src/run/error/reserved_task_name.rb
85
72
  - src/run/error/runfile_version_mismatch.rb
73
+ - src/run/error/unexpected_named_parameters.rb
86
74
  - src/run/error/unknown_task.rb
87
75
  - src/run/helper/are_you_sure_helper.rb
88
76
  - src/run/helper/bind_helper.rb
@@ -96,6 +84,7 @@ files:
96
84
  - src/run/helper/yesno_helper.rb
97
85
  - src/run/task/block_task.rb
98
86
  - src/run/task/system_task.rb
87
+ - src/run/version.rb
99
88
  homepage: https://github.com/pyrsmk/run
100
89
  licenses:
101
90
  - MIT
data/CHEATSHEET.md DELETED
@@ -1,238 +0,0 @@
1
- # Defining a task
2
-
3
- ```rb
4
- task :eslint do
5
- end
6
- ```
7
-
8
- # Defining a task with aliases
9
-
10
- ```rb
11
- task [:console, :c] do
12
- end
13
- ```
14
-
15
- # Defining a task with parameters
16
-
17
- ```rb
18
- task :hello do |name, age|
19
- puts "Hello #{name}, you are #{age}."
20
- end
21
- ```
22
-
23
- # Running commands
24
-
25
- ```rb
26
- task :clear_all do
27
- run "rm -rf /*"
28
- end
29
- ```
30
-
31
- # Running subtasks
32
-
33
- ```rb
34
- task :linting do
35
- run :eslint
36
- run :rubocop
37
- end
38
- ```
39
-
40
- # Running a task/command in quiet mode
41
-
42
- ```rb
43
- task :clear_cache do
44
- run "rm -rf cache/*", quiet: true
45
- end
46
- ```
47
-
48
- # Using named booleans
49
-
50
- ```sh
51
- run server +tunnel
52
- ```
53
-
54
- ```rb
55
- task :server do |tunnel: false|
56
- run "http_server #{tunnel ? "--tunnel" : ""}"
57
- end
58
- ```
59
-
60
- # Helpers
61
-
62
- ## are_you_sure
63
-
64
- ```rb
65
- task :dangerous_task do
66
- are_you_sure "This task will delete your hard drive. Are you sure about that?"
67
- # Some dangerous actions.
68
- end
69
- ```
70
-
71
- ## bind
72
-
73
- ```rb
74
- task :rails do
75
- run "bundle exec unicorn -c config/unicorn.rb -p 3000"
76
- end
77
-
78
- task :vite do
79
- run "bin/vite dev"
80
- end
81
-
82
- task :dev do
83
- # Bind `rails` and `vite` tasks together, if one closes, the other terminates too.
84
- bind :rails, :vite
85
- end
86
- ```
87
-
88
- ```rb
89
- task :dev do
90
- # Plug STDIN to the `rails` task.
91
- bind :rails, :vite, stdin: :rails
92
- end
93
- ```
94
-
95
- ## catch_interruption
96
-
97
- ```rb
98
- task :server do
99
- catch_interruption("docker run -d -p 8080:80 web_server") do
100
- run :clear_cache
101
- end
102
- end
103
- ```
104
-
105
- ## exists
106
-
107
- ```rb
108
- task :man do
109
- command = exists("bat") ? "bat" : "cat"
110
- run "#{command} #{__dir__}/README.md"
111
- end
112
- ```
113
-
114
- ## expand
115
-
116
- ```rb
117
- task :scan do |glob|
118
- expand(glob).each do |file_path|
119
- puts file_path
120
- end
121
- end
122
- ```
123
-
124
- ## menu
125
-
126
- ```rb
127
- task :deploy_aws do
128
- region = menu "Location?", ["us‑east‑2", "us-west-1", "eu-west-1"]
129
- end
130
- ```
131
-
132
- ```rb
133
- task :deploy_aws do
134
- region = menu "Location?", {
135
- "US East (Ohio)" => "us‑east‑2",
136
- "US West (N. California)" => "us-west-1",
137
- "Europe (Ireland)" => "eu-west-1",
138
- }
139
- end
140
- ```
141
-
142
- ## pause
143
-
144
- ```rb
145
- task :deploy do
146
- puts "Press enter to continue.".yellow
147
- pause
148
- run :deploy_production
149
- end
150
- ```
151
-
152
- ## question
153
-
154
- ```rb
155
- task :survey do
156
- comment = question "Did your meal was good?"
157
- end
158
- ```
159
-
160
- ```rb
161
- task :age do
162
- age = question "What is your age?", /^\d+$/
163
- end
164
- ```
165
-
166
- ```rb
167
- task :age do
168
- age = question "What is your age?", /^\d+$/, default: "30"
169
- end
170
- ```
171
-
172
- ## yesno
173
-
174
- ```rb
175
- task :deploy do
176
- run :migrate if yesno "Run migrations?"
177
- end
178
- ```
179
-
180
- ```rb
181
- task :deploy do
182
- run :migrate if yesno "Run migrations?", default: true
183
- end
184
- ```
185
-
186
- ## wait_for_interruption
187
-
188
- ```rb
189
- task :server do
190
- Thread.new do
191
- run :rails
192
- end
193
- Thread.new do
194
- run :vite
195
- end
196
- wait_for_interruption do
197
- run :kill_rails
198
- run :kill_vite
199
- end
200
- end
201
- ```
202
-
203
- # Colorization
204
-
205
- ```rb
206
- puts "hello".bold
207
- puts "hello".dim
208
- puts "hello".italic
209
- puts "hello".underline
210
- puts "hello".inverse
211
- puts "hello".strikethrough
212
- puts "hello".black
213
- puts "hello".red
214
- puts "hello".green
215
- puts "hello".yellow
216
- puts "hello".blue
217
- puts "hello".magenta
218
- puts "hello".cyan
219
- puts "hello".white
220
- puts "hello".bright_black
221
- puts "hello".bright_red
222
- puts "hello".bright_green
223
- puts "hello".bright_yellow
224
- puts "hello".bright_blue
225
- puts "hello".bright_magenta
226
- puts "hello".bright_cyan
227
- puts "hello".bright_white
228
- ```
229
-
230
- ```rb
231
- puts "hello".green.bold.italic
232
- ```
233
-
234
- # Advanced usage
235
-
236
- ```sh
237
- RUNFILE=/path/to/Runfile.rb run my_task
238
- ```