semmy 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -5
- data/README.md +22 -0
- data/lib/semmy/scm/git.rb +34 -0
- data/lib/semmy/scm/jj.rb +85 -0
- data/lib/semmy/scm.rb +39 -5
- data/lib/semmy/tasks/branches.rb +6 -8
- data/lib/semmy/tasks/commit.rb +2 -8
- data/lib/semmy/tasks.rb +2 -0
- data/lib/semmy/version.rb +1 -1
- data/semmy.gemspec +1 -2
- metadata +11 -24
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ce09082714dcb3d35eb9667425bf29167c3d3a768138b272a7b09af7ff592343
|
|
4
|
+
data.tar.gz: 819dd6a572482aced62c3a3b80ab28d4af69a09276401cca60f0536df602194d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f4e4fb1222c83d1e94ccf400719c36d21501fb1f4219cae6a314ce389fce167bbeb2f5a881fc0cf2bf7fe42c72ee63e2fbaec43a7e5a89cf83528bd589884925
|
|
7
|
+
data.tar.gz: 6bbcad0f49ab3726535dde84915a57f139708ebefd97fe1879dc8e1a97c22a6c051162c0ee4279bdb76df4bd4c793fc0805e56886776dc85db09963aedf6368f
|
data/CHANGELOG.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
-
### Version 1.
|
|
3
|
+
### Version 1.3.0
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
2026-09-11
|
|
6
6
|
|
|
7
|
-
[Compare changes](https://github.com/tf/semmy/compare/1-
|
|
7
|
+
[Compare changes](https://github.com/tf/semmy/compare/1-2-stable...v1.3.0)
|
|
8
8
|
|
|
9
|
-
-
|
|
9
|
+
- Support releasing from Jujutsu repositories.
|
|
10
10
|
|
|
11
11
|
See
|
|
12
|
-
[1-
|
|
12
|
+
[1-2-stable branch](https://github.com/tf/semmy/blob/1-2-stable/CHANGELOG.md)
|
|
13
13
|
for previous changes.
|
data/README.md
CHANGED
|
@@ -21,6 +21,28 @@ tags.
|
|
|
21
21
|
Patch level versions are released via backports to the stable
|
|
22
22
|
branches.
|
|
23
23
|
|
|
24
|
+
### Jujutsu Repositories
|
|
25
|
+
|
|
26
|
+
Semmy detects a `.jj` directory and drives
|
|
27
|
+
[Jujutsu](https://jj-vcs.github.io/jj/) instead of Git. Bookmarks take
|
|
28
|
+
the place of branches: since jj has no checked out branch, the
|
|
29
|
+
bookmark of the closest ancestor commit is used and the commit tasks
|
|
30
|
+
move it forward explicitly. The release branch is resolved once per
|
|
31
|
+
rake run, before `branches:create_stable` places a second bookmark on
|
|
32
|
+
the same commit.
|
|
33
|
+
|
|
34
|
+
Bundler's `release` task shells out to Git, and colocated jj
|
|
35
|
+
repositories leave `HEAD` detached, which would make its push step
|
|
36
|
+
fail with `src refspec refs/heads/HEAD does not match any`. Semmy
|
|
37
|
+
attaches `HEAD` to the release branch in a prerequisite of Bundler's
|
|
38
|
+
`release:source_control_push` task. Only the ref is moved, never the
|
|
39
|
+
working copy, and jj detaches `HEAD` again on its next working copy
|
|
40
|
+
update.
|
|
41
|
+
|
|
42
|
+
This requires the working copy commit to sit directly on top of the
|
|
43
|
+
release branch. Otherwise the release aborts with a hint to run
|
|
44
|
+
`jj new master`.
|
|
45
|
+
|
|
24
46
|
### Version Suffix
|
|
25
47
|
|
|
26
48
|
The version in the gem's version file is increased in a separate
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'git'
|
|
2
|
+
|
|
3
|
+
module Semmy
|
|
4
|
+
module Scm
|
|
5
|
+
module Git
|
|
6
|
+
extend self
|
|
7
|
+
|
|
8
|
+
def current_branch
|
|
9
|
+
repository.current_branch
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def commit_all(message, _branch)
|
|
13
|
+
repository.commit_all(message)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def create_branch(name, _base)
|
|
17
|
+
repository.branch(name).create
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def push(remote, name)
|
|
21
|
+
repository.push(remote, name)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def attach_git_head(_branch)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def repository
|
|
30
|
+
::Git.open('.')
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/semmy/scm/jj.rb
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
require 'open3'
|
|
2
|
+
|
|
3
|
+
module Semmy
|
|
4
|
+
module Scm
|
|
5
|
+
module Jj
|
|
6
|
+
extend self
|
|
7
|
+
|
|
8
|
+
class CommandFailed < Error; end
|
|
9
|
+
class BookmarkNotFound < Error; end
|
|
10
|
+
class GitHeadMismatch < Error; end
|
|
11
|
+
|
|
12
|
+
def current_branch
|
|
13
|
+
jj('log', '--no-graph',
|
|
14
|
+
'--revisions', 'heads(::@ & bookmarks())',
|
|
15
|
+
'--template', 'local_bookmarks.map(|bookmark| bookmark.name()).join("\n")')
|
|
16
|
+
.split("\n").first
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def commit_all(message, branch)
|
|
20
|
+
bookmark = required_bookmark(branch)
|
|
21
|
+
|
|
22
|
+
jj('commit', '--message', message)
|
|
23
|
+
jj('bookmark', 'set', bookmark, '--revision', '@-')
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def create_branch(name, base)
|
|
27
|
+
jj('bookmark', 'create', name, '--revision', required_bookmark(base))
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def push(remote, name)
|
|
31
|
+
unless bookmark?(name)
|
|
32
|
+
fail(BookmarkNotFound, "Bookmark #{name} does not exist.")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
jj('git', 'push', '--remote', remote, '--bookmark', name)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def attach_git_head(branch)
|
|
39
|
+
bookmark = required_bookmark(branch)
|
|
40
|
+
reference = "refs/heads/#{bookmark}"
|
|
41
|
+
|
|
42
|
+
unless git('rev-parse', 'HEAD') == git('rev-parse', reference)
|
|
43
|
+
fail(GitHeadMismatch,
|
|
44
|
+
"Git HEAD is not at #{bookmark}. " \
|
|
45
|
+
"Run `jj new #{bookmark}` before releasing.")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
Shell.info("Attaching git HEAD to #{bookmark}.")
|
|
49
|
+
git('symbolic-ref', 'HEAD', reference)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def required_bookmark(name)
|
|
55
|
+
name ||
|
|
56
|
+
fail(BookmarkNotFound,
|
|
57
|
+
'No bookmark found in ancestors of working copy commit.')
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def bookmark?(name)
|
|
61
|
+
!jj('bookmark', 'list', '--template', 'name ++ "\n"', name).strip.empty?
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def jj(*args)
|
|
65
|
+
run('jj', *args)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def git(*args)
|
|
69
|
+
run('git', *args)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def run(command, *args)
|
|
73
|
+
stdout, stderr, status = Open3.capture3(command, *args)
|
|
74
|
+
|
|
75
|
+
unless status.success?
|
|
76
|
+
fail(CommandFailed,
|
|
77
|
+
"Command `#{command} #{args.join(' ')}` failed:\n#{stderr}")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
Shell.sub_process_output(stderr.chomp) unless stderr.empty?
|
|
81
|
+
stdout
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
data/lib/semmy/scm.rb
CHANGED
|
@@ -1,17 +1,46 @@
|
|
|
1
|
+
require 'pathname'
|
|
2
|
+
|
|
3
|
+
require 'semmy/scm/git'
|
|
4
|
+
require 'semmy/scm/jj'
|
|
5
|
+
|
|
1
6
|
module Semmy
|
|
2
7
|
module Scm
|
|
3
8
|
extend self
|
|
4
9
|
|
|
5
10
|
def on_master?
|
|
6
|
-
|
|
11
|
+
release_branch == 'master'
|
|
7
12
|
end
|
|
8
13
|
|
|
9
14
|
def on_minor_version_stable?(stable_branch_name)
|
|
10
|
-
!!
|
|
15
|
+
!!release_branch.to_s.match(stable_branch_matcher(stable_branch_name))
|
|
11
16
|
end
|
|
12
17
|
|
|
13
18
|
def on_major_version_stable?(stable_branch_name)
|
|
14
|
-
!!
|
|
19
|
+
!!release_branch.to_s.match(major_version_stable_branch_matcher(stable_branch_name))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def commit_all(message)
|
|
23
|
+
repository.commit_all(message, release_branch)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def create_branch(name)
|
|
27
|
+
repository.create_branch(name, release_branch)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def push(remote, name)
|
|
31
|
+
repository.push(remote, name)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def attach_git_head
|
|
35
|
+
repository.attach_git_head(release_branch)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def release_branch
|
|
39
|
+
@release_branch ||= repository.current_branch
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def reset
|
|
43
|
+
@release_branch = nil
|
|
15
44
|
end
|
|
16
45
|
|
|
17
46
|
private
|
|
@@ -24,8 +53,13 @@ module Semmy
|
|
|
24
53
|
Regexp.new(stable_branch_name.gsub(/%\{\w+\}/, '[0-9]+'))
|
|
25
54
|
end
|
|
26
55
|
|
|
27
|
-
def
|
|
28
|
-
|
|
56
|
+
def repository
|
|
57
|
+
Pathname.pwd.ascend do |directory|
|
|
58
|
+
return Jj if directory.join('.jj').directory?
|
|
59
|
+
return Git if directory.join('.git').exist?
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
Git
|
|
29
63
|
end
|
|
30
64
|
end
|
|
31
65
|
end
|
data/lib/semmy/tasks/branches.rb
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'git'
|
|
2
|
-
|
|
3
1
|
module Semmy
|
|
4
2
|
module Tasks
|
|
5
3
|
class Branches < Base
|
|
@@ -8,7 +6,7 @@ module Semmy
|
|
|
8
6
|
task 'create_stable' do
|
|
9
7
|
Shell.info("Creating stable branch #{stable_branch_name}.")
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
Scm.create_branch(stable_branch_name)
|
|
12
10
|
end
|
|
13
11
|
|
|
14
12
|
task 'push_master', [:remote] do |_, args|
|
|
@@ -18,6 +16,10 @@ module Semmy
|
|
|
18
16
|
task 'push_previous_stable', [:remote] do |_, args|
|
|
19
17
|
push_branch(args[:remote], previous_stable_branch_name)
|
|
20
18
|
end
|
|
19
|
+
|
|
20
|
+
task 'attach_git_head' do
|
|
21
|
+
Scm.attach_git_head
|
|
22
|
+
end
|
|
21
23
|
end
|
|
22
24
|
end
|
|
23
25
|
|
|
@@ -38,15 +40,11 @@ module Semmy
|
|
|
38
40
|
|
|
39
41
|
if config.push_branches_after_release
|
|
40
42
|
Shell.info("Pushing #{name} to #{remote}.")
|
|
41
|
-
|
|
43
|
+
Scm.push(remote, name)
|
|
42
44
|
else
|
|
43
45
|
Shell.info("NOTE: Remember to push #{name} to #{remote}.")
|
|
44
46
|
end
|
|
45
47
|
end
|
|
46
|
-
|
|
47
|
-
def git
|
|
48
|
-
Git.open('.')
|
|
49
|
-
end
|
|
50
48
|
end
|
|
51
49
|
end
|
|
52
50
|
end
|
data/lib/semmy/tasks/commit.rb
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'git'
|
|
2
|
-
|
|
3
1
|
module Semmy
|
|
4
2
|
module Tasks
|
|
5
3
|
class Commit < Base
|
|
@@ -8,7 +6,7 @@ module Semmy
|
|
|
8
6
|
task 'prepare' do
|
|
9
7
|
Shell.info('Creating prepare commit.')
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
Scm.commit_all(config.prepare_commit_message % {
|
|
12
10
|
version: Project.version
|
|
13
11
|
})
|
|
14
12
|
end
|
|
@@ -16,15 +14,11 @@ module Semmy
|
|
|
16
14
|
task 'bump' do
|
|
17
15
|
Shell.info('Creating bump commit.')
|
|
18
16
|
|
|
19
|
-
|
|
17
|
+
Scm.commit_all(config.bump_commit_message % {
|
|
20
18
|
version: Project.version
|
|
21
19
|
})
|
|
22
20
|
end
|
|
23
21
|
end
|
|
24
|
-
|
|
25
|
-
def git
|
|
26
|
-
Git.open('.')
|
|
27
|
-
end
|
|
28
22
|
end
|
|
29
23
|
end
|
|
30
24
|
end
|
data/lib/semmy/tasks.rb
CHANGED
data/lib/semmy/version.rb
CHANGED
data/semmy.gemspec
CHANGED
|
@@ -22,8 +22,7 @@ Gem::Specification.new do |spec|
|
|
|
22
22
|
spec.add_dependency 'unindent', '~> 1.0'
|
|
23
23
|
spec.add_dependency 'rainbow', '~> 2.1'
|
|
24
24
|
|
|
25
|
-
spec.add_development_dependency '
|
|
26
|
-
spec.add_development_dependency 'rake', '~> 11.0'
|
|
25
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
|
27
26
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
28
27
|
spec.add_development_dependency 'rubocop', '~> 0.42.0'
|
|
29
28
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: semmy
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tim Fischbach
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-09-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: git
|
|
@@ -52,34 +52,20 @@ dependencies:
|
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
54
|
version: '2.1'
|
|
55
|
-
- !ruby/object:Gem::Dependency
|
|
56
|
-
name: bundler
|
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
|
58
|
-
requirements:
|
|
59
|
-
- - "~>"
|
|
60
|
-
- !ruby/object:Gem::Version
|
|
61
|
-
version: '1.10'
|
|
62
|
-
type: :development
|
|
63
|
-
prerelease: false
|
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
-
requirements:
|
|
66
|
-
- - "~>"
|
|
67
|
-
- !ruby/object:Gem::Version
|
|
68
|
-
version: '1.10'
|
|
69
55
|
- !ruby/object:Gem::Dependency
|
|
70
56
|
name: rake
|
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
|
72
58
|
requirements:
|
|
73
59
|
- - "~>"
|
|
74
60
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '
|
|
61
|
+
version: '13.0'
|
|
76
62
|
type: :development
|
|
77
63
|
prerelease: false
|
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
65
|
requirements:
|
|
80
66
|
- - "~>"
|
|
81
67
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '
|
|
68
|
+
version: '13.0'
|
|
83
69
|
- !ruby/object:Gem::Dependency
|
|
84
70
|
name: rspec
|
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -108,7 +94,7 @@ dependencies:
|
|
|
108
94
|
- - "~>"
|
|
109
95
|
- !ruby/object:Gem::Version
|
|
110
96
|
version: 0.42.0
|
|
111
|
-
description:
|
|
97
|
+
description:
|
|
112
98
|
email:
|
|
113
99
|
- mail@timfischbach.de
|
|
114
100
|
executables: []
|
|
@@ -140,6 +126,8 @@ files:
|
|
|
140
126
|
- lib/semmy/project.rb
|
|
141
127
|
- lib/semmy/ruby_gems.rb
|
|
142
128
|
- lib/semmy/scm.rb
|
|
129
|
+
- lib/semmy/scm/git.rb
|
|
130
|
+
- lib/semmy/scm/jj.rb
|
|
143
131
|
- lib/semmy/shell.rb
|
|
144
132
|
- lib/semmy/tasks.rb
|
|
145
133
|
- lib/semmy/tasks/base.rb
|
|
@@ -157,7 +145,7 @@ homepage: https://github.com/tf/semmy
|
|
|
157
145
|
licenses:
|
|
158
146
|
- MIT
|
|
159
147
|
metadata: {}
|
|
160
|
-
post_install_message:
|
|
148
|
+
post_install_message:
|
|
161
149
|
rdoc_options: []
|
|
162
150
|
require_paths:
|
|
163
151
|
- lib
|
|
@@ -172,9 +160,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
172
160
|
- !ruby/object:Gem::Version
|
|
173
161
|
version: '0'
|
|
174
162
|
requirements: []
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
signing_key:
|
|
163
|
+
rubygems_version: 3.4.19
|
|
164
|
+
signing_key:
|
|
178
165
|
specification_version: 4
|
|
179
166
|
summary: Rake tasks for a semantic versioning of gems
|
|
180
167
|
test_files: []
|