gem-release 1.0.0 → 2.0.0.dev.1
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/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,28 @@
|
|
1
|
+
require 'gem/release/context/gemspec'
|
2
|
+
|
3
|
+
module Gem
|
4
|
+
module Release
|
5
|
+
class Context
|
6
|
+
class Gem
|
7
|
+
attr_reader :name, :spec
|
8
|
+
|
9
|
+
def initialize(name)
|
10
|
+
@spec = Gemspec.new(name)
|
11
|
+
@name = name
|
12
|
+
end
|
13
|
+
|
14
|
+
def version
|
15
|
+
spec.version.to_s if spec
|
16
|
+
end
|
17
|
+
|
18
|
+
def filename
|
19
|
+
spec.gem_filename if spec
|
20
|
+
end
|
21
|
+
|
22
|
+
def spec_filename
|
23
|
+
spec.filename if name
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Gem
|
2
|
+
module Release
|
3
|
+
class Context
|
4
|
+
class Gemspec < Struct.new(:name)
|
5
|
+
attr_reader :filename
|
6
|
+
|
7
|
+
def initialize(*)
|
8
|
+
super
|
9
|
+
@filename = name && "#{name}.gemspec" || filenames.first
|
10
|
+
end
|
11
|
+
|
12
|
+
def gem_name
|
13
|
+
gemspec.name if gemspec
|
14
|
+
end
|
15
|
+
|
16
|
+
def version
|
17
|
+
gemspec.version.to_s if gemspec
|
18
|
+
end
|
19
|
+
|
20
|
+
def gem_filename
|
21
|
+
gemspec.file_name if gemspec
|
22
|
+
end
|
23
|
+
|
24
|
+
def exists?
|
25
|
+
filename && File.exists?(filename)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def gemspec
|
31
|
+
return @gemspec if instance_variable_defined?(:@gemspec)
|
32
|
+
@gemspec = exists? ? ::Gem::Specification.load(filename) : nil
|
33
|
+
end
|
34
|
+
|
35
|
+
def filenames
|
36
|
+
Dir['*.gemspec'].map { |path| File.basename(path) }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
module Gem
|
4
|
+
module Release
|
5
|
+
class Context
|
6
|
+
class Paths < Struct.new(:names, :opts)
|
7
|
+
class Base < Struct.new(:names, :opts)
|
8
|
+
def in_dir(dir, &block)
|
9
|
+
dir == cwd ? yield : Dir.chdir(dir, &block)
|
10
|
+
end
|
11
|
+
|
12
|
+
def current
|
13
|
+
[[cwd, cwd.basename.to_s]]
|
14
|
+
end
|
15
|
+
|
16
|
+
def cwd
|
17
|
+
@cwd ||= Pathname.pwd
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class ByNames < Base
|
22
|
+
def in_dirs(&block)
|
23
|
+
dirs.each do |dir, name|
|
24
|
+
dir.mkdir unless dir == cwd || dir.exist?
|
25
|
+
in_dir(dir) { yield name }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def dirs
|
32
|
+
names.any? ? dirs_by_names : current
|
33
|
+
end
|
34
|
+
|
35
|
+
def dirs_by_names
|
36
|
+
names.map { |name| [Pathname.new(dir || name).expand_path, name] }
|
37
|
+
end
|
38
|
+
|
39
|
+
def dir
|
40
|
+
opts[:dir]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class ByGemspecs < Base
|
45
|
+
def in_dirs(&block)
|
46
|
+
dirs.each do |dir, name|
|
47
|
+
in_dir(dir) { yield name }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def dirs
|
54
|
+
dirs = by_gemspecs if opts[:recurse]
|
55
|
+
dirs ||= by_names if names.any?
|
56
|
+
dirs ||= gemspec
|
57
|
+
dirs || by_gemspecs || current
|
58
|
+
end
|
59
|
+
|
60
|
+
def by_gemspecs
|
61
|
+
paths = gemspecs(true).map { |path| [path.dirname, name_for(path)] }
|
62
|
+
paths unless paths.empty?
|
63
|
+
end
|
64
|
+
|
65
|
+
def by_names
|
66
|
+
paths = names.map { |arg| by_gemspecs.detect { |_, name| name == arg } }.compact
|
67
|
+
paths unless paths.empty?
|
68
|
+
end
|
69
|
+
|
70
|
+
def gemspec
|
71
|
+
path = gemspecs.first
|
72
|
+
[[path.expand_path.dirname, name_for(path)]] if path
|
73
|
+
end
|
74
|
+
|
75
|
+
def name_for(path)
|
76
|
+
path.basename('.gemspec').to_s
|
77
|
+
end
|
78
|
+
|
79
|
+
def gemspecs(recurse = false)
|
80
|
+
pattern = recurse ? '**/*.gemspec' : '*.gemspec'
|
81
|
+
Pathname.glob(pattern).map(&:expand_path).sort
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Gem
|
2
|
+
module Release
|
3
|
+
class Context
|
4
|
+
class System
|
5
|
+
def run(cmd)
|
6
|
+
system(cmd)
|
7
|
+
end
|
8
|
+
|
9
|
+
def gem_cmd(cmd, *args)
|
10
|
+
::Gem::Commands.const_get("#{cmd.to_s.capitalize}Command").new.invoke(*args.flatten)
|
11
|
+
# TODO what's with the return value? maybe add our own abstraction that can check the result?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
15
|
+
def git_remotes
|
16
|
+
`git remote`.split("\n")
|
17
|
+
end
|
18
|
+
|
19
|
+
def git_user_name
|
20
|
+
str = `git config --get user.name`.strip
|
21
|
+
str unless str.empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
def git_user_email
|
25
|
+
str = `git config --get user.email`.strip
|
26
|
+
str unless str.empty?
|
27
|
+
end
|
28
|
+
|
29
|
+
def github_user_name
|
30
|
+
str = `git config --get github.user`.strip
|
31
|
+
str.empty? ? git_user_name : str
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'ostruct'
|
3
|
+
require 'gem/release/helper/string'
|
4
|
+
|
5
|
+
module Gem
|
6
|
+
module Release
|
7
|
+
class Data < Struct.new(:system, :gem, :opts)
|
8
|
+
include Helper::String
|
9
|
+
|
10
|
+
def data
|
11
|
+
{
|
12
|
+
gem_name: gem_name,
|
13
|
+
gem_path: gem_name.gsub('-', '/'),
|
14
|
+
module_names: module_names,
|
15
|
+
author: user_name,
|
16
|
+
email: user_email,
|
17
|
+
homepage: homepage,
|
18
|
+
licenses: licenses,
|
19
|
+
summary: '[summary]',
|
20
|
+
description: '[description]',
|
21
|
+
files: files
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def module_names
|
28
|
+
gem_name.split('-').map { |part| camelize(part) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def gem_name
|
32
|
+
gem.name || raise('No gem_name given.')
|
33
|
+
end
|
34
|
+
|
35
|
+
def user_name
|
36
|
+
system.git_user_name || '[your name]'
|
37
|
+
end
|
38
|
+
|
39
|
+
def user_email
|
40
|
+
system.git_user_email || '[your email]'
|
41
|
+
end
|
42
|
+
|
43
|
+
def homepage
|
44
|
+
"https://github.com/#{user_name}/#{gem_name}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def licenses
|
48
|
+
Array(license).join(',').split(',').map(&:upcase)
|
49
|
+
end
|
50
|
+
|
51
|
+
def license
|
52
|
+
opts[:license] if opts[:license]
|
53
|
+
end
|
54
|
+
|
55
|
+
def files
|
56
|
+
STRATEGIES[(opts[:strategy] || :glob).to_sym] || STRATEGIES[:glob]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'gem/release/files/template/context'
|
2
|
+
|
3
|
+
module Gem
|
4
|
+
module Release
|
5
|
+
module Files
|
6
|
+
class Template
|
7
|
+
FILES = {
|
8
|
+
'.gitignore' => '.gitignore',
|
9
|
+
'Gemfile' => 'Gemfile',
|
10
|
+
'gemspec' => '%{gem_name}.gemspec',
|
11
|
+
'license' => 'MIT-LICENSE.md',
|
12
|
+
'main.rb' => 'lib/%{gem_path}.rb',
|
13
|
+
'version.rb' => 'lib/%{gem_path}/version.rb'
|
14
|
+
}
|
15
|
+
|
16
|
+
attr_accessor :source, :target, :data
|
17
|
+
|
18
|
+
def initialize(source, target, data)
|
19
|
+
@source = source
|
20
|
+
@target = (FILES[target] || target) % data
|
21
|
+
@data = data
|
22
|
+
end
|
23
|
+
|
24
|
+
PATH = File.expand_path('../..', __FILE__)
|
25
|
+
|
26
|
+
def filename
|
27
|
+
File.basename(target)
|
28
|
+
end
|
29
|
+
|
30
|
+
def write
|
31
|
+
return false if exists?
|
32
|
+
FileUtils.mkdir_p(File.dirname(target))
|
33
|
+
File.write(target, render)
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def exists?
|
38
|
+
File.exist?(target.to_s)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def render
|
44
|
+
template.result(binding)
|
45
|
+
end
|
46
|
+
|
47
|
+
def template
|
48
|
+
ERB.new(File.read(source))
|
49
|
+
end
|
50
|
+
|
51
|
+
def binding
|
52
|
+
context.instance_eval { binding }
|
53
|
+
end
|
54
|
+
|
55
|
+
def context
|
56
|
+
Context.new(data)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Gem
|
2
|
+
module Release
|
3
|
+
module Files
|
4
|
+
class Template
|
5
|
+
class Context < OpenStruct
|
6
|
+
class Const < Struct.new(:type, :names)
|
7
|
+
def define(&block)
|
8
|
+
lines = build(names) { |name| "#{type} #{name}" }
|
9
|
+
lines << indent(block.call, names.size) if block
|
10
|
+
lines += build(names) { |name| 'end' }.reverse
|
11
|
+
lines.join("\n")
|
12
|
+
end
|
13
|
+
|
14
|
+
def build(names, &block)
|
15
|
+
names.map.with_index { |name, ix| indent(block.call(name), ix) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def indent(str, level)
|
19
|
+
"#{' ' * level}#{str}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def define(type, &block)
|
24
|
+
Const.new(type, module_names).define(&block)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Gem
|
2
|
+
module Release
|
3
|
+
module Files
|
4
|
+
class Templates < Struct.new(:files, :groups, :data)
|
5
|
+
BUILTIN = [
|
6
|
+
['./.gem-release/%s'],
|
7
|
+
['~/.gem-release/%s'],
|
8
|
+
['../../templates/', __FILE__],
|
9
|
+
]
|
10
|
+
|
11
|
+
CUSTOM = [
|
12
|
+
['./.gem-release/%s'],
|
13
|
+
['~/.gem-release/%s'],
|
14
|
+
['../../templates/%s', __FILE__],
|
15
|
+
]
|
16
|
+
|
17
|
+
LICENSE = [
|
18
|
+
['./.gem-release/licenses'],
|
19
|
+
['~/.gem-release/licenses'],
|
20
|
+
['../../templates/licenses', __FILE__],
|
21
|
+
]
|
22
|
+
|
23
|
+
def self.license(name, data)
|
24
|
+
file = Templates.new(["#{name}{,.*}"], [], data).license
|
25
|
+
file.target = "LICENSE#{File.extname(file.target)}" if file
|
26
|
+
file
|
27
|
+
end
|
28
|
+
|
29
|
+
def [](filename)
|
30
|
+
all.detect { |file| file.filename == filename }
|
31
|
+
end
|
32
|
+
|
33
|
+
def all
|
34
|
+
all = builtin + custom
|
35
|
+
all.flatten.uniq(&:target)
|
36
|
+
end
|
37
|
+
|
38
|
+
def builtin
|
39
|
+
templates_for(BUILTIN, files)
|
40
|
+
end
|
41
|
+
|
42
|
+
def custom
|
43
|
+
templates_for(CUSTOM, '**/*')
|
44
|
+
end
|
45
|
+
|
46
|
+
def license
|
47
|
+
templates_for(LICENSE, files).first
|
48
|
+
end
|
49
|
+
|
50
|
+
def templates_for(sources, files)
|
51
|
+
all = Group.new(groups, data, sources, files).all
|
52
|
+
all.map { |source, target| Template.new(source, target, data) }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
require 'gem/release/files/templates/group'
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Gem
|
2
|
+
module Release
|
3
|
+
module Files
|
4
|
+
class Templates
|
5
|
+
class Group
|
6
|
+
attr_reader :groups, :data, :sources, :files
|
7
|
+
|
8
|
+
def initialize(groups, data, sources, files)
|
9
|
+
@groups = [:default] + Array(groups)
|
10
|
+
@data = data
|
11
|
+
@sources = sources
|
12
|
+
@files = Array(files)
|
13
|
+
end
|
14
|
+
|
15
|
+
def all
|
16
|
+
return [] unless paths.any?
|
17
|
+
all = Dir.glob(pattern, File::FNM_DOTMATCH)
|
18
|
+
all = all.select { |file| File.file?(file) }
|
19
|
+
all.map { |file| [file, relative(file)] }
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def pattern
|
25
|
+
"{#{paths.join(',')}}/{#{files.join(',')}}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def relative(file)
|
29
|
+
paths.inject(file) { |file, path| file.sub("#{path}/", '') }
|
30
|
+
end
|
31
|
+
|
32
|
+
def paths
|
33
|
+
@paths ||= groups.map do |group|
|
34
|
+
paths = paths_for(group).map { |path| File.expand_path(*path) }
|
35
|
+
paths.detect { |path| File.exists?(path) }
|
36
|
+
end.compact
|
37
|
+
end
|
38
|
+
|
39
|
+
def paths_for(group)
|
40
|
+
sources.map { |paths| paths.map { |path| path % group } }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|