ruby_git 0.3.1 → 0.3.4

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: b12470df80fc020031e73898e6332def5b5d6e7c419acb3036a58585263269b7
4
- data.tar.gz: d1138d2381fc7272397357105b8e884a78bed2396289608df6dc746896018b4b
3
+ metadata.gz: 9c3507b566d30abc32d770188184bf932f3af97985f579df84dfa24b3e6e9a96
4
+ data.tar.gz: 8fecb84e47a289736ecf79579a2de496b0520734a4a3d6199c5838e0543ba1d1
5
5
  SHA512:
6
- metadata.gz: f1cbdfcdea413421d06bf15ad2c205866dff32a1b92ffea0b260dbecf31fe62313fb6b355ae81fff9cb0f07fab26af622c90eeb28c1b1e28c63c27a02223e499
7
- data.tar.gz: e51b5c257998f8a2c9cad6927bfd1b32d4f397c793b82edd6017a00b4581b9b6f6f00623f05ec9d2052b42a72c62fabc94268bb4caa6b1d6b408a3b2d5041f46
6
+ metadata.gz: b8c39128ee93c9a24cb6b07f7b99284f2373647c02d276aa76e9ccad9bfa3ce622ed12c7e0d0043bb3e4b4834069db626de9cc4885ec25fd89a8bac86b705bcc
7
+ data.tar.gz: bc37e79e11cead6979605727b5134fbbd528610977768bb7302c79cb7eebf7fa385ce1b07573d208f1ff7e4af29344a30e2ddf9e1a9c66a38d60330253b79271
@@ -1,9 +1,6 @@
1
1
  name: Continuous Integration
2
2
 
3
3
  on:
4
- push:
5
- branches: [main]
6
-
7
4
  pull_request:
8
5
  branches: [main]
9
6
 
@@ -26,6 +23,10 @@ jobs:
26
23
  build:
27
24
  name: Ruby ${{ matrix.ruby }} on ${{ matrix.operating-system }}
28
25
 
26
+ if: >-
27
+ github.event_name == 'workflow_dispatch' ||
28
+ (github.event_name == 'pull_request' && !startsWith(github.event.pull_request.head.ref, 'release-please--'))
29
+
29
30
  runs-on: ${{ matrix.operating-system }}
30
31
  continue-on-error: true
31
32
 
@@ -35,19 +36,9 @@ jobs:
35
36
  strategy:
36
37
  fail-fast: false
37
38
  matrix:
38
- ruby: ["3.1", "3.2", "3.3", "3.4"]
39
+ ruby: ["3.1", "3.4"]
39
40
  operating-system: [ubuntu-latest]
40
41
  fail_on_low_coverage: [true]
41
- include:
42
- - ruby: "3.1"
43
- operating-system: windows-latest
44
- fail_on_low_coverage: false
45
- - ruby: "jruby-9.4"
46
- operating-system: ubuntu-latest
47
- fail_on_low_coverage: false
48
- - ruby: "truffleruby-24"
49
- operating-system: ubuntu-latest
50
- fail_on_low_coverage: false
51
42
 
52
43
  steps:
53
44
  - name: Checkout
@@ -61,27 +52,3 @@ jobs:
61
52
 
62
53
  - name: Run rake
63
54
  run: bundle exec rake
64
-
65
- coverage:
66
- name: Report test coverage to CodeClimate
67
-
68
- needs: [build]
69
- runs-on: ubuntu-latest
70
-
71
- steps:
72
- - name: Checkout
73
- uses: actions/checkout@v4
74
-
75
- - name: Initialize Ruby
76
- uses: ruby/setup-ruby@v1
77
- with:
78
- ruby-version: 3.1
79
- bundler-cache: true
80
-
81
- - name: Report test coverage
82
- uses: paambaati/codeclimate-action@v9
83
- env:
84
- CC_TEST_REPORTER_ID: b86e77bc6980a43dc09314502fe13334e0f663770b840628ca0716e6dcdeeb5d
85
- with:
86
- coverageCommand: bundle exec rake spec
87
- coverageLocations: ${{github.workspace}}/coverage/lcov/*.lcov:lcov
@@ -9,6 +9,10 @@ jobs:
9
9
  commit-lint:
10
10
  name: Verify Conventional Commits
11
11
 
12
+ if: >-
13
+ github.event_name == 'workflow_dispatch' ||
14
+ (github.event_name == 'pull_request' && !startsWith(github.event.pull_request.head.ref, 'release-please--'))
15
+
12
16
  runs-on: ubuntu-latest
13
17
 
14
18
  steps:
@@ -1,9 +1,6 @@
1
1
  name: Experimental Ruby Builds
2
2
 
3
3
  on:
4
- push:
5
- branches: [main]
6
-
7
4
  workflow_dispatch:
8
5
 
9
6
  env:
@@ -34,19 +31,28 @@ jobs:
34
31
  matrix:
35
32
  fail_on_low_coverage: [true]
36
33
  include:
34
+ - ruby: "3.1"
35
+ operating-system: windows-latest
36
+ fail_on_low_coverage: false
37
37
  - ruby: head
38
38
  operating-system: ubuntu-latest
39
39
  - ruby: head
40
40
  operating-system: windows-latest
41
+ - ruby: "truffleruby-24"
42
+ operating-system: ubuntu-latest
43
+ fail_on_low_coverage: false
41
44
  - ruby: truffleruby-head
42
45
  operating-system: ubuntu-latest
43
46
  fail_on_low_coverage: false
44
- - ruby: jruby-head
47
+ - ruby: "jruby-9.4"
45
48
  operating-system: ubuntu-latest
46
49
  fail_on_low_coverage: false
47
50
  - ruby: "jruby-9.4"
48
51
  operating-system: windows-latest
49
52
  fail_on_low_coverage: false
53
+ - ruby: jruby-head
54
+ operating-system: ubuntu-latest
55
+ fail_on_low_coverage: false
50
56
  - ruby: jruby-head
51
57
  operating-system: windows-latest
52
58
  fail_on_low_coverage: false
@@ -0,0 +1,51 @@
1
+ ---
2
+ name: Release Gem
3
+ description: |
4
+ This workflow creates a new release on GitHub and publishes the gem to
5
+ RubyGems.org.
6
+
7
+ The workflow uses the `googleapis/release-please-action` to handle the
8
+ release creation process and the `rubygems/release-gem` action to publish
9
+ the gem.
10
+
11
+ on:
12
+ push:
13
+ branches: ["main"]
14
+
15
+ workflow_dispatch:
16
+
17
+ jobs:
18
+ release:
19
+ runs-on: ubuntu-latest
20
+
21
+ environment:
22
+ name: RubyGems
23
+ url: https://rubygems.org/gems/ruby_git
24
+
25
+ permissions:
26
+ contents: write
27
+ pull-requests: write
28
+ id-token: write
29
+
30
+ steps:
31
+ - name: Checkout project
32
+ uses: actions/checkout@v4
33
+
34
+ - name: Create release
35
+ uses: googleapis/release-please-action@v4
36
+ id: release
37
+ with:
38
+ token: ${{ secrets.AUTO_RELEASE_TOKEN }}
39
+ config-file: release-please-config.json
40
+ manifest-file: .release-please-manifest.json
41
+
42
+ - name: Setup ruby
43
+ uses: ruby/setup-ruby@v1
44
+ if: ${{ steps.release.outputs.release_created }}
45
+ with:
46
+ bundler-cache: true
47
+ ruby-version: ruby
48
+
49
+ - name: Push to RubyGems.org
50
+ uses: rubygems/release-gem@v1
51
+ if: ${{ steps.release.outputs.release_created }}
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.3.4"
3
+ }
data/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Change Log
2
2
 
3
+ ## [0.3.4](https://github.com/main-branch/ruby_git/compare/v0.3.3...v0.3.4) (2025-04-17)
4
+
5
+
6
+ ### Features
7
+
8
+ * Add initial_branch option to RubyGit::Worktree.init ([9f5e8da](https://github.com/main-branch/ruby_git/commit/9f5e8daca1599d46c9a53429b24f4fff47f148b6))
9
+ * Add initial_branch option to RubyGit.init ([c0007e5](https://github.com/main-branch/ruby_git/commit/c0007e501c2768e921c1aef618c8edb4969e5e95))
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * Rewrap any errors raised by Process.spawn in RubyGit::SpawnError ([1ed4444](https://github.com/main-branch/ruby_git/commit/1ed4444c12ff1598af8915eac0c568bbaa865c84))
15
+
16
+ ## [0.3.3](https://github.com/main-branch/ruby_git/compare/v0.3.2...v0.3.3) (2025-04-17)
17
+
18
+
19
+ ### Bug Fixes
20
+
21
+ * Do not trigger build workflows after merging to main or for release PRs ([0678dd3](https://github.com/main-branch/ruby_git/commit/0678dd347235aaa9f55d84853de94d01935f974d))
22
+ * Move unneeded builds from continuous_integration to experimental_ruby_builds ([2d15e1c](https://github.com/main-branch/ruby_git/commit/2d15e1c7aef848e4d3cc857e6f606a0f68d7bf6f))
23
+
24
+ ## [0.3.2](https://github.com/main-branch/ruby_git/compare/v0.3.1...v0.3.2) (2025-04-16)
25
+
26
+
27
+ ### Bug Fixes
28
+
29
+ * Automate commit-to-publish workflow ([9850fed](https://github.com/main-branch/ruby_git/commit/9850fed2230f154eaf6319644d0e6b40c5352e7f))
30
+
3
31
  ## v0.3.1 (2025-03-28)
4
32
 
5
33
  [Full Changelog](https://github.com/main-branch/ruby_git/compare/v0.3.0..v0.3.1)
data/README.md CHANGED
@@ -7,8 +7,6 @@ and the order of implementing new features.
7
7
  [![Build Status](https://github.com/main-branch/ruby_git/actions/workflows/continuous_integration.yml/badge.svg)](https://github.com/main-branch/ruby_git/actions/workflows/continuous_integration.yml)
8
8
  [![Documentation](https://img.shields.io/badge/Documentation-Latest-green)](https://rubydoc.info/gems/ruby_git/)
9
9
  [![Change Log](https://img.shields.io/badge/CHANGELOG-Latest-green)](https://rubydoc.info/gems/ruby_git/file/CHANGELOG.md)
10
- [![Maintainability](https://api.codeclimate.com/v1/badges/5403e4613b7518f70da7/maintainability)](https://codeclimate.com/github/main-branch/ruby_git/maintainability)
11
- [![Test Coverage](https://api.codeclimate.com/v1/badges/5403e4613b7518f70da7/test_coverage)](https://codeclimate.com/github/main-branch/ruby_git/test_coverage)
12
10
  [![Slack](https://img.shields.io/badge/slack-main--branch/ruby__git-yellow.svg?logo=slack)](https://main-branch.slack.com/archives/C01CHR7TMM2)
13
11
 
14
12
  Git Is Hard™ but it doesn't have to be that way. Git has this reputation because it has an
data/Rakefile CHANGED
@@ -17,6 +17,13 @@ Bundler::Audit::Task.new
17
17
  require 'bundler'
18
18
  require 'bundler/gem_tasks'
19
19
 
20
+ # Make it so that calling `rake release` just calls `rake release:rubygems_push` to
21
+ # avoid creating and pushing a new tag.
22
+
23
+ Rake::Task['release'].clear
24
+ desc 'Customized release task to avoid creating a new tag'
25
+ task release: 'release:rubygem_push'
26
+
20
27
  # RSpec
21
28
 
22
29
  require 'rspec/core/rake_task'
@@ -187,20 +187,39 @@ module RubyGit
187
187
  #
188
188
  # @api private
189
189
  #
190
- def run_with_chdir(args, options)
191
- return ProcessExecuter.run_with_options(args, options) unless jruby? && options.chdir != :not_set
190
+ def run_with_chdir(args, options) # rubocop:disable Metrics/MethodLength
191
+ return run_and_handle_spawn_error(args, options) unless jruby? && options.chdir != :not_set
192
192
 
193
193
  # :nocov: Not executed in MRI Ruby
194
- Dir.chdir(options.chdir) do
195
- saved_chdir = options.chdir
196
- options.merge!(chdir: :not_set)
197
- ProcessExecuter.run_with_options(args, options).tap do
198
- options.merge!(chdir: saved_chdir)
194
+ begin
195
+ Dir.chdir(options.chdir) do
196
+ saved_chdir = options.chdir
197
+ options.merge!(chdir: :not_set)
198
+ run_and_handle_spawn_error(args, options).tap do
199
+ options.merge!(chdir: saved_chdir)
200
+ end
199
201
  end
202
+ rescue Errno::ENOENT, Errno::ENOTDIR => e
203
+ raise RubyGit::SpawnError, "chdir(#{options.chdir}) failed: #{e.message}"
200
204
  end
201
205
  # :nocov:
202
206
  end
203
207
 
208
+ # Catch ProcessExecuter::SpawnError and raise a RubyGit::SpawnError in its place
209
+ #
210
+ # @param args [Array<String>] the command to run
211
+ # @param options [RubyGit::CommandLine::Options] the options to pass to `Process.spawn`
212
+ #
213
+ # @return [ProcessExecuter::Result] the result of the command
214
+ #
215
+ # @api private
216
+ #
217
+ def run_and_handle_spawn_error(args, options)
218
+ ProcessExecuter.run_with_options(args, options)
219
+ rescue ProcessExecuter::SpawnError => e
220
+ raise RubyGit::SpawnError, e.message
221
+ end
222
+
204
223
  # Returns true if running on JRuby
205
224
  #
206
225
  # @return [Boolean]
@@ -21,6 +21,7 @@ module RubyGit
21
21
  # │ └─> RubyGit::SignaledError
22
22
  # │ └─> RubyGit::TimeoutError
23
23
  # ├─> RubyGit::ProcessIOError
24
+ # ├─> RubyGit::SpawnError
24
25
  # └─> RubyGit::UnexpectedResultError
25
26
  # ```
26
27
  #
@@ -32,6 +33,7 @@ module RubyGit
32
33
  # | `SignaledError` | This error is raised when the git command line is terminated as a result of receiving a signal. This could happen if the process is forcibly terminated or if there is a serious system error. |
33
34
  # | `TimeoutError` | This is a specific type of `SignaledError` that is raised when the git command line operation times out and is killed via the SIGKILL signal. This happens if the operation takes longer than the timeout duration configured in `Git.config.timeout` or via the `:timeout` parameter given in git methods that support timeouts. |
34
35
  # | `ProcessIOError` | An error was encountered reading or writing to a subprocess. |
36
+ # | `SpawnError` | An error was encountered when spawning a subprocess and it never started. |
35
37
  # | `UnexpectedResultError` | The command line ran without error but did not return the expected results. |
36
38
  #
37
39
  # @example Rescuing a generic error
@@ -166,4 +168,10 @@ module RubyGit
166
168
  # @api public
167
169
  #
168
170
  class UnexpectedResultError < RubyGit::Error; end
171
+
172
+ # Raised when the git command could not be spawned
173
+ #
174
+ # @api public
175
+ #
176
+ class SpawnError < RubyGit::Error; end
169
177
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyGit
4
+ # Module containing option validators for RubyGit
5
+ # @api public
6
+ module OptionValidators
7
+ # Raise an error if an option is not a Boolean (or optionally nil) value
8
+ # @param name [String] the name of the option
9
+ # @param value [Object] the value of the option
10
+ # @param nullable [Boolean] whether the option can be nil (default is false)
11
+ # @return [void]
12
+ # @raise [ArgumentError] if the option is not a Boolean (or optionally nil) value
13
+ # @api private
14
+ def validate_boolean_option(name:, value:, nullable: false)
15
+ return if nullable && value.nil?
16
+
17
+ return if [true, false].include?(value)
18
+
19
+ raise ArgumentError, "The '#{name}:' option must be a Boolean value but was #{value.inspect}"
20
+ end
21
+
22
+ # Raise an error if an option is not a String (or optionally nil) value
23
+ # @param name [String] the name of the option
24
+ # @param value [Object] the value of the option
25
+ # @param nullable [Boolean] whether the option can be nil (default is false)
26
+ # @return [void]
27
+ # @raise [ArgumentError] if the option is not a String (or optionally nil) value
28
+ # @api private
29
+ def validate_string_option(name:, value:, nullable: false)
30
+ return if nullable && value.nil?
31
+
32
+ return if value.is_a?(String)
33
+
34
+ raise ArgumentError, "The '#{name}:' option must be a String or nil but was #{value.inspect}"
35
+ end
36
+ end
37
+ end
@@ -26,8 +26,36 @@ module RubyGit
26
26
  #
27
27
  # @param [String] repository_path the path to the repository
28
28
  #
29
+ # The purpose of this flag is to allow tests to not have to mock the
30
+ # normalization of the path. This allows testing that the right git command
31
+ # is contructed based on the options passed any particular method.
32
+ #
33
+ # @raise [ArgumentError] if the path is not a directory
34
+ #
29
35
  def initialize(repository_path)
30
- @path = File.realpath(repository_path)
36
+ @path = normalize_path(repository_path)
37
+ end
38
+
39
+ private
40
+
41
+ # Expand and convert the given path to an absolute, real path
42
+ #
43
+ # @example Expand the path
44
+ # normalize_path('~/repository.git') #=> '/Users/james/repository.git'
45
+ #
46
+ # @example Convert to an absolute path
47
+ # File.chdir('/User/james/repository/.git')
48
+ # normalize_path('.') #=> '/User/james/repository/.git'
49
+ #
50
+ # @param path [String] the path to normalize
51
+ #
52
+ # @return [String]
53
+ #
54
+ # @api private
55
+ def normalize_path(path)
56
+ raise ArgumentError, "Directory '#{path}' does not exist." unless File.directory?(path)
57
+
58
+ File.realpath(File.expand_path(path))
31
59
  end
32
60
  end
33
61
  end
@@ -3,5 +3,5 @@
3
3
  module RubyGit
4
4
  # The ruby_git gem version
5
5
  #
6
- VERSION = '0.3.1'
6
+ VERSION = '0.3.4'
7
7
  end
@@ -7,6 +7,9 @@ module RubyGit
7
7
  # Create a new Worktree using {.init}, {.clone}, or {.open}.
8
8
  #
9
9
  class Worktree
10
+ extend RubyGit::OptionValidators
11
+ include RubyGit::OptionValidators
12
+
10
13
  # The root path of the working tree
11
14
  #
12
15
  # @example
@@ -26,19 +29,24 @@ module RubyGit
26
29
  # @see https://git-scm.com/docs/git-init git-init
27
30
  #
28
31
  # @example
29
- # worktree = Worktree.init(worktree_path)
32
+ # worktree = Worktree.init(worktree_path, initial_branch: 'main')
30
33
  #
31
- # @param [String] worktree_path the root path of a Git working tree
34
+ # @param worktree_path [String] the root path of a Git working tree
35
+ # @param initial_branch [String] the initial branch in the newly created repository
32
36
  #
33
- # @raise [RubyGit::Error] if worktree_path is not a directory
37
+ # @raise [ArgumentError] if worktree_path does not exist or is not a directory
38
+ # @raise [RubyGit::Error] if there is an error initializing the repository
34
39
  #
35
40
  # @return [RubyGit::Worktree] the working tree whose root is at `path`
36
41
  #
37
- def self.init(worktree_path)
38
- raise RubyGit::Error, "Path '#{worktree_path}' not valid." unless File.directory?(worktree_path)
42
+ def self.init(worktree_path, initial_branch: nil)
43
+ validate_string_option(name: :initial_branch, value: initial_branch, nullable: true)
39
44
 
40
45
  command = ['init']
46
+ command << '--initial-branch' << initial_branch unless initial_branch.nil?
47
+
41
48
  options = { chdir: worktree_path, out: StringIO.new, err: StringIO.new }
49
+
42
50
  RubyGit::CommandLine.run(*command, **options)
43
51
 
44
52
  new(worktree_path)
@@ -105,17 +113,6 @@ module RubyGit
105
113
  new(cloned_to(clone_output))
106
114
  end
107
115
 
108
- # Get path of the cloned worktree from `git clone` stderr output
109
- #
110
- # @param clone_output [String] the stderr output of the `git clone` command
111
- #
112
- # @return [String] the path of the cloned worktree
113
- #
114
- # @api private
115
- def self.cloned_to(clone_output)
116
- clone_output.match(/Cloning into ['"](.+)['"]\.\.\./)[1]
117
- end
118
-
119
116
  # Show the working tree and index status
120
117
  #
121
118
  # @example worktree = Worktree.open(worktree_path) worktree.status #=>
@@ -154,7 +151,7 @@ module RubyGit
154
151
  command << '--' unless path_specs.empty?
155
152
  command.concat(path_specs)
156
153
  options = { out: StringIO.new, err: StringIO.new }
157
- status_output = run(*command, **options).stdout
154
+ status_output = run_with_context(*command, **options).stdout
158
155
  RubyGit::Status.parse(status_output)
159
156
  end
160
157
 
@@ -194,7 +191,7 @@ module RubyGit
194
191
 
195
192
  options = { out: StringIO.new, err: StringIO.new }
196
193
 
197
- run(*command, **options)
194
+ run_with_context(*command, **options)
198
195
  end
199
196
 
200
197
  # Return the repository associated with the worktree
@@ -206,42 +203,95 @@ module RubyGit
206
203
  # @return [RubyGit::Repository] the repository associated with the worktree
207
204
  #
208
205
  def repository
209
- @repository ||= begin
210
- command = %w[rev-parse --git-dir]
211
- options = { chdir: path, chomp: true, out: StringIO.new, err: StringIO.new }
212
- # rev-parse path might be relative to the worktree, thus the need to expand it
213
- git_dir = File.realpath(RubyGit::CommandLine.run(*command, **options).stdout, path)
214
- Repository.new(git_dir)
215
- end
206
+ @repository ||= Repository.new(repository_path)
216
207
  end
217
208
 
218
209
  private
219
210
 
211
+ # The path to the repository associated with this worktree
212
+ #
213
+ # @return [String]
214
+ #
215
+ # @api private
216
+ #
217
+ def repository_path
218
+ command = %w[rev-parse --git-dir]
219
+ options = { chdir: path, chomp: true, out: StringIO.new, err: StringIO.new }
220
+ # rev-parse path might be relative to the worktree, thus the need to expand it
221
+ File.realpath(RubyGit::CommandLine.run(*command, **options).stdout, path)
222
+ end
223
+
220
224
  # Create a Worktree object
221
225
  #
222
226
  # @param worktree_path [String] a path anywhere in the worktree
223
227
  #
228
+ # The purpose of this flag is to allow tests to not have to mock the
229
+ # normalization of the path. This allows testing that the right git command
230
+ # is contructed based on the options passed any particular method.
231
+ #
232
+ # @raise [ArgumentError] if the path is not a directory or the path is not in a
233
+ # git working tree
234
+ #
235
+ # @return [RubyGit::Worktree] the worktree whose root is at `path`
224
236
  # @api private
225
237
  #
226
238
  def initialize(worktree_path)
227
- raise RubyGit::Error, "Path '#{worktree_path}' not valid." unless File.directory?(worktree_path)
228
-
229
- @path = root_path(worktree_path)
239
+ @path = normalize_path(worktree_path)
230
240
  RubyGit.logger.debug("Created #{inspect}")
231
241
  end
232
242
 
233
- # Find the root path of a Git working tree containing `path`
243
+ # Get path of the cloned worktree from `git clone` stderr output
234
244
  #
235
- # @raise [RubyGit::FailedError] if the path is not in a Git working tree
245
+ # @param clone_output [String] the stderr output of the `git clone` command
246
+ #
247
+ # @return [String] the path of the cloned worktree
248
+ #
249
+ # @api private
250
+ private_class_method def self.cloned_to(clone_output)
251
+ clone_output.match(/Cloning into ['"](.+)['"]\.\.\./)[1]
252
+ end
253
+
254
+ # Return the absolute path to the root of the working tree containing path
255
+ #
256
+ # @example Expand the path
257
+ # normalize_path('~/worktree') #=> '/Users/james/worktree'
258
+ #
259
+ # @example Convert to an absolute path
260
+ # File.chdir('/User/james/worktree')
261
+ # normalize_path('.') #=> '/User/james/worktree'
262
+ #
263
+ # @param path [String] a (possibly relative) path within the worktree
264
+ #
265
+ # @return [String]
266
+ #
267
+ # @raise [ArgumentError] if the path is not a directory or the path is not in a
268
+ # git working tree
269
+ #
270
+ # @api private
271
+ #
272
+ def normalize_path(path)
273
+ raise ArgumentError, "Directory '#{path}' does not exist." unless File.directory?(path)
274
+
275
+ begin
276
+ root_path(path)
277
+ rescue RubyGit::FailedError => e
278
+ raise ArgumentError, e.message
279
+ end
280
+ end
281
+
282
+ # Find the root path of a Git working tree containing `path`
236
283
  #
237
284
  # @return [String] the root path of the Git working tree containing `path`
238
285
  #
286
+ # @raise [ArgumentError] if the path is not in a Git working tree
287
+ #
239
288
  # @api private
240
289
  #
241
290
  def root_path(worktree_path)
242
291
  command = %w[rev-parse --show-toplevel]
243
292
  options = { chdir: worktree_path, chomp: true, out: StringIO.new, err: StringIO.new }
244
- File.realpath(RubyGit::CommandLine.run(*command, **options).stdout)
293
+ root_path = RubyGit::CommandLine.run(*command, **options).stdout
294
+ File.realpath(File.expand_path(root_path))
245
295
  end
246
296
 
247
297
  # Run a Git command in this worktree
@@ -255,23 +305,8 @@ module RubyGit
255
305
  #
256
306
  # @api private
257
307
  #
258
- def run(*command, **options)
308
+ def run_with_context(*command, **options)
259
309
  RubyGit::CommandLine.run(*command, repository_path: repository.path, worktree_path: path, **options)
260
310
  end
261
-
262
- # Raise an error if an option is not a Boolean (or optionally nil) value
263
- # @param name [String] the name of the option
264
- # @param value [Object] the value of the option
265
- # @param nullable [Boolean] whether the option can be nil (default is false)
266
- # @return [void]
267
- # @raise [ArgumentError] if the option is not a Boolean (or optionally nil) value
268
- # @api private
269
- def validate_boolean_option(name:, value:, nullable: false)
270
- return if nullable && value.nil?
271
-
272
- return if [true, false].include?(value)
273
-
274
- raise ArgumentError, "The '#{name}:' option must be a Boolean value but was #{value.inspect}"
275
- end
276
311
  end
277
312
  end
data/lib/ruby_git.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require_relative 'ruby_git/command_line'
4
4
  require_relative 'ruby_git/encoding_normalizer'
5
5
  require_relative 'ruby_git/errors'
6
+ require_relative 'ruby_git/option_validators'
6
7
  require_relative 'ruby_git/repository'
7
8
  require_relative 'ruby_git/status'
8
9
  require_relative 'ruby_git/version'
@@ -79,16 +80,17 @@ module RubyGit
79
80
  # @see https://git-scm.com/docs/git-init git-init
80
81
  #
81
82
  # @example
82
- # worktree = Worktree.init(worktree_path)
83
+ # worktree = Worktree.init(worktree_path, initial_branch: 'main')
83
84
  #
84
- # @param [String] worktree_path the root path of a worktree
85
+ # @param worktree_path [String] the root path of a worktree
86
+ # @param initial_branch [String] the initial branch in the newly created repository
85
87
  #
86
88
  # @raise [RubyGit::Error] if worktree_path is not a directory
87
89
  #
88
90
  # @return [RubyGit::Worktree] the worktree whose root is at `path`
89
91
  #
90
- def self.init(worktree_path)
91
- RubyGit::Worktree.init(worktree_path)
92
+ def self.init(worktree_path, initial_branch:)
93
+ RubyGit::Worktree.init(worktree_path, initial_branch:)
92
94
  end
93
95
 
94
96
  # Open an existing Git working tree that contains worktree_path
@@ -0,0 +1,23 @@
1
+ {
2
+ "bootstrap-sha": "b03a7aebb563e4a25eca7f664dd39c7a0595eb61",
3
+ "packages": {
4
+ ".": {
5
+ "release-type": "ruby",
6
+ "package-name": "ruby_git",
7
+ "changelog-path": "CHANGELOG.md",
8
+ "version-file": "lib/ruby_git/version.rb",
9
+ "bump-minor-pre-major": true,
10
+ "bump-patch-for-minor-pre-major": true,
11
+ "draft": true,
12
+ "prerelease": false,
13
+ "include-component-in-tag": false,
14
+ "pull-request-title-pattern": "chore: release v${version}"
15
+ }
16
+ },
17
+ "plugins": [
18
+ {
19
+ "type": "sentence-case"
20
+ }
21
+ ],
22
+ "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
23
+ }
data/ruby_git.gemspec CHANGED
@@ -56,7 +56,7 @@ Gem::Specification.new do |spec|
56
56
  spec.add_development_dependency 'yardstick', '~> 0.9'
57
57
  end
58
58
 
59
- spec.add_dependency 'process_executer', '~> 3.0'
59
+ spec.add_dependency 'process_executer', '~> 3.2'
60
60
  spec.add_dependency 'rchardet', '~> 1.9'
61
61
 
62
62
  spec.metadata['rubygems_mfa_required'] = 'true'
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_git
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Couball
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-03-28 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: bundler-audit
@@ -203,14 +203,14 @@ dependencies:
203
203
  requirements:
204
204
  - - "~>"
205
205
  - !ruby/object:Gem::Version
206
- version: '3.0'
206
+ version: '3.2'
207
207
  type: :runtime
208
208
  prerelease: false
209
209
  version_requirements: !ruby/object:Gem::Requirement
210
210
  requirements:
211
211
  - - "~>"
212
212
  - !ruby/object:Gem::Version
213
- version: '3.0'
213
+ version: '3.2'
214
214
  - !ruby/object:Gem::Dependency
215
215
  name: rchardet
216
216
  requirement: !ruby/object:Gem::Requirement
@@ -241,9 +241,11 @@ files:
241
241
  - ".github/workflows/continuous_integration.yml"
242
242
  - ".github/workflows/enforce_conventional_commits.yml"
243
243
  - ".github/workflows/experimental_ruby_builds.yml"
244
+ - ".github/workflows/release.yml"
244
245
  - ".gitignore"
245
246
  - ".husky/commit-msg"
246
247
  - ".markdownlint.yml"
248
+ - ".release-please-manifest.json"
247
249
  - ".rspec"
248
250
  - ".rubocop.yml"
249
251
  - ".yardopts"
@@ -266,6 +268,7 @@ files:
266
268
  - lib/ruby_git/command_line/runner.rb
267
269
  - lib/ruby_git/encoding_normalizer.rb
268
270
  - lib/ruby_git/errors.rb
271
+ - lib/ruby_git/option_validators.rb
269
272
  - lib/ruby_git/repository.rb
270
273
  - lib/ruby_git/status.rb
271
274
  - lib/ruby_git/status/branch.rb
@@ -283,6 +286,7 @@ files:
283
286
  - lib/ruby_git/worktree.rb
284
287
  - package.json
285
288
  - pre-commit
289
+ - release-please-config.json
286
290
  - ruby_git.gemspec
287
291
  homepage: https://github.com/main-branch/ruby_git
288
292
  licenses:
@@ -291,8 +295,8 @@ metadata:
291
295
  allowed_push_host: https://rubygems.org
292
296
  homepage_uri: https://github.com/main-branch/ruby_git
293
297
  source_code_uri: https://github.com/main-branch/ruby_git
294
- documentation_uri: https://rubydoc.info/gems/ruby_git/0.3.1
295
- changelog_uri: https://rubydoc.info/gems/ruby_git/0.3.1/file/CHANGELOG.md
298
+ documentation_uri: https://rubydoc.info/gems/ruby_git/0.3.4
299
+ changelog_uri: https://rubydoc.info/gems/ruby_git/0.3.4/file/CHANGELOG.md
296
300
  rubygems_mfa_required: 'true'
297
301
  rdoc_options: []
298
302
  require_paths:
@@ -311,7 +315,7 @@ requirements:
311
315
  - 'Platform: Mac, Linux, or Windows'
312
316
  - 'Ruby: MRI 3.1 or later, TruffleRuby 24 or later, or JRuby 9.4 or later'
313
317
  - Git 2.28.0 or later
314
- rubygems_version: 3.6.2
318
+ rubygems_version: 3.6.7
315
319
  specification_version: 4
316
320
  summary: An object-oriented interface to working with the git command line
317
321
  test_files: []