braid 1.1.5 → 1.1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/exe/braid +11 -0
  3. data/lib/braid/check_gem.rb +65 -0
  4. data/lib/braid/command.rb +18 -0
  5. data/lib/braid/commands/add.rb +41 -1
  6. data/lib/braid/commands/diff.rb +2 -1
  7. data/lib/braid/commands/push.rb +1 -0
  8. data/lib/braid/commands/remove.rb +1 -0
  9. data/lib/braid/commands/setup.rb +1 -0
  10. data/lib/braid/commands/status.rb +1 -0
  11. data/lib/braid/commands/update.rb +1 -0
  12. data/lib/braid/commands/upgrade_config.rb +1 -0
  13. data/lib/braid/config.rb +28 -4
  14. data/{bin/braid → lib/braid/main.rb} +16 -17
  15. data/lib/braid/mirror.rb +111 -24
  16. data/lib/braid/operations.rb +20 -18
  17. data/lib/braid/operations_lite.rb +19 -1
  18. data/lib/braid/sorbet/fake_runtime.rb +75 -0
  19. data/lib/braid/sorbet/setup.rb +18 -0
  20. data/lib/braid/version.rb +4 -1
  21. data/lib/braid.rb +23 -3
  22. metadata +26 -75
  23. data/.gitignore +0 -16
  24. data/.travis.yml +0 -15
  25. data/CONTRIBUTING.md +0 -24
  26. data/Gemfile +0 -3
  27. data/README.md +0 -234
  28. data/Rakefile +0 -12
  29. data/_config.yml +0 -1
  30. data/braid.gemspec +0 -35
  31. data/braids-json.schema.json +0 -91
  32. data/config_versions.md +0 -58
  33. data/spec/config_spec.rb +0 -59
  34. data/spec/fixtures/shiny/README +0 -3
  35. data/spec/fixtures/shiny/other-skit/layout.liquid +0 -219
  36. data/spec/fixtures/shiny/skit-layout.liquid.test +0 -2
  37. data/spec/fixtures/shiny/skit1.test +0 -2
  38. data/spec/fixtures/shiny-conf-1.0.9-lock/.braids.json +0 -10
  39. data/spec/fixtures/shiny-conf-1.0.9-lock/expected.braids.json +0 -9
  40. data/spec/fixtures/shiny-conf-1.0.9-lock/skit1/layouts/layout.liquid +0 -219
  41. data/spec/fixtures/shiny-conf-1.0.9-lock/skit1/preview.png +0 -0
  42. data/spec/fixtures/shiny-conf-breaking-changes/.braids +0 -14
  43. data/spec/fixtures/shiny-conf-breaking-changes/Spoon-Knife/README.md +0 -9
  44. data/spec/fixtures/shiny-conf-breaking-changes/Spoon-Knife/index.html +0 -20
  45. data/spec/fixtures/shiny-conf-breaking-changes/Spoon-Knife/styles.css +0 -17
  46. data/spec/fixtures/shiny-conf-breaking-changes/expected.braids.json +0 -10
  47. data/spec/fixtures/shiny-conf-breaking-changes/skit1/layouts/layout.liquid +0 -219
  48. data/spec/fixtures/shiny-conf-breaking-changes/skit1/preview.png +0 -0
  49. data/spec/fixtures/shiny-conf-future/.braids.json +0 -10
  50. data/spec/fixtures/shiny-conf-future/skit1/layouts/layout.liquid +0 -219
  51. data/spec/fixtures/shiny-conf-future/skit1/preview.png +0 -0
  52. data/spec/fixtures/shiny-conf-json-old-name/.braids +0 -9
  53. data/spec/fixtures/shiny-conf-json-old-name/expected.braids.json +0 -10
  54. data/spec/fixtures/shiny-conf-json-old-name/skit1/layouts/layout.liquid +0 -219
  55. data/spec/fixtures/shiny-conf-json-old-name/skit1/preview.png +0 -0
  56. data/spec/fixtures/shiny-conf-yaml/.braids +0 -8
  57. data/spec/fixtures/shiny-conf-yaml/expected.braids.json +0 -10
  58. data/spec/fixtures/shiny-conf-yaml/skit1/layouts/layout.liquid +0 -219
  59. data/spec/fixtures/shiny-conf-yaml/skit1/preview.png +0 -0
  60. data/spec/fixtures/shiny_skit1.2_merged/layouts/layout.liquid +0 -223
  61. data/spec/fixtures/shiny_skit1.2_merged/preview.png +0 -0
  62. data/spec/fixtures/shiny_skit1_conflicting/layouts/layout.liquid +0 -221
  63. data/spec/fixtures/shiny_skit1_conflicting/preview.png +0 -0
  64. data/spec/fixtures/shiny_skit1_mergeable/layouts/layout.liquid +0 -221
  65. data/spec/fixtures/shiny_skit1_mergeable/preview.png +0 -0
  66. data/spec/fixtures/skit1/layouts/layout.liquid +0 -219
  67. data/spec/fixtures/skit1/preview.png +0 -0
  68. data/spec/fixtures/skit1.1/layouts/layout.liquid +0 -219
  69. data/spec/fixtures/skit1.1_with_filter/.gitattributes +0 -1
  70. data/spec/fixtures/skit1.1_with_filter/layouts/layout.liquid +0 -219
  71. data/spec/fixtures/skit1.1_with_filter/preview.png +0 -0
  72. data/spec/fixtures/skit1.1x/layouts/layout.liquid +0 -219
  73. data/spec/fixtures/skit1.2/layouts/layout.liquid +0 -221
  74. data/spec/fixtures/skit1.3/layouts/README.md +0 -1
  75. data/spec/fixtures/skit1.3/layouts/layout.liquid +0 -221
  76. data/spec/fixtures/skit1_with_filter/.gitattributes +0 -1
  77. data/spec/fixtures/skit1_with_filter/layouts/layout.liquid +0 -219
  78. data/spec/fixtures/skit1_with_filter/preview.png +0 -0
  79. data/spec/integration/adding_spec.rb +0 -230
  80. data/spec/integration/config_versioning_spec.rb +0 -222
  81. data/spec/integration/diff_spec.rb +0 -597
  82. data/spec/integration/integration_helper.rb +0 -129
  83. data/spec/integration/push_spec.rb +0 -399
  84. data/spec/integration/remove_spec.rb +0 -81
  85. data/spec/integration/status_spec.rb +0 -165
  86. data/spec/integration/updating_spec.rb +0 -487
  87. data/spec/mirror_spec.rb +0 -119
  88. data/spec/operations_spec.rb +0 -66
  89. data/spec/test_helper.rb +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 820284531c81fc3d920345ddca21afa6cb6f49489aa088c2eb6b3233923069e9
4
- data.tar.gz: ee5eb584e64c6426e77905bc1d8ac7d1622620665749546bf142c424dacf027e
3
+ metadata.gz: 6efac3d863ec38976f90032c012ebe9acca8911a9316608d7dfe704cc0d8925b
4
+ data.tar.gz: 5c5c8870bbf0702767234ee5b467324c7c25914ed3de06ac67ef903f87ca4ee7
5
5
  SHA512:
6
- metadata.gz: 71b869dfd6f57e8d64238b7d09761415d807572cd2d2b71e8f0d0a3fb48d759af2269f0ba13a946142408981b8edb3d84c8f00cca51ed1542fcf0a785e5c38f4
7
- data.tar.gz: fe09b15e8062fab7aa8389dddc9bae1c4f684e583bed5ac3105970fe7ad6d809b5af9583cf6c970563a8471317a78cfac505522f3402403b7d547aba087a613c
6
+ metadata.gz: dcb55a781668a47cdae99c5e013844b3234c7edcaeec21d71f64174dfc6ae3339acf89083b3256244fd430bdf035285d44cd9244d2abd6808b97f1c3c0be41cf
7
+ data.tar.gz: b8143594481cb94c3ca8c099e02c4c231be84e4a742b5e2047a7e79c82ea0e47c1b8e1ece68719130870aa613f5bca20182eb85e62f1d45a8bca210c0e163f80
data/exe/braid ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # I haven't found a clean way to get Sorbet to check this file since the name
4
+ # doesn't end in `.rb`. (If I add `--file bin/braid` to `sorbet/config`, then
5
+ # the Sorbet language server doesn't support using Watchman.) So move all the
6
+ # interesting code to `lib/braid/main.rb` and leave this as a launcher that
7
+ # doesn't have any code worth type checking. ~ Matt 2022-04-02
8
+
9
+ require_relative '../lib/braid/check_gem'
10
+
11
+ require 'braid/main'
@@ -0,0 +1,65 @@
1
+ # Since this file can't safely depend on the Sorbet runtime, it isn't prudent to
2
+ # try to commit to `typed: true` even if the file currently passes type checking
3
+ # without needing any references to `T`. Like `exe/braid`, this file doesn't
4
+ # have much code worth type checking.
5
+ #
6
+ # typed: false
7
+
8
+ # Braid has several entry points that run code from Ruby gems (either Braid
9
+ # itself or dependencies such as Sorbet) and expect to get the correct versions
10
+ # (either the same copy of Braid or versions of dependencies consistent with the
11
+ # gemspec or Gemfile, as applicable). This currently applies to the following
12
+ # entry points:
13
+ #
14
+ # - The Braid CLI launcher: `exe/braid`
15
+ # - The Braid test suite under `spec`
16
+ # - The Rakefile: Has a target to run the Sorbet type checker and wants the
17
+ # correct version for the current version of Braid.
18
+ #
19
+ # If these entry points are invoked without first activating the correct gems,
20
+ # then other globally installed versions might be used by default, leading to
21
+ # unintended behavior. So we have each of these entry points check that a Braid
22
+ # gem is active in the current Ruby interpreter _and_ the entry point is part of
23
+ # that same Braid gem. If so, we can assume that the correct versions of
24
+ # dependencies are active as well.
25
+ #
26
+ # To implement the check, the entry point file loads its corresponding copy of
27
+ # check_gem.rb via `require_relative`, and that copy of check_gem.rb checks that
28
+ # it is part of the active Braid gem. Note that loading check_gem.rb via
29
+ # `require 'lib/braid/check_gem'` would defeat the purpose, since it would
30
+ # activate whatever Braid gem is visible and then check that that gem's copy of
31
+ # check_gem.rb is part of the active Braid gem (which it would always be), not
32
+ # whether the _caller_ is part of the active Braid gem.
33
+ #
34
+ # Common means of activating the correct gems before invoking an entry point
35
+ # include:
36
+ #
37
+ # - Bundler: Used when developing Braid itself and possibly by some projects
38
+ # that use Braid. It modifies the environment so that every Ruby subprocess
39
+ # activates the gems from the Gemfile.lock.
40
+ # - A wrapper for `exe/braid` generated by `gem install --wrappers`.
41
+ #
42
+ # Note that we don't have every `.rb` file that is part of Braid load
43
+ # check_gem.rb: that would be too invasive and only helps in the case where a
44
+ # user manually added Braid's `lib` dir to the load path, which is a mistake
45
+ # that a reasonable user is much less likely to make than just running an entry
46
+ # point without the proper setup.
47
+ #
48
+ # TODO: Is there a more standard way to do this check? One would think it would
49
+ # be potentially applicable to any Ruby project, though maybe most don't care as
50
+ # much as we do about catching the problem up front.
51
+
52
+ braid_spec = Gem.loaded_specs['braid']
53
+ if braid_spec.nil? || __FILE__ != braid_spec.gem_dir + '/lib/braid/check_gem.rb'
54
+ STDERR.puts <<-MSG
55
+ Error: The RubyGems environment is not set up correctly for Braid.
56
+ - If you're using a copy of Braid installed globally via 'gem install' or
57
+ similar, use the 'braid' wrapper script (which is typically installed at a
58
+ location like ~/.gem/ruby/bin/braid depending on your environment) instead of
59
+ running 'exe/braid' directly.
60
+ - If you're using a copy of Braid managed by Bundler (including when developing
61
+ Braid itself), prepend 'bundle exec' to your command or use a binstub
62
+ generated by 'bundle binstubs'.
63
+ MSG
64
+ exit(1)
65
+ end
data/lib/braid/command.rb CHANGED
@@ -1,5 +1,8 @@
1
+ # typed: true
1
2
  module Braid
2
3
  class Command
4
+ extend T::Sig
5
+
3
6
  class InvalidRevision < BraidError
4
7
  end
5
8
 
@@ -14,6 +17,11 @@ module Braid
14
17
  klass.new.run(*args)
15
18
 
16
19
  rescue BraidError => error
20
+ handle_error(error)
21
+ end
22
+
23
+ sig {params(error: BraidError).returns(T.noreturn)}
24
+ def self.handle_error(error)
17
25
  case error
18
26
  when Operations::ShellExecutionError
19
27
  msg "Shell error: #{error.message}"
@@ -23,10 +31,12 @@ module Braid
23
31
  exit(1)
24
32
  end
25
33
 
34
+ sig {params(str: String).void}
26
35
  def self.msg(str)
27
36
  puts "Braid: #{str}"
28
37
  end
29
38
 
39
+ sig {params(str: String).void}
30
40
  def msg(str)
31
41
  self.class.msg(str)
32
42
  end
@@ -35,16 +45,19 @@ module Braid
35
45
  @config ||= Config.new({'mode' => config_mode})
36
46
  end
37
47
 
48
+ sig {returns(T::Boolean)}
38
49
  def verbose?
39
50
  Braid.verbose
40
51
  end
41
52
 
53
+ sig {returns(T::Boolean)}
42
54
  def force?
43
55
  Braid.force
44
56
  end
45
57
 
46
58
  private
47
59
 
60
+ sig {returns(Config::ConfigMode)}
48
61
  def config_mode
49
62
  Config::MODE_MAY_WRITE
50
63
  end
@@ -63,14 +76,17 @@ module Braid
63
76
  git.remote_rm(mirror.remote) unless options['keep']
64
77
  end
65
78
 
79
+ sig {returns(T::Boolean)}
66
80
  def use_local_cache?
67
81
  Braid.use_local_cache
68
82
  end
69
83
 
84
+ sig {void}
70
85
  def self.verify_git_version!
71
86
  git.require_version!(REQUIRED_GIT_VERSION)
72
87
  end
73
88
 
89
+ sig {void}
74
90
  def self.check_working_dir!
75
91
  # If we aren't in a git repository at all, git.is_inside_worktree will
76
92
  # propagate a "fatal: Not a git repository" ShellException.
@@ -82,6 +98,7 @@ module Braid
82
98
  end
83
99
  end
84
100
 
101
+ sig {void}
85
102
  def bail_on_local_changes!
86
103
  git.ensure_clean!
87
104
  end
@@ -100,6 +117,7 @@ module Braid
100
117
  end
101
118
  end
102
119
 
120
+ sig {void}
103
121
  def add_config_file
104
122
  git.rm(OLD_CONFIG_FILE) if File.exist?(OLD_CONFIG_FILE)
105
123
  git.add(CONFIG_FILE)
@@ -1,15 +1,55 @@
1
+ # typed: true
1
2
  module Braid
2
3
  module Commands
3
4
  class Add < Command
5
+ # Returns the default branch name of the repository at the given URL, or
6
+ # nil if it couldn't be determined.
7
+ #
8
+ # We won't be able to determine a default branch in certain cases that we
9
+ # expect to be unusual in the context of Braid, such as if the HEAD is
10
+ # detached or points to a ref outside of `refs/heads`. (Presumably, the
11
+ # same thing happens if the server is too old to report symrefs to us.)
12
+ # In those cases, a plausible alternative behavior would be to just lock
13
+ # the mirror to the remote HEAD revision, but that's probably not what the
14
+ # user wants. It's much more likely that something is wrong and Braid
15
+ # should report an error.
16
+ def get_default_branch_name(url)
17
+ head_targets = []
18
+ # The `HEAD` parameter here doesn't appear to do an exact match (it
19
+ # appears to match any ref with `HEAD` as the last path component, such
20
+ # as `refs/remotes/origin/HEAD` in the unusual case where the repository
21
+ # contains its own remote-tracking branches), but it reduces the data we
22
+ # have to scan a bit.
23
+ git.ls_remote('--symref', url, 'HEAD').split("\n").each do |line|
24
+ m = /^ref: (.*)\tHEAD$/.match(line)
25
+ head_targets.push(m[1]) if m
26
+ end
27
+ return nil unless head_targets.size == 1
28
+ m = /^refs\/heads\/(.*)$/.match(head_targets[0])
29
+ return nil unless m
30
+ m[1]
31
+ end
32
+
4
33
  def run(url, options = {})
5
34
  with_reset_on_error do
35
+ if options['branch'].nil? && options['tag'].nil? && options['revision'].nil?
36
+ default_branch = get_default_branch_name(url)
37
+ if default_branch.nil?
38
+ raise BraidError, <<-MSG
39
+ Failed to detect the default branch of the remote repository. Please specify
40
+ the branch you want to use via the --branch option.
41
+ MSG
42
+ end
43
+ options['branch'] = default_branch
44
+ end
45
+
6
46
  mirror = config.add_from_options(url, options)
7
47
  add_config_file
8
48
 
9
49
  mirror.branch = nil if options['revision']
10
50
  raise BraidError, 'Can not add mirror specifying both a revision and a tag' if options['revision'] && mirror.tag
11
51
 
12
- branch_message = (mirror.branch.nil? || mirror.branch == 'master') ? '' : " branch '#{mirror.branch}'"
52
+ branch_message = mirror.branch.nil? ? '' : " branch '#{mirror.branch}'"
13
53
  tag_message = mirror.tag.nil? ? '' : " tag '#{mirror.tag}'"
14
54
  revision_message = options['revision'] ? " at #{display_revision(mirror, options['revision'])}" : ''
15
55
  msg "Adding mirror of '#{mirror.url}'#{branch_message}#{tag_message}#{revision_message}."
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  module Braid
2
3
  module Commands
3
4
  class Diff < Command
@@ -35,7 +36,7 @@ module Braid
35
36
 
36
37
  # XXX: Warn if the user specifies file paths that are outside the
37
38
  # mirror? Currently, they just won't match anything.
38
- git.diff_to_stdout(*mirror.diff_args(*options['git_diff_args']))
39
+ git.diff_to_stdout(*mirror.diff_args(options['git_diff_args']))
39
40
 
40
41
  clear_remote(mirror, options)
41
42
  end
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  require 'fileutils'
2
3
  require 'tmpdir'
3
4
 
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  module Braid
2
3
  module Commands
3
4
  class Remove < Command
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  module Braid
2
3
  module Commands
3
4
  class Setup < Command
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  module Braid
2
3
  module Commands
3
4
  class Status < Command
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  module Braid
2
3
  module Commands
3
4
  class Update < Command
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  module Braid
2
3
  module Commands
3
4
  class UpgradeConfig < Command
data/lib/braid/config.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  require 'yaml'
2
3
  require 'json'
3
4
  require 'yaml/store'
@@ -48,6 +49,10 @@ require 'yaml/store'
48
49
 
49
50
  module Braid
50
51
  class Config
52
+ extend T::Sig
53
+
54
+ # TODO (typing): Migrate to T::Enum?
55
+ ConfigMode = T.type_alias { Integer }
51
56
 
52
57
  MODE_UPGRADE = 1
53
58
  MODE_READ_ONLY = 2
@@ -56,11 +61,13 @@ module Braid
56
61
  CURRENT_CONFIG_VERSION = 1
57
62
 
58
63
  class PathAlreadyInUse < BraidError
64
+ sig {returns(String)}
59
65
  def message
60
66
  "path already in use: #{super}"
61
67
  end
62
68
  end
63
69
  class MirrorDoesNotExist < BraidError
70
+ sig {returns(String)}
64
71
  def message
65
72
  "mirror does not exist: #{super}"
66
73
  end
@@ -70,9 +77,15 @@ module Braid
70
77
  end
71
78
 
72
79
  # For upgrade-config command only. XXX: Ideally would be immutable.
73
- attr_reader :config_version, :config_existed, :breaking_change_descs
80
+ sig {returns(Integer)}
81
+ attr_reader :config_version
82
+ sig {returns(T::Boolean)}
83
+ attr_reader :config_existed
84
+ sig {returns(T::Array[String])}
85
+ attr_reader :breaking_change_descs
74
86
 
75
87
  # options: config_file, old_config_files, mode
88
+ sig {params(options: T.untyped).void}
76
89
  def initialize(options = {})
77
90
  @config_file = options['config_file'] || CONFIG_FILE
78
91
  old_config_files = options['old_config_files'] || [OLD_CONFIG_FILE]
@@ -150,6 +163,7 @@ MSG
150
163
 
151
164
  end
152
165
 
166
+ sig {params(url: String, options: T.untyped).returns(Mirror)}
153
167
  def add_from_options(url, options)
154
168
  mirror = Mirror.new_from_options(url, options)
155
169
 
@@ -157,33 +171,39 @@ MSG
157
171
  mirror
158
172
  end
159
173
 
174
+ sig {returns(T::Array[Mirror])}
160
175
  def mirrors
161
176
  @db.keys
162
177
  end
163
178
 
179
+ sig {params(path: String).returns(T.nilable(Mirror))}
164
180
  def get(path)
165
181
  key = path.to_s.sub(/\/$/, '')
166
182
  attributes = @db[key]
167
183
  attributes ? Mirror.new(path, attributes) : nil
168
184
  end
169
185
 
186
+ sig {params(path: String).returns(Mirror)}
170
187
  def get!(path)
171
188
  mirror = get(path)
172
189
  raise MirrorDoesNotExist, path unless mirror
173
190
  mirror
174
191
  end
175
192
 
193
+ sig {params(mirror: Mirror).void}
176
194
  def add(mirror)
177
195
  raise PathAlreadyInUse, mirror.path if get(mirror.path)
178
196
  write_mirror(mirror)
179
197
  write_db
180
198
  end
181
199
 
200
+ sig {params(mirror: Mirror).void}
182
201
  def remove(mirror)
183
202
  @db.delete(mirror.path)
184
203
  write_db
185
204
  end
186
205
 
206
+ sig {params(mirror: Mirror).void}
187
207
  def update(mirror)
188
208
  raise MirrorDoesNotExist, mirror.path unless get(mirror.path)
189
209
  write_mirror(mirror)
@@ -191,6 +211,7 @@ MSG
191
211
  end
192
212
 
193
213
  # Public for upgrade-config command only.
214
+ sig {void}
194
215
  def write_db
195
216
  new_db = {}
196
217
  @db.keys.sort.each do |key|
@@ -211,11 +232,12 @@ MSG
211
232
 
212
233
  private
213
234
 
235
+ sig {params(config_file: String, old_config_files: T::Array[String]).returns(T.untyped)}
214
236
  def load_config(config_file, old_config_files)
215
237
  (old_config_files + [config_file]).each do |file|
216
238
  next unless File.exist?(file)
217
239
  begin
218
- store = YAML::Store.new(file)
240
+ store = T.let(YAML::Store, T.untyped).new(file)
219
241
  data = {}
220
242
  store.transaction(true) do
221
243
  store.roots.each do |path|
@@ -228,15 +250,17 @@ MSG
228
250
  return data if data
229
251
  end
230
252
  end
231
- return nil
253
+ nil
232
254
  end
233
255
 
256
+ sig {params(mirror: Mirror).void}
234
257
  def write_mirror(mirror)
235
258
  @db[mirror.path] = clean_attributes(mirror.attributes)
236
259
  end
237
260
 
261
+ sig {params(hash: T::Hash[String, T.untyped]).returns(T::Hash[String, T.untyped])}
238
262
  def clean_attributes(hash)
239
- hash.reject { |k, v| v.nil? }
263
+ hash.reject { |_, v| v.nil? }
240
264
  end
241
265
  end
242
266
  end
@@ -1,28 +1,24 @@
1
- #!/usr/bin/env ruby
1
+ # typed: true
2
2
 
3
- # Duplicated from Braid::Command.run. :(
4
- def die(msg)
5
- puts "Braid: Error: #{msg}"
6
- exit(1)
7
- end
8
-
9
- # If we assume Ruby >= 2.0, we can use __dir__.
10
- libdir = File.expand_path(File.dirname(File.realpath(__FILE__)) + '/../lib')
11
- unless File.exists?(libdir)
12
- # Don't silently fall back to a different globally installed copy of Braid!
13
- die "Cannot find Braid's 'lib' directory."
14
- end
15
- $LOAD_PATH.unshift(libdir)
16
3
  require 'braid'
17
4
 
18
5
  require 'rubygems'
19
6
  require 'main'
20
7
 
8
+ # This is needed for `T` below to resolve to `Braid::T` when using the fake
9
+ # Sorbet runtime. TODO: Indent the contents and accept the large diff?
10
+ module Braid
11
+
21
12
  Home = File.expand_path(ENV['HOME'] || '~')
22
13
 
23
14
  # mostly blantantly stolen from ara's punch script
24
15
  # main kicks ass!
25
- Main {
16
+ T.unsafe(Main).run {
17
+ # `Main` is somewhat mind-bending and I'm unsure what the type of `self`
18
+ # actually is here, but whatever it is, we don't have a type declaration for
19
+ # it.
20
+ T.bind(self, T.untyped)
21
+
26
22
  description <<-TXT
27
23
  braid is a simple tool to help track git repositories inside a git repository.
28
24
 
@@ -35,7 +31,8 @@ Main {
35
31
  # The "main" library doesn't provide a way to do this??
36
32
  def check_no_extra_args!
37
33
  if @argv.length > 0
38
- die 'Extra argument(s) passed to command.'
34
+ Braid::Command.handle_error(
35
+ Braid::BraidError.new('Extra argument(s) passed to command.'))
39
36
  end
40
37
  end
41
38
 
@@ -138,7 +135,7 @@ Main {
138
135
 
139
136
  mixin :optional_local_path, :option_verbose, :option_keep_remote
140
137
 
141
- synopsis (Main::Usage.default_synopsis(self) + ' [-- git_diff_arg*]')
138
+ synopsis(T.unsafe(Main::Usage).default_synopsis(self) + ' [-- git_diff_arg*]')
142
139
 
143
140
  run {
144
141
  if @argv.length > 0 && @argv[0] == '--'
@@ -333,3 +330,5 @@ Main {
333
330
 
334
331
  run { help! }
335
332
  }
333
+
334
+ end