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 +4 -4
- data/.github/workflows/continuous_integration.yml +5 -38
- data/.github/workflows/enforce_conventional_commits.yml +4 -0
- data/.github/workflows/experimental_ruby_builds.yml +10 -4
- data/.github/workflows/release.yml +51 -0
- data/.release-please-manifest.json +3 -0
- data/CHANGELOG.md +28 -0
- data/README.md +0 -2
- data/Rakefile +7 -0
- data/lib/ruby_git/command_line/runner.rb +26 -7
- data/lib/ruby_git/errors.rb +8 -0
- data/lib/ruby_git/option_validators.rb +37 -0
- data/lib/ruby_git/repository.rb +29 -1
- data/lib/ruby_git/version.rb +1 -1
- data/lib/ruby_git/worktree.rb +82 -47
- data/lib/ruby_git.rb +6 -4
- data/release-please-config.json +23 -0
- data/ruby_git.gemspec +1 -1
- metadata +11 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c3507b566d30abc32d770188184bf932f3af97985f579df84dfa24b3e6e9a96
|
4
|
+
data.tar.gz: 8fecb84e47a289736ecf79579a2de496b0520734a4a3d6199c5838e0543ba1d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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-
|
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 }}
|
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
|
[](https://github.com/main-branch/ruby_git/actions/workflows/continuous_integration.yml)
|
8
8
|
[](https://rubydoc.info/gems/ruby_git/)
|
9
9
|
[](https://rubydoc.info/gems/ruby_git/file/CHANGELOG.md)
|
10
|
-
[](https://codeclimate.com/github/main-branch/ruby_git/maintainability)
|
11
|
-
[](https://codeclimate.com/github/main-branch/ruby_git/test_coverage)
|
12
10
|
[](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
|
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
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
options.
|
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]
|
data/lib/ruby_git/errors.rb
CHANGED
@@ -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
|
data/lib/ruby_git/repository.rb
CHANGED
@@ -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 =
|
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
|
data/lib/ruby_git/version.rb
CHANGED
data/lib/ruby_git/worktree.rb
CHANGED
@@ -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]
|
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 [
|
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
|
-
|
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 =
|
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
|
-
|
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 ||=
|
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
|
-
|
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
|
-
#
|
243
|
+
# Get path of the cloned worktree from `git clone` stderr output
|
234
244
|
#
|
235
|
-
# @
|
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
|
-
|
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
|
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]
|
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.
|
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.
|
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:
|
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.
|
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.
|
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.
|
295
|
-
changelog_uri: https://rubydoc.info/gems/ruby_git/0.3.
|
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.
|
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: []
|