modulesync 2.1.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +29 -9
  3. data/.github/workflows/release.yml +7 -7
  4. data/.gitignore +1 -0
  5. data/.rubocop.yml +14 -8
  6. data/.rubocop_todo.yml +25 -17
  7. data/.simplecov +46 -0
  8. data/CHANGELOG.md +58 -0
  9. data/Gemfile +5 -3
  10. data/LICENSE +173 -12
  11. data/README.md +30 -0
  12. data/bin/msync +17 -1
  13. data/features/cli.feature +12 -6
  14. data/features/execute.feature +51 -0
  15. data/features/hook.feature +5 -8
  16. data/features/push.feature +46 -0
  17. data/features/reset.feature +57 -0
  18. data/features/step_definitions/git_steps.rb +29 -1
  19. data/features/support/env.rb +9 -0
  20. data/features/update/bump_version.feature +8 -12
  21. data/features/update/dot_sync.feature +52 -0
  22. data/features/update/pull_request.feature +180 -0
  23. data/features/update.feature +74 -103
  24. data/lib/modulesync/cli/thor.rb +12 -0
  25. data/lib/modulesync/cli.rb +122 -28
  26. data/lib/modulesync/git_service/base.rb +63 -0
  27. data/lib/modulesync/git_service/factory.rb +28 -0
  28. data/lib/modulesync/{pr → git_service}/github.rb +23 -21
  29. data/lib/modulesync/git_service/gitlab.rb +62 -0
  30. data/lib/modulesync/git_service.rb +96 -0
  31. data/lib/modulesync/hook.rb +11 -13
  32. data/lib/modulesync/renderer.rb +3 -6
  33. data/lib/modulesync/repository.rb +78 -28
  34. data/lib/modulesync/settings.rb +0 -1
  35. data/lib/modulesync/source_code.rb +28 -2
  36. data/lib/modulesync/util.rb +4 -4
  37. data/lib/modulesync.rb +104 -66
  38. data/modulesync.gemspec +9 -5
  39. data/spec/helpers/faker/puppet_module_remote_repo.rb +16 -1
  40. data/spec/spec_helper.rb +2 -0
  41. data/spec/unit/modulesync/git_service/factory_spec.rb +16 -0
  42. data/spec/unit/modulesync/git_service/github_spec.rb +81 -0
  43. data/spec/unit/modulesync/git_service/gitlab_spec.rb +90 -0
  44. data/spec/unit/modulesync/git_service_spec.rb +201 -0
  45. data/spec/unit/modulesync/source_code_spec.rb +22 -0
  46. data/spec/unit/modulesync_spec.rb +0 -12
  47. metadata +96 -14
  48. data/lib/modulesync/pr/gitlab.rb +0 -54
  49. data/spec/unit/modulesync/pr/github_spec.rb +0 -49
  50. data/spec/unit/modulesync/pr/gitlab_spec.rb +0 -81
@@ -14,9 +14,8 @@ Feature: update
14
14
  """
15
15
  <%= @configs['name'] %>
16
16
  """
17
- When I run `msync update --noop`
18
- Then the exit status should be 0
19
- And the output should match:
17
+ When I successfully run `msync update --noop`
18
+ Then the output should match:
20
19
  """
21
20
  Files added:
22
21
  test
@@ -37,9 +36,8 @@ Feature: update
37
36
  """
38
37
  <%= @configs['name'] %>
39
38
  """
40
- When I run `msync update -s -m "Add test"`
41
- Then the exit status should be 0
42
- And the puppet module "puppet-test" from "fakenamespace" should have no commits made by "Aruba"
39
+ When I successfully run `msync update -s -m "Add test"`
40
+ Then the puppet module "puppet-test" from "fakenamespace" should have no commits made by "Aruba"
43
41
 
44
42
  Scenario: Adding a new file to repo without write access
45
43
  Given a basic setup with a puppet module "puppet-test" from "fakenamespace"
@@ -72,9 +70,8 @@ Feature: update
72
70
  """
73
71
  <%= @configs['name'] %>
74
72
  """
75
- When I run `msync update --noop`
76
- Then the exit status should be 0
77
- And the output should match:
73
+ When I successfully run `msync update --noop`
74
+ Then the output should match:
78
75
  """
79
76
  Warning: using './moduleroot/test' as template without '.erb' suffix
80
77
  """
@@ -99,9 +96,8 @@ Feature: update
99
96
  """
100
97
  <%= @configs['name'] %>
101
98
  """
102
- When I run `msync update --noop`
103
- Then the exit status should be 0
104
- And the output should match:
99
+ When I successfully run `msync update --noop`
100
+ Then the output should match:
105
101
  """
106
102
  Files added:
107
103
  test
@@ -125,9 +121,8 @@ Feature: update
125
121
  """
126
122
  <%= @configs['name'] %>
127
123
  """
128
- When I run `msync update --noop`
129
- Then the exit status should be 0
130
- And the output should match:
124
+ When I successfully run `msync update --noop`
125
+ Then the output should match:
131
126
  """
132
127
  Files added:
133
128
  test
@@ -151,9 +146,8 @@ Feature: update
151
146
  """
152
147
  <%= @configs['name'] %>
153
148
  """
154
- When I run `msync update --noop`
155
- Then the exit status should be 0
156
- And the output should match:
149
+ When I successfully run `msync update --noop`
150
+ Then the output should match:
157
151
  """
158
152
  Files added:
159
153
  test
@@ -195,9 +189,8 @@ Feature: update
195
189
  <%= c['name'] %>
196
190
  <% end %>
197
191
  """
198
- When I run `msync update --noop -s`
199
- Then the exit status should be 0
200
- And the puppet module "puppet-test" from "fakenamespace" should have no commits made by "Aruba"
192
+ When I successfully run `msync update --noop -s`
193
+ Then the puppet module "puppet-test" from "fakenamespace" should have no commits made by "Aruba"
201
194
 
202
195
  Scenario: Using skip_broken and fail_on_warnings options with invalid files
203
196
  Given a basic setup with a puppet module "puppet-test" from "fakenamespace"
@@ -235,9 +228,8 @@ Feature: update
235
228
  """
236
229
  source '<%= @configs['gem_source'] %>'
237
230
  """
238
- When I run `msync update --noop`
239
- Then the exit status should be 0
240
- And the output should match:
231
+ When I successfully run `msync update --noop`
232
+ Then the output should match:
241
233
  """
242
234
  Files changed:
243
235
  +diff --git a/Gemfile b/Gemfile
@@ -265,9 +257,8 @@ Feature: update
265
257
  """
266
258
  source '<%= @configs['gem_source'] %>'
267
259
  """
268
- When I run `msync update -m "Update Gemfile" -r test`
269
- Then the exit status should be 0
270
- And the puppet module "puppet-test" from "fakenamespace" should have only 1 commit made by "Aruba"
260
+ When I successfully run `msync update -m "Update Gemfile" -r test`
261
+ Then the puppet module "puppet-test" from "fakenamespace" should have only 1 commit made by "Aruba"
271
262
  And the puppet module "puppet-test" from "fakenamespace" should have 1 commit made by "Aruba" in branch "test"
272
263
  And the puppet module "puppet-test" from "fakenamespace" should have a branch "test" with a file named "Gemfile" which contains:
273
264
  """
@@ -292,7 +283,7 @@ Feature: update
292
283
  """
293
284
  source '<%= @configs['gem_source'] %>'
294
285
  """
295
- When I run `msync update --noop`
286
+ When I successfully run `msync update --noop`
296
287
  Then the output should not match:
297
288
  """
298
289
  Files changed:
@@ -302,7 +293,6 @@ Feature: update
302
293
  """
303
294
  Not managing 'Gemfile' in 'puppet-test'
304
295
  """
305
- And the exit status should be 0
306
296
  And the file named "modules/fakenamespace/puppet-test/Gemfile" should contain:
307
297
  """
308
298
  source 'https://rubygems.org'
@@ -326,14 +316,13 @@ Feature: update
326
316
  """
327
317
  source 'https://rubygems.org'
328
318
  """
329
- When I run `msync update --noop`
319
+ When I successfully run `msync update --noop`
330
320
  Then the output should match:
331
321
  """
332
322
  Files changed:
333
323
  diff --git a/Gemfile b/Gemfile
334
324
  deleted file mode 100644
335
325
  """
336
- And the exit status should be 0
337
326
  And the puppet module "puppet-test" from "fakenamespace" should have no commits made by "Aruba"
338
327
 
339
328
  Scenario: Setting a non-existent file to deleted
@@ -345,12 +334,12 @@ Feature: update
345
334
  delete: true
346
335
  """
347
336
  And a directory named "moduleroot"
348
- When I run `msync update -m 'deletes a file that doesnt exist!' -f puppet-test`
349
- And the exit status should be 0
350
- And the puppet module "puppet-test" from "fakenamespace" should have no commits made by "Aruba"
337
+ When I successfully run `msync update -m 'deletes a file that doesnt exist!' -f puppet-test`
338
+ Then the puppet module "puppet-test" from "fakenamespace" should have no commits made by "Aruba"
351
339
 
352
340
  Scenario: Setting a directory to unmanaged
353
341
  Given a basic setup with a puppet module "puppet-apache" from "puppetlabs"
342
+ And I successfully run `msync clone`
354
343
  And a file named "config_defaults.yml" with:
355
344
  """
356
345
  ---
@@ -367,17 +356,15 @@ Feature: update
367
356
  """
368
357
  This is a fake spec_helper!
369
358
  """
370
- When I run `msync update --offline`
359
+ When I successfully run `msync update --offline`
371
360
  Then the output should contain:
372
361
  """
373
362
  Not managing 'spec/spec_helper.rb' in 'puppet-apache'
374
363
  """
375
- And the exit status should be 0
376
364
  And the file named "modules/puppetlabs/puppet-apache/spec/spec_helper.rb" should contain:
377
365
  """
378
366
  This is a fake spec_helper!
379
367
  """
380
- And the exit status should be 0
381
368
  And the puppet module "puppet-apache" from "puppetlabs" should have no commits made by "Aruba"
382
369
 
383
370
  Scenario: Adding a new file in a new subdirectory
@@ -395,9 +382,8 @@ Feature: update
395
382
  require '<%= required %>'
396
383
  <% end %>
397
384
  """
398
- When I run `msync update --noop`
399
- Then the exit status should be 0
400
- And the output should match:
385
+ When I successfully run `msync update --noop`
386
+ Then the output should match:
401
387
  """
402
388
  Files added:
403
389
  spec/spec_helper.rb
@@ -410,6 +396,7 @@ Feature: update
410
396
 
411
397
  Scenario: Updating offline
412
398
  Given a basic setup with a puppet module "puppet-test" from "fakenamespace"
399
+ And I successfully run `msync clone`
413
400
  And a file named "config_defaults.yml" with:
414
401
  """
415
402
  ---
@@ -423,17 +410,15 @@ Feature: update
423
410
  require '<%= required %>'
424
411
  <% end %>
425
412
  """
426
- When I run `msync update --offline`
427
- Then the exit status should be 0
428
- And the output should not match /Files (changed|added|deleted):/
413
+ When I successfully run `msync update --offline`
414
+ Then the output should not match /Files (changed|added|deleted):/
429
415
  And the puppet module "puppet-test" from "fakenamespace" should have no commits made by "Aruba"
430
416
 
431
417
  Scenario: Pulling a module that already exists in the modules directory
432
418
  Given a basic setup with a puppet module "puppet-test" from "fakenamespace"
433
419
  And a directory named "moduleroot"
434
- When I run `msync update --message "First update run"`
435
- Then the exit status should be 0
436
- And the puppet module "puppet-test" from "fakenamespace" should have no commits made by "Aruba"
420
+ When I successfully run `msync update --message "First update run"`
421
+ Then the puppet module "puppet-test" from "fakenamespace" should have no commits made by "Aruba"
437
422
  Given a file named "config_defaults.yml" with:
438
423
  """
439
424
  ---
@@ -447,9 +432,8 @@ Feature: update
447
432
  require '<%= required %>'
448
433
  <% end %>
449
434
  """
450
- When I run `msync update --noop`
451
- Then the exit status should be 0
452
- And the output should match:
435
+ When I successfully run `msync update --noop`
436
+ Then the output should match:
453
437
  """
454
438
  Files added:
455
439
  spec/spec_helper.rb
@@ -459,9 +443,8 @@ Feature: update
459
443
  Scenario: When running update without changes
460
444
  Given a basic setup with a puppet module "puppet-test" from "fakenamespace"
461
445
  And a directory named "moduleroot"
462
- When I run `msync update --message "Running without changes"`
463
- Then the exit status should be 0
464
- And the stdout should contain "There were no changes in 'modules/fakenamespace/puppet-test'. Not committing."
446
+ When I successfully run `msync update --verbose --message "Running without changes"`
447
+ Then the stdout should contain "There were no changes in 'modules/fakenamespace/puppet-test'. Not committing."
465
448
  And the puppet module "puppet-test" from "fakenamespace" should have no commits made by "Aruba"
466
449
 
467
450
  Scenario: When specifying configurations in managed_modules.yml
@@ -483,9 +466,8 @@ Feature: update
483
466
  """
484
467
  <%= @configs['name'] %>
485
468
  """
486
- When I run `msync update --noop`
487
- Then the exit status should be 0
488
- And the output should match:
469
+ When I successfully run `msync update --noop`
470
+ Then the output should match:
489
471
  """
490
472
  Files added:
491
473
  test
@@ -521,9 +503,8 @@ Feature: update
521
503
  """
522
504
  <%= @configs['name'] %>
523
505
  """
524
- When I run `msync update --noop -f puppet-test`
525
- Then the exit status should be 0
526
- And the output should match:
506
+ When I successfully run `msync update --noop -f puppet-test`
507
+ Then the output should match:
527
508
  """
528
509
  Files added:
529
510
  test
@@ -560,9 +541,8 @@ Feature: update
560
541
  """
561
542
  <%= @configs['name'] %>
562
543
  """
563
- When I run `msync update --noop -x puppet-blacksmith`
564
- Then the exit status should be 0
565
- And the output should match:
544
+ When I successfully run `msync update --noop -x puppet-blacksmith`
545
+ Then the output should match:
566
546
  """
567
547
  Files added:
568
548
  test
@@ -604,9 +584,8 @@ Feature: update
604
584
  spec/spec_helper.rb:
605
585
  unmanaged: true
606
586
  """
607
- When I run `msync update --noop`
608
- Then the exit status should be 0
609
- And the output should match:
587
+ When I successfully run `msync update --noop`
588
+ Then the output should match:
610
589
  """
611
590
  Not managing 'spec/spec_helper.rb' in 'puppet-test'
612
591
  """
@@ -645,9 +624,8 @@ Feature: update
645
624
  """
646
625
  <%= @configs['name'] %>
647
626
  """
648
- When I run `msync update --noop`
649
- Then the exit status should be 0
650
- And the output should match:
627
+ When I successfully run `msync update --noop`
628
+ Then the output should match:
651
629
  """
652
630
  Files added:
653
631
  test
@@ -674,9 +652,8 @@ Feature: update
674
652
  """
675
653
  Hello world!
676
654
  """
677
- When I run `msync update --noop`
678
- Then the exit status should be 0
679
- And the output should match:
655
+ When I successfully run `msync update --noop`
656
+ Then the output should match:
680
657
  """
681
658
  Files changed:
682
659
  +diff --git a/README.md b/README.md
@@ -701,40 +678,16 @@ Feature: update
701
678
  """
702
679
  source '<%= @configs['gem_source'] %>'
703
680
  """
704
- When I run `msync update -m "Update Gemfile" -r test`
705
- Then the exit status should be 0
706
- And the puppet module "puppet-test" from "fakenamespace" should have only 1 commit made by "Aruba"
681
+ When I successfully run `msync update -m "Update Gemfile" -r test`
682
+ Then the puppet module "puppet-test" from "fakenamespace" should have only 1 commit made by "Aruba"
707
683
  And the puppet module "puppet-test" from "fakenamespace" should have 1 commit made by "Aruba" in branch "test"
708
684
  Given I remove the directory "modules"
709
- When I run `msync update -m "Update Gemfile" -r test`
710
- Then the exit status should be 0
685
+ When I successfully run `msync update -m "Update Gemfile" -r test`
711
686
  Then the output should not contain "error"
712
687
  Then the output should not contain "rejected"
713
688
  And the puppet module "puppet-test" from "fakenamespace" should have only 1 commit made by "Aruba"
714
689
  And the puppet module "puppet-test" from "fakenamespace" should have 1 commit made by "Aruba" in branch "test"
715
690
 
716
- Scenario: Creating a GitHub PR with an update
717
- Given a basic setup with a puppet module "puppet-test" from "fakenamespace"
718
- And a directory named "moduleroot"
719
- And I set the environment variables to:
720
- | variable | value |
721
- | GITHUB_TOKEN | foobar |
722
- When I run `msync update --noop --branch managed_update --pr`
723
- Then the output should contain "Would submit PR "
724
- And the exit status should be 0
725
- And the puppet module "puppet-test" from "fakenamespace" should have no commits made by "Aruba"
726
-
727
- Scenario: Creating a GitLab MR with an update
728
- Given a basic setup with a puppet module "puppet-test" from "fakenamespace"
729
- And a directory named "moduleroot"
730
- And I set the environment variables to:
731
- | variable | value |
732
- | GITLAB_TOKEN | foobar |
733
- When I run `msync update --noop --branch managed_update --pr`
734
- Then the output should contain "Would submit MR "
735
- And the exit status should be 0
736
- And the puppet module "puppet-test" from "fakenamespace" should have no commits made by "Aruba"
737
-
738
691
  Scenario: Repository with a default branch other than master
739
692
  Given a basic setup with a puppet module "puppet-test" from "fakenamespace"
740
693
  And the puppet module "puppet-test" from "fakenamespace" has the default branch named "develop"
@@ -749,9 +702,8 @@ Feature: update
749
702
  """
750
703
  source '<%= @configs['gem_source'] %>'
751
704
  """
752
- When I run `msync update -m "Update Gemfile"`
753
- Then the exit status should be 0
754
- And the output should contain "Using repository's default branch: develop"
705
+ When I successfully run `msync update --verbose -m "Update Gemfile"`
706
+ Then the output should contain "Using repository's default branch: develop"
755
707
  And the puppet module "puppet-test" from "fakenamespace" should have only 1 commit made by "Aruba"
756
708
  And the puppet module "puppet-test" from "fakenamespace" should have 1 commit made by "Aruba" in branch "develop"
757
709
 
@@ -768,12 +720,31 @@ Feature: update
768
720
  target: <%= @metadata[:target_file] %>
769
721
  workdir: <%= @metadata[:workdir] %>
770
722
  """
771
- When I run `msync update --noop`
772
- Then the exit status should be 0
773
- And the file named "modules/fakenamespace/puppet-test/test" should contain:
723
+ When I successfully run `msync update --noop`
724
+ Then the file named "modules/fakenamespace/puppet-test/test" should contain:
774
725
  """
775
726
  module: puppet-test
776
727
  target: modules/fakenamespace/puppet-test/test
777
728
  workdir: modules/fakenamespace/puppet-test
778
729
  """
779
730
  And the puppet module "puppet-test" from "fakenamespace" should have no commits made by "Aruba"
731
+
732
+ # This reproduces the issue: https://github.com/voxpupuli/modulesync/issues/81
733
+ Scenario: Resync repositories after upstream branch deletion
734
+ Given a basic setup with a puppet module "puppet-test" from "fakenamespace"
735
+ And a file named "config_defaults.yml" with:
736
+ """
737
+ ---
738
+ test:
739
+ name: aruba
740
+ """
741
+ And a directory named "moduleroot"
742
+ And a file named "moduleroot/test.erb" with:
743
+ """
744
+ <%= @configs['name'] %>
745
+ """
746
+ When I successfully run `msync update -m "No changes!" --branch delete-me`
747
+ Then the puppet module "puppet-test" from "fakenamespace" should have 1 commit made by "Aruba" in branch "delete-me"
748
+ When the branch "delete-me" of the puppet module "puppet-test" from "fakenamespace" is deleted
749
+ And I successfully run `msync update -m "No changes!" --branch delete-me`
750
+ Then the puppet module "puppet-test" from "fakenamespace" should have no commits made by "Aruba"
@@ -8,7 +8,19 @@ module ModuleSync
8
8
  # This class extends ::Thor class to
9
9
  # - exit with status code sets to `1` on Thor failure (e.g. missing required option)
10
10
  # - exit with status code sets to `1` when user calls `msync` (or a subcommand) without required arguments
11
+ # - show subcommands help using `msync subcommand --help`
11
12
  class Thor < ::Thor
13
+ def self.start(*args)
14
+ if (Thor::HELP_MAPPINGS & ARGV).any? && subcommands.none? { |command| command.start_with?(ARGV[0]) }
15
+ Thor::HELP_MAPPINGS.each do |cmd|
16
+ if (match = ARGV.delete(cmd))
17
+ ARGV.unshift match
18
+ end
19
+ end
20
+ end
21
+ super
22
+ end
23
+
12
24
  desc '_invalid_command_call', 'Invalid command', hide: true
13
25
  def _invalid_command_call
14
26
  self.class.new.help
@@ -7,31 +7,34 @@ require 'modulesync/util'
7
7
 
8
8
  module ModuleSync
9
9
  module CLI
10
+ def self.prepare_options(cli_options, **more_options)
11
+ options = CLI.defaults
12
+ options.merge! Util.symbolize_keys(cli_options)
13
+ options.merge! more_options
14
+
15
+ Util.symbolize_keys options
16
+ end
17
+
10
18
  def self.defaults
11
19
  @defaults ||= Util.symbolize_keys(Util.parse_config(Constants::MODULESYNC_CONF_FILE))
12
20
  end
13
21
 
14
22
  class Hook < Thor
15
- class_option :project_root,
16
- :aliases => '-c',
17
- :desc => 'Path used by git to clone modules into. Defaults to "modules"',
18
- :default => CLI.defaults[:project_root] || 'modules'
19
- class_option :hook_args,
20
- :aliases => '-a',
21
- :desc => 'Arguments to pass to msync in the git hook'
22
-
23
+ option :hook_args,
24
+ :aliases => '-a',
25
+ :desc => 'Arguments to pass to msync in the git hook'
26
+ option :branch,
27
+ :aliases => '-b',
28
+ :desc => 'Branch name to pass to msync in the git hook',
29
+ :default => CLI.defaults[:branch]
23
30
  desc 'activate', 'Activate the git hook.'
24
31
  def activate
25
- config = { :command => 'hook' }.merge(options)
26
- config[:hook] = 'activate'
27
- ModuleSync.hook(config)
32
+ ModuleSync.hook CLI.prepare_options(options, hook: 'activate')
28
33
  end
29
34
 
30
35
  desc 'deactivate', 'Deactivate the git hook.'
31
36
  def deactivate
32
- config = { :command => 'hook' }.merge(options)
33
- config[:hook] = 'deactivate'
34
- ModuleSync.hook(config)
37
+ ModuleSync.hook CLI.prepare_options(options, hook: 'deactivate')
35
38
  end
36
39
  end
37
40
 
@@ -39,7 +42,7 @@ module ModuleSync
39
42
  class_option :project_root,
40
43
  :aliases => '-c',
41
44
  :desc => 'Path used by git to clone modules into.',
42
- :default => CLI.defaults[:project_root] || 'modules'
45
+ :default => CLI.defaults[:project_root]
43
46
  class_option :git_base,
44
47
  :desc => 'Specify the base part of a git URL to pull from',
45
48
  :default => CLI.defaults[:git_base] || 'git@github.com:'
@@ -53,11 +56,11 @@ module ModuleSync
53
56
  class_option :negative_filter,
54
57
  :aliases => '-x',
55
58
  :desc => 'A regular expression to skip repositories.'
56
- class_option :branch,
57
- :aliases => '-b',
58
- :desc => 'Branch name to make the changes in.' \
59
- ' Defaults to the default branch of the upstream repository, but falls back to "master".',
60
- :default => CLI.defaults[:branch]
59
+ class_option :verbose,
60
+ :aliases => '-v',
61
+ :desc => 'Verbose mode',
62
+ :type => :boolean,
63
+ :default => false
61
64
 
62
65
  desc 'update', 'Update the modules in managed_modules.yml'
63
66
  option :message,
@@ -67,7 +70,7 @@ module ModuleSync
67
70
  option :configs,
68
71
  :aliases => '-c',
69
72
  :desc => 'The local directory or remote repository to define the list of managed modules,' \
70
- ' the file templates, and the default values for template variables.'
73
+ ' the file templates, and the default values for template variables.'
71
74
  option :managed_modules_conf,
72
75
  :desc => 'The file name to define the list of managed modules'
73
76
  option :remote_branch,
@@ -104,7 +107,7 @@ module ModuleSync
104
107
  :default => CLI.defaults[:pr_labels] || []
105
108
  option :pr_target_branch,
106
109
  :desc => 'Target branch for the pull/merge request',
107
- :default => CLI.defaults[:pr_target_branch] || 'master'
110
+ :default => CLI.defaults[:pr_target_branch]
108
111
  option :offline,
109
112
  :type => :boolean,
110
113
  :desc => 'Do not run any Git commands. Allows the user to manage Git outside of ModuleSync.',
@@ -130,17 +133,108 @@ module ModuleSync
130
133
  :type => :boolean,
131
134
  :aliases => '-F',
132
135
  :desc => 'Produce a failure exit code when there are warnings' \
133
- ' (only has effect when --skip_broken is enabled)',
136
+ ' (only has effect when --skip_broken is enabled)',
134
137
  :default => false
135
-
138
+ option :branch,
139
+ :aliases => '-b',
140
+ :desc => 'Branch name to make the changes in.' \
141
+ ' Defaults to the default branch of the upstream repository, but falls back to "master".',
142
+ :default => CLI.defaults[:branch]
136
143
  def update
137
- config = { :command => 'update' }.merge(options)
138
- config = Util.symbolize_keys(config)
144
+ config = CLI.prepare_options(options)
139
145
  raise Thor::Error, 'No value provided for required option "--message"' unless config[:noop] \
140
146
  || config[:message] \
141
147
  || config[:offline]
142
- config[:git_opts] = { 'amend' => config[:amend], 'force' => config[:force] }
143
- ModuleSync.update(config)
148
+
149
+ ModuleSync.update config
150
+ end
151
+
152
+ desc 'execute [OPTIONS] -- COMMAND..', 'Execute the command in each managed modules'
153
+ long_desc <<~DESC
154
+ Execute the command in each managed modules.
155
+
156
+ COMMAND can be an absolute or a relative path.
157
+
158
+ To ease running local commands, a relative path is expanded with the current user directory but only if the target file exists.
159
+
160
+ Example: `msync exec custom-scripts/true` will run "$PWD/custom-scripts/true" in each repository.
161
+
162
+ As side effect, you can shadow system binary if a local file is present:
163
+ \x5 `msync exec true` will run "$PWD/true", not `/bin/true` if "$PWD/true" exists.
164
+ DESC
165
+
166
+ option :configs,
167
+ :aliases => '-c',
168
+ :desc => 'The local directory or remote repository to define the list of managed modules,' \
169
+ ' the file templates, and the default values for template variables.'
170
+ option :managed_modules_conf,
171
+ :desc => 'The file name to define the list of managed modules'
172
+ option :branch,
173
+ :aliases => '-b',
174
+ :desc => 'Branch name to make the changes in.',
175
+ :default => CLI.defaults[:branch]
176
+ option :fail_fast,
177
+ :type => :boolean,
178
+ :desc => 'Abort the run after a command execution failure',
179
+ :default => CLI.defaults[:fail_fast].nil? ? true : CLI.defaults[:fail_fast]
180
+ def execute(*command_args)
181
+ raise Thor::Error, 'COMMAND is a required argument' if command_args.empty?
182
+
183
+ ModuleSync.execute CLI.prepare_options(options, command_args: command_args)
184
+ end
185
+
186
+ desc 'reset', 'Reset local repositories to a well-known state'
187
+ long_desc <<~DESC
188
+ Reset local repository to a well-known state:
189
+ \x5 * Switch local repositories to specified branch
190
+ \x5 * Fetch and prune repositories unless running with `--offline` option
191
+ \x5 * Hard-reset any changes to specified source branch, technically any git refs, e.g. `main`, `origin/wip`
192
+ \x5 * Clean all extra local files
193
+
194
+ Note: If a repository is not already cloned, it will operate the following to reach to well-known state:
195
+ \x5 * Clone the repository
196
+ \x5 * Switch to specified branch
197
+ DESC
198
+ option :configs,
199
+ :aliases => '-c',
200
+ :desc => 'The local directory or remote repository to define the list of managed modules,' \
201
+ ' the file templates, and the default values for template variables.'
202
+ option :managed_modules_conf,
203
+ :desc => 'The file name to define the list of managed modules'
204
+ option :branch,
205
+ :aliases => '-b',
206
+ :desc => 'Branch name to make the changes in.',
207
+ :default => CLI.defaults[:branch]
208
+ option :offline,
209
+ :type => :boolean,
210
+ :desc => 'Only proceed local operations',
211
+ :default => false
212
+ option :source_branch,
213
+ :desc => 'Branch to reset from (e.g. origin/wip)'
214
+ def reset
215
+ ModuleSync.reset CLI.prepare_options(options)
216
+ end
217
+
218
+ desc 'push', 'Push all available commits from branch to remote'
219
+ option :configs,
220
+ :aliases => '-c',
221
+ :desc => 'The local directory or remote repository to define the list of managed modules,' \
222
+ ' the file templates, and the default values for template variables.'
223
+ option :managed_modules_conf,
224
+ :desc => 'The file name to define the list of managed modules'
225
+ option :branch,
226
+ :aliases => '-b',
227
+ :desc => 'Branch name to push',
228
+ :default => CLI.defaults[:branch]
229
+ option :remote_branch,
230
+ :desc => 'Remote branch to push to (e.g. maintenance)'
231
+ def push
232
+ ModuleSync.push CLI.prepare_options(options)
233
+ end
234
+
235
+ desc 'clone', 'Clone repositories that need to'
236
+ def clone
237
+ ModuleSync.clone CLI.prepare_options(options)
144
238
  end
145
239
 
146
240
  desc 'hook', 'Activate or deactivate a git hook.'