gem-release 1.0.0 → 2.0.0.dev.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +13 -0
- data/Gemfile.lock +72 -0
- data/{lib/gem_release/templates/LICENSE → MIT-LICENSE.md} +3 -2
- data/README.md +646 -0
- data/README.md.erb +159 -0
- data/TODO.txt +194 -0
- data/lib/gem/release.rb +13 -0
- data/lib/gem/release/cmds.rb +16 -0
- data/lib/gem/release/cmds/base.rb +101 -0
- data/lib/gem/release/cmds/bootstrap.rb +222 -0
- data/lib/gem/release/cmds/bump.rb +165 -0
- data/lib/gem/release/cmds/gemspec.rb +85 -0
- data/lib/gem/release/cmds/release.rb +100 -0
- data/lib/gem/release/cmds/runner.rb +52 -0
- data/lib/gem/release/cmds/tag.rb +93 -0
- data/lib/gem/release/config.rb +42 -0
- data/lib/gem/release/config/env.rb +49 -0
- data/lib/gem/release/config/files.rb +35 -0
- data/lib/gem/release/context.rb +76 -0
- data/lib/gem/release/context/gem.rb +28 -0
- data/lib/gem/release/context/gemspec.rb +41 -0
- data/lib/gem/release/context/paths.rb +87 -0
- data/lib/gem/release/context/system.rb +36 -0
- data/lib/gem/release/data.rb +60 -0
- data/lib/gem/release/files/template.rb +61 -0
- data/lib/gem/release/files/template/context.rb +30 -0
- data/lib/gem/release/files/templates.rb +59 -0
- data/lib/gem/release/files/templates/group.rb +47 -0
- data/lib/gem/release/files/version.rb +68 -0
- data/lib/gem/release/helper.rb +45 -0
- data/lib/gem/release/helper/hash.rb +35 -0
- data/lib/gem/release/helper/string.rb +43 -0
- data/lib/gem/release/support/gem_command.rb +67 -0
- data/lib/gem/release/support/registry.rb +59 -0
- data/lib/gem/release/templates/.gitignore +8 -0
- data/lib/gem/release/templates/Gemfile +3 -0
- data/lib/gem/release/templates/gemspec +19 -0
- data/lib/gem/release/templates/licenses/mit.md +21 -0
- data/lib/gem/release/templates/licenses/mpl-2.md +373 -0
- data/lib/gem/release/templates/main.rb +1 -0
- data/lib/gem/release/templates/rspec/.rspec +3 -0
- data/lib/gem/release/templates/rspec/spec/spec_helper.rb +4 -0
- data/lib/gem/release/templates/travis/.travis.yml +1 -0
- data/lib/gem/release/templates/version.rb +1 -0
- data/lib/gem/release/version.rb +5 -0
- data/lib/gem/release/version/number.rb +102 -0
- data/lib/rubygems/commands/bootstrap_command.rb +4 -93
- data/lib/rubygems/commands/bump_command.rb +4 -110
- data/lib/rubygems/commands/gemspec_command.rb +5 -29
- data/lib/rubygems/commands/release_command.rb +4 -70
- data/lib/rubygems/commands/tag_command.rb +5 -46
- data/lib/rubygems_plugin.rb +8 -2
- metadata +56 -83
- data/lib/core_ext/hash/symbolize_keys.rb +0 -13
- data/lib/core_ext/kernel/silence.rb +0 -18
- data/lib/core_ext/string/camelize.rb +0 -5
- data/lib/gem_release.rb +0 -10
- data/lib/gem_release/command_options.rb +0 -31
- data/lib/gem_release/configuration.rb +0 -33
- data/lib/gem_release/gemspec_template.rb +0 -35
- data/lib/gem_release/helpers.rb +0 -104
- data/lib/gem_release/template.rb +0 -52
- data/lib/gem_release/templates/Gemfile +0 -3
- data/lib/gem_release/templates/README.md +0 -1
- data/lib/gem_release/templates/Rakefile +0 -10
- data/lib/gem_release/templates/gemspec +0 -18
- data/lib/gem_release/templates/gitignore +0 -25
- data/lib/gem_release/templates/test/test_helper.rb +0 -2
- data/lib/gem_release/templates/version.rb +0 -12
- data/lib/gem_release/version.rb +0 -3
- data/lib/gem_release/version_file.rb +0 -115
- data/lib/gem_release/version_template.rb +0 -14
@@ -0,0 +1,222 @@
|
|
1
|
+
require 'gem/release/cmds/base'
|
2
|
+
require 'gem/release/data'
|
3
|
+
require 'gem/release/files/templates'
|
4
|
+
|
5
|
+
module Gem
|
6
|
+
module Release
|
7
|
+
module Cmds
|
8
|
+
class Bootstrap < Base
|
9
|
+
summary 'Scaffolds a new gem from template files.'
|
10
|
+
|
11
|
+
# TODO document license
|
12
|
+
|
13
|
+
description <<~str
|
14
|
+
#{summary} Optionally initialize a git repository, set a git remote, and push
|
15
|
+
to the remote repository.
|
16
|
+
|
17
|
+
If no argument is given the current directory name is used as the gem name. If
|
18
|
+
one or many arguments are given then these will be used as gem names, and new
|
19
|
+
directories will be created accordingly.
|
20
|
+
|
21
|
+
By default the following files will be created:
|
22
|
+
|
23
|
+
* `.gitignore`
|
24
|
+
* `Gemspec`
|
25
|
+
* `[gem-name].gemspec`
|
26
|
+
* `LICENSE.md`
|
27
|
+
* `lib/[gem]/[name].rb`
|
28
|
+
* `lib/[gem]/[name]/version.rb`
|
29
|
+
|
30
|
+
Templates in the first existing one of these directories will always be used to
|
31
|
+
create additional files:
|
32
|
+
|
33
|
+
* `./.gem-release/default` (local)
|
34
|
+
* `~/.gem-release/default` (global)
|
35
|
+
|
36
|
+
If `--template [group]` is given additional files will be created from the
|
37
|
+
first existing one of these directories:
|
38
|
+
|
39
|
+
* `./.gem-release/[group]` (local)
|
40
|
+
* `~/.gem-release/[group]` (global)
|
41
|
+
|
42
|
+
It is possible to specify several template groups in order to add files from
|
43
|
+
several custom template directories.
|
44
|
+
|
45
|
+
If `--template rspec` is given then additionally the files `.rspec` and
|
46
|
+
`spec/spec_helper.rb` will be created, or whatever files exist in a local or
|
47
|
+
global directory `.gem-release/templates/rspec`.
|
48
|
+
|
49
|
+
If `--template travis` is given then additionally the file `.travis.yml` will
|
50
|
+
be created, or whatever files exist in a local or global directory
|
51
|
+
`.gem-release/templates/travis`.
|
52
|
+
|
53
|
+
The license added by default is the MIT License. If `--license [name]` is given
|
54
|
+
then this license will be added. The only other license file shipped is the
|
55
|
+
Mozilla Public License v2.0. Other licenses must be present in the local or
|
56
|
+
global directory `.gem-release/licenses`.
|
57
|
+
str
|
58
|
+
|
59
|
+
arg :gem_name, 'name of the gem (optional, will default to the current directory name if not specified)'
|
60
|
+
|
61
|
+
DEFAULTS = {
|
62
|
+
strategy: :glob,
|
63
|
+
scaffold: true,
|
64
|
+
git: true,
|
65
|
+
github: false,
|
66
|
+
push: false,
|
67
|
+
license: :mit,
|
68
|
+
templates: []
|
69
|
+
}
|
70
|
+
|
71
|
+
DESCR = {
|
72
|
+
scaffold: 'Scaffold gem files',
|
73
|
+
dir: 'Directory to place the gem in (defaults to the given name, or the current working dir)',
|
74
|
+
licenses: 'License(s) to add',
|
75
|
+
template: 'Template groups to use for scaffolding',
|
76
|
+
rspec: 'Use the rspec group (by default adds .rspec and spec/spec_helper.rb)',
|
77
|
+
travis: 'Use the rspec group (by default adds .travis.yml)',
|
78
|
+
strategy: 'Strategy for collecting files [glob|git] in .gemspec',
|
79
|
+
git: 'Initialize a git repo',
|
80
|
+
github: 'Initialize a git repo, create on github',
|
81
|
+
remote: 'Git remote repository',
|
82
|
+
push: 'Push the git repo to github'
|
83
|
+
}
|
84
|
+
|
85
|
+
opt '--[no]-scaffold', DESCR[:scaffold] do |value|
|
86
|
+
opts[:scaffold] = value
|
87
|
+
end
|
88
|
+
|
89
|
+
opt '--dir DIR', DESCR[:dir] do |value|
|
90
|
+
opts[:dir] = value
|
91
|
+
end
|
92
|
+
|
93
|
+
opt '-t', '--template NAME', DESCR[:template] do |value|
|
94
|
+
(opts[:templates] ||= []) << value
|
95
|
+
end
|
96
|
+
|
97
|
+
opt '--rspec', DESCR[:rspec] do |value|
|
98
|
+
(opts[:templates] ||= []) << value
|
99
|
+
end
|
100
|
+
|
101
|
+
opt '--travis', DESCR[:travis] do |value|
|
102
|
+
(opts[:templates] ||= []) << value
|
103
|
+
end
|
104
|
+
|
105
|
+
opt '-l', '--no-license NAME', DESCR[:license] do |value|
|
106
|
+
value ? (opts[:license] ||= []) << value : opts[:license] = []
|
107
|
+
end
|
108
|
+
|
109
|
+
opt '-s', '--strategy NAME', DESCR[:strategy] do |value|
|
110
|
+
opts[:strategy] = value
|
111
|
+
end
|
112
|
+
|
113
|
+
opt '--git', DESCR[:git] do |value|
|
114
|
+
opts[:git] = value
|
115
|
+
end
|
116
|
+
|
117
|
+
opt '--github', DESCR[:github] do |value|
|
118
|
+
opts[:github] = value
|
119
|
+
end
|
120
|
+
|
121
|
+
opt '--remote', DESCR[:remote] do |value|
|
122
|
+
opts[:remote] = value
|
123
|
+
end
|
124
|
+
|
125
|
+
opt '--push', DESCR[:push] do |value|
|
126
|
+
opts[:push] = value
|
127
|
+
end
|
128
|
+
|
129
|
+
MSGS = {
|
130
|
+
scaffold: 'Scaffolding gem %s',
|
131
|
+
create: 'Creating %s',
|
132
|
+
exists: 'Skipping existing file %s',
|
133
|
+
git_init: 'Initializing git repository',
|
134
|
+
git_add: 'Adding files',
|
135
|
+
git_commit: 'Creating initial commit',
|
136
|
+
git_remote: 'Adding git remote %s',
|
137
|
+
git_push: 'Pushing to git remote %s',
|
138
|
+
unknown_license: 'Unknown license: %s'
|
139
|
+
}
|
140
|
+
|
141
|
+
CMDS = {
|
142
|
+
git_init: 'git init',
|
143
|
+
git_add: 'git add .',
|
144
|
+
git_commit: 'git commit -m "Initial commit"',
|
145
|
+
git_remote: 'git remote add %s https://github.com/%s.git',
|
146
|
+
git_push: 'git push -u %s master'
|
147
|
+
}
|
148
|
+
|
149
|
+
def run
|
150
|
+
in_dirs do
|
151
|
+
scaffold if opts[:scaffold]
|
152
|
+
init_git if opts[:github] || opts[:git]
|
153
|
+
create_repo if opts[:github]
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
private
|
158
|
+
|
159
|
+
FILES = %w(
|
160
|
+
.gitignore
|
161
|
+
Gemfile
|
162
|
+
gemspec
|
163
|
+
main.rb
|
164
|
+
version.rb
|
165
|
+
)
|
166
|
+
|
167
|
+
def scaffold
|
168
|
+
announce :scaffold, gem.name
|
169
|
+
files.each { |file| write(file) }
|
170
|
+
end
|
171
|
+
|
172
|
+
def files
|
173
|
+
files = Files::Templates.new(FILES, opts[:templates], data).all
|
174
|
+
files << license if opts[:license]
|
175
|
+
files.compact
|
176
|
+
end
|
177
|
+
|
178
|
+
def license
|
179
|
+
file = Files::Templates.license(opts[:license], data)
|
180
|
+
warn :unknown_license, opts[:license] unless file
|
181
|
+
file
|
182
|
+
end
|
183
|
+
|
184
|
+
def write(file)
|
185
|
+
msg = :create if pretend?
|
186
|
+
msg ||= file.write ? :create : :exists
|
187
|
+
level = msg == :create ? :info : :warn
|
188
|
+
send(level, msg, file.target)
|
189
|
+
end
|
190
|
+
|
191
|
+
def init_git
|
192
|
+
cmd :git_init
|
193
|
+
cmd :git_add
|
194
|
+
cmd :git_commit
|
195
|
+
end
|
196
|
+
|
197
|
+
def create_repo
|
198
|
+
cmd :git_remote, remote, "#{github_user_name}/#{gem.name}"
|
199
|
+
cmd :git_push, remote if opts[:push]
|
200
|
+
end
|
201
|
+
|
202
|
+
def data
|
203
|
+
Data.new(system, gem, opts).data
|
204
|
+
end
|
205
|
+
|
206
|
+
def remote
|
207
|
+
opts[:remote] || :origin
|
208
|
+
end
|
209
|
+
|
210
|
+
def opts
|
211
|
+
@opts ||= normalize(super)
|
212
|
+
end
|
213
|
+
|
214
|
+
def normalize(opts)
|
215
|
+
opts[:templates] << 'rspec' if opts.delete(:rspec)
|
216
|
+
opts[:templates] << 'travis' if opts.delete(:travis)
|
217
|
+
opts
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
require 'gem/release/cmds/base'
|
2
|
+
require 'gem/release/files/version'
|
3
|
+
|
4
|
+
module Gem
|
5
|
+
module Release
|
6
|
+
module Cmds
|
7
|
+
class Bump < Base
|
8
|
+
summary 'Bumps one, several, or all gems in this directory.'
|
9
|
+
|
10
|
+
description <<~str
|
11
|
+
Bumps the version number defined in lib/[gem_name]/version.rb to to a given,
|
12
|
+
specific version number, or to the next major, minor, patch, or pre-release
|
13
|
+
level.
|
14
|
+
|
15
|
+
Optionally it pushes to the origin repository. Also, optionally it invokes the
|
16
|
+
`gem tag` and/or `gem release` command.
|
17
|
+
|
18
|
+
If no argument is given the first gemspec's name is assumed as the gem name.
|
19
|
+
If one or many arguments are given then these will be used as gem names. If
|
20
|
+
`--recurse` is given then all gem names from all gemspecs in this directory or
|
21
|
+
any of its subdirectories will be used.
|
22
|
+
|
23
|
+
The version can be bumped to either one of these targets:
|
24
|
+
|
25
|
+
```
|
26
|
+
major
|
27
|
+
1.1.1 # Bump to the given, specific version number
|
28
|
+
major # Bump to the next major level (e.g. 0.0.1 to 1.0.0)
|
29
|
+
minor # Bump to the next minor level (e.g. 0.0.1 to 0.1.0)
|
30
|
+
patch # Bump to the next patch level (e.g. 0.0.1 to 0.0.2)
|
31
|
+
pre|rc|etc # Bump to the next pre-release level (e.g. 0.0.1 to
|
32
|
+
# 0.1.0.pre.1, 1.0.0.pre.1 to 1.0.0.pre.2)
|
33
|
+
```
|
34
|
+
|
35
|
+
When searching for the version file for a gem named `gem-name`: the following
|
36
|
+
paths will be searched relative to the gemspec's directory.
|
37
|
+
|
38
|
+
* `lib/gem-name/version.rb`
|
39
|
+
* `lib/gem/name/version.rb`
|
40
|
+
str
|
41
|
+
|
42
|
+
arg :gem_name, 'name of the gem (optional, will use the directory name, or all gemspecs if --recurse is given)'
|
43
|
+
|
44
|
+
DESCR = {
|
45
|
+
version: 'Target version: next [major|minor|patch|pre|release] or a given version number [x.x.x]',
|
46
|
+
commit: 'Perform a commit after incrementing gem version',
|
47
|
+
push: 'Push the new commit to the git remote repository',
|
48
|
+
remote: 'Git remote to push to (defaults to origin)',
|
49
|
+
tag: 'Shortcut for running the `gem tag` command',
|
50
|
+
recurse: 'Recurse into directories that contain gemspec files',
|
51
|
+
release: 'Shortcut for the `gem release` command'
|
52
|
+
}
|
53
|
+
|
54
|
+
DEFAULTS = {
|
55
|
+
commit: true,
|
56
|
+
push: true,
|
57
|
+
remote: 'origin'
|
58
|
+
}
|
59
|
+
|
60
|
+
opt '-c', '--[no-]commit', DESCR[:commit] do |value|
|
61
|
+
opts[:commit] = value
|
62
|
+
end
|
63
|
+
|
64
|
+
opt '-p', '--[no-]push', DESCR[:push] do |value|
|
65
|
+
opts[:push] = value
|
66
|
+
end
|
67
|
+
|
68
|
+
opt '--remote REMOTE', DESCR[:remote] do |value|
|
69
|
+
opts[:remote] = value
|
70
|
+
end
|
71
|
+
|
72
|
+
opt '-v', '--version VERSION', DESCR[:version] do |value|
|
73
|
+
opts[:version] = value
|
74
|
+
end
|
75
|
+
|
76
|
+
opt '-t', '--tag', DESCR[:tag] do |value|
|
77
|
+
opts[:tag] = value
|
78
|
+
end
|
79
|
+
|
80
|
+
opt '-r', '--release', DESCR[:release] do |value|
|
81
|
+
opts[:release] = value
|
82
|
+
end
|
83
|
+
|
84
|
+
opt '--recurse', DESCR[:recurse] do |value|
|
85
|
+
opts[:recurse] = value
|
86
|
+
end
|
87
|
+
|
88
|
+
MSGS = {
|
89
|
+
not_found: 'Ignoring %s. Version file %s not found.',
|
90
|
+
no_remote: 'Cannot push to missing git remote %s.',
|
91
|
+
bump: 'Bumping %s from version %s to %s',
|
92
|
+
version: 'Changing version in %s from %s to %s',
|
93
|
+
git_add: 'Staging %s',
|
94
|
+
git_commit: 'Creating commit',
|
95
|
+
git_push: 'Pushing to the %s git repository'
|
96
|
+
}
|
97
|
+
|
98
|
+
CMDS = {
|
99
|
+
git_add: 'git add %s',
|
100
|
+
git_commit: 'git commit -m "Bump to %s"',
|
101
|
+
git_push: 'git push %s'
|
102
|
+
}
|
103
|
+
|
104
|
+
def run
|
105
|
+
in_gem_dirs do
|
106
|
+
validate
|
107
|
+
bump
|
108
|
+
commit if opts[:commit]
|
109
|
+
push if opts[:commit] && opts[:push]
|
110
|
+
reset
|
111
|
+
end
|
112
|
+
tag if opts[:tag]
|
113
|
+
release if opts[:release]
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def validate
|
119
|
+
abort :not_found, gem.name, version.path unless version.exists?
|
120
|
+
abort :no_remote, remote if push? && !git_remotes.include?(remote)
|
121
|
+
end
|
122
|
+
|
123
|
+
def bump
|
124
|
+
announce :bump, gem.name, version.from, version.to
|
125
|
+
return true if pretend?
|
126
|
+
notice :version, version.path, version.from, version.to
|
127
|
+
version.bump
|
128
|
+
end
|
129
|
+
|
130
|
+
def commit
|
131
|
+
cmd :git_add, version.path
|
132
|
+
cmd :git_commit, version.to
|
133
|
+
end
|
134
|
+
|
135
|
+
def push
|
136
|
+
cmd :git_push, remote
|
137
|
+
end
|
138
|
+
|
139
|
+
def tag
|
140
|
+
Tag.new(context, args, opts).run
|
141
|
+
end
|
142
|
+
|
143
|
+
def release
|
144
|
+
Release.new(context, args, except(opts, :tag)).run
|
145
|
+
end
|
146
|
+
|
147
|
+
def reset
|
148
|
+
@version = nil
|
149
|
+
end
|
150
|
+
|
151
|
+
def version
|
152
|
+
@version ||= Files::Version.new(gem.name, opts[:version])
|
153
|
+
end
|
154
|
+
|
155
|
+
def push?
|
156
|
+
opts[:push]
|
157
|
+
end
|
158
|
+
|
159
|
+
def remote
|
160
|
+
opts[:remote]
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'gem/release/cmds/base'
|
2
|
+
require 'gem/release/data'
|
3
|
+
require 'gem/release/files/template'
|
4
|
+
|
5
|
+
module Gem
|
6
|
+
module Release
|
7
|
+
module Cmds
|
8
|
+
class Gemspec < Base
|
9
|
+
summary 'Generates a gemspec.'
|
10
|
+
|
11
|
+
description <<~str
|
12
|
+
#{summary}
|
13
|
+
|
14
|
+
If no argument is given the current directory name is used as the gem name. If
|
15
|
+
one or many arguments are given then these will be used as gem names, and new
|
16
|
+
directories will be created accordingly.
|
17
|
+
|
18
|
+
The generated `gemspec` file will use the `glob` strategy for finding files by
|
19
|
+
default. Known strategies are:
|
20
|
+
|
21
|
+
* `glob` - uses the glob pattern `{bin/*,lib/**/*,[A-Z]*}`
|
22
|
+
* `git` - uses the git command `git ls-files app lib`
|
23
|
+
str
|
24
|
+
|
25
|
+
arg :gem_name, 'name of the gem (optional, will default to the current directory name if not specified)'
|
26
|
+
|
27
|
+
DEFAULTS = {
|
28
|
+
strategy: :glob
|
29
|
+
}
|
30
|
+
|
31
|
+
DESCR = {
|
32
|
+
dir: 'Directory to place the gem in (defaults to the given name, or the current working dir)',
|
33
|
+
license: 'License(s) to list in the gemspec',
|
34
|
+
strategy: 'Strategy for collecting files [glob|git] in gemspec'
|
35
|
+
}
|
36
|
+
|
37
|
+
opt '--dir DIR', DESCR[:dir] do |value|
|
38
|
+
opts[:dir] = value
|
39
|
+
end
|
40
|
+
|
41
|
+
opt '-l', '--[no]-license[s] NAMES', DESCR[:license] do |value|
|
42
|
+
value ? (opts[:license] ||= []) << value : opts[:license] = []
|
43
|
+
end
|
44
|
+
|
45
|
+
opt '-s', '--strategy', DESCR[:strategy] do |value|
|
46
|
+
opts[:strategy] = value
|
47
|
+
end
|
48
|
+
|
49
|
+
MSGS = {
|
50
|
+
gemspec: 'Generating %s.gemspec',
|
51
|
+
create: 'Creating %s',
|
52
|
+
exists: 'Skipping %s: already exists'
|
53
|
+
}
|
54
|
+
|
55
|
+
def run
|
56
|
+
in_dirs do
|
57
|
+
announce :gemspec, gem.name
|
58
|
+
generate
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def generate
|
65
|
+
msg = :create if pretend?
|
66
|
+
msg ||= file.write ? :create : :exists
|
67
|
+
level = msg == :create ? :notice : :warn
|
68
|
+
send(level, msg, file.target)
|
69
|
+
end
|
70
|
+
|
71
|
+
def file
|
72
|
+
templates["#{gem.name}.gemspec"]
|
73
|
+
end
|
74
|
+
|
75
|
+
def templates
|
76
|
+
Files::Templates.new(['gemspec'], opts[:template], data)
|
77
|
+
end
|
78
|
+
|
79
|
+
def data
|
80
|
+
Data.new(system, gem, opts).data
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|