gem-release 2.0.4 → 2.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 96e9d27302cb5ba5444cad166e530346225b7a0aa3d013b364bcde5ad1635f27
4
- data.tar.gz: 0bbb377c212e3c54d0793fb36de24ffd9e4d08ef361ae9981bf6fa486ae5f397
3
+ metadata.gz: 59a74ca0943a92d16c2b92150c7663328f6305f6c0e80326511b1bd9b1538b9c
4
+ data.tar.gz: 0f0d2bf816fec6d960ad13115fdd29f8b01c5d0c2d52ea36c46672760f51bc4e
5
5
  SHA512:
6
- metadata.gz: 6c0b04712a95b66f3d264fdfb8dc8d1a84b2ad44a417b256d672e63bcef30b718ceb819e9c24b71aa877f5d2f6afe49b8274f9341c216142f4c0b6651d5e3e1b
7
- data.tar.gz: aaec8d0107ae77203b1d2f1f7a2fd4126e4d0f3ca3eb9368da77bdf033d44d7867c09d8eb6ad876b66bc487406bc4100fef9f5145a4e860d50fd784d973af29c
6
+ metadata.gz: f5d485a4a0f2b82af24381ad741aa013d3af2ec13c73dd39e579a52de2fe0829fd9ab9bbb976d074c19412497178e5850e92be36e1e1048d4b47c5e849e16a87
7
+ data.tar.gz: 25051d1b673c5f38a445e1966bff7b360cf704bff9253d0a710d2e493a5b7bb2ab03a0ae5060336902a9080aea5d77f48a21bfb8475b4a2d724a3fed17e836b7
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## v2.1.0 - 2019-10-17
4
+
5
+ ### Added
6
+
7
+ - Add gem release --github
8
+ (PR: https://github.com/svenfuchs/gem-release/pull/73)
9
+
3
10
  ## v2.0.4 - 2019-10-10
4
11
 
5
12
  ### Fixed
data/Gemfile CHANGED
@@ -10,4 +10,5 @@ group :test do
10
10
  gem 'rspec'
11
11
  gem 'simplecov'
12
12
  gem 'coveralls'
13
+ gem 'webmock'
13
14
  end
@@ -1,13 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gem-release (2.0.3)
4
+ gem-release (2.1.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- addressable (2.6.0)
10
- public_suffix (>= 2.0.2, < 4.0)
9
+ addressable (2.7.0)
10
+ public_suffix (>= 2.0.2, < 5.0)
11
11
  builder (3.2.3)
12
12
  coveralls (0.8.23)
13
13
  json (>= 1.8, < 3)
@@ -19,7 +19,7 @@ GEM
19
19
  safe_yaml (~> 1.0.0)
20
20
  diff-lcs (1.3)
21
21
  docile (1.3.2)
22
- faraday (0.15.4)
22
+ faraday (0.17.0)
23
23
  multipart-post (>= 1.2, < 3)
24
24
  geminabox (1.1.1)
25
25
  builder
@@ -28,47 +28,47 @@ GEM
28
28
  nesty
29
29
  reentrant_flock
30
30
  sinatra (>= 1.2.7)
31
- hashdiff (0.4.0)
31
+ hashdiff (1.0.0)
32
32
  httpclient (2.8.3)
33
33
  json (2.2.0)
34
34
  multipart-post (2.1.1)
35
35
  mustermann (1.0.3)
36
36
  nesty (1.0.2)
37
- public_suffix (3.1.1)
37
+ public_suffix (4.0.1)
38
38
  rack (2.0.7)
39
- rack-protection (2.0.5)
39
+ rack-protection (2.0.7)
40
40
  rack
41
41
  reentrant_flock (0.1.1)
42
- rspec (3.8.0)
43
- rspec-core (~> 3.8.0)
44
- rspec-expectations (~> 3.8.0)
45
- rspec-mocks (~> 3.8.0)
46
- rspec-core (3.8.2)
47
- rspec-support (~> 3.8.0)
48
- rspec-expectations (3.8.4)
42
+ rspec (3.9.0)
43
+ rspec-core (~> 3.9.0)
44
+ rspec-expectations (~> 3.9.0)
45
+ rspec-mocks (~> 3.9.0)
46
+ rspec-core (3.9.0)
47
+ rspec-support (~> 3.9.0)
48
+ rspec-expectations (3.9.0)
49
49
  diff-lcs (>= 1.2.0, < 2.0)
50
- rspec-support (~> 3.8.0)
51
- rspec-mocks (3.8.1)
50
+ rspec-support (~> 3.9.0)
51
+ rspec-mocks (3.9.0)
52
52
  diff-lcs (>= 1.2.0, < 2.0)
53
- rspec-support (~> 3.8.0)
54
- rspec-support (3.8.2)
53
+ rspec-support (~> 3.9.0)
54
+ rspec-support (3.9.0)
55
55
  safe_yaml (1.0.5)
56
56
  simplecov (0.16.1)
57
57
  docile (~> 1.1)
58
58
  json (>= 1.8, < 3)
59
59
  simplecov-html (~> 0.10.0)
60
60
  simplecov-html (0.10.2)
61
- sinatra (2.0.5)
61
+ sinatra (2.0.7)
62
62
  mustermann (~> 1.0)
63
63
  rack (~> 2.0)
64
- rack-protection (= 2.0.5)
64
+ rack-protection (= 2.0.7)
65
65
  tilt (~> 2.0)
66
66
  term-ansicolor (1.7.1)
67
67
  tins (~> 1.0)
68
68
  thor (0.20.3)
69
- tilt (2.0.9)
70
- tins (1.20.3)
71
- webmock (3.6.0)
69
+ tilt (2.0.10)
70
+ tins (1.21.1)
71
+ webmock (3.7.6)
72
72
  addressable (>= 2.3.6)
73
73
  crack (>= 0.3.2)
74
74
  hashdiff (>= 0.4.0, < 2.0.0)
@@ -1,6 +1,7 @@
1
1
  require 'gem/release/cmds/bootstrap'
2
2
  require 'gem/release/cmds/bump'
3
3
  require 'gem/release/cmds/gemspec'
4
+ require 'gem/release/cmds/github'
4
5
  require 'gem/release/cmds/release'
5
6
  require 'gem/release/cmds/runner'
6
7
  require 'gem/release/cmds/tag'
@@ -0,0 +1,79 @@
1
+ require 'gem/release/cmds/base'
2
+ require 'gem/release/context/github'
3
+
4
+ module Gem
5
+ module Release
6
+ module Cmds
7
+ class Github < Base
8
+ summary "Creates a GitHub release for the current version."
9
+
10
+ description <<-str.split("\n").map(&:lstrip).join("\n")
11
+ Creates a GitHub release for the current version.
12
+
13
+ Requires a tag `v[version]` to be present or --tag to be given.
14
+ str
15
+
16
+ MSGS = {
17
+ release: 'Creating GitHub release for %s version %s.',
18
+ no_tag: 'Tag %s does not exist. Run `gem tag` or pass `--tag`.',
19
+ no_repo: 'Could not determine the repository name. Please pass `--repo REPO`, or set homepage or metadata[:github_url] to the GitHub repository URL in the gemspec.',
20
+ no_token: 'Could not determine the GitHub OAuth token. Please pass `--token TOKEN`. See https://developer.github.com/v3/#oauth2-token-sent-in-a-header for more details.',
21
+ }.freeze
22
+
23
+ def run
24
+ in_gem_dirs do
25
+ announce :release, gem.name, tag_name
26
+ validate
27
+ release
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def validate
34
+ abort :no_tag, tag_name unless tagged?
35
+ abort :no_token unless token
36
+ end
37
+
38
+ def tagged?
39
+ git.tags.include?(tag_name)
40
+ end
41
+
42
+ def release
43
+ return if pretend?
44
+ Context::Github.new(repo, data).release
45
+ end
46
+
47
+ def data
48
+ {
49
+ version: gem.version,
50
+ tag_name: tag_name,
51
+ name: "#{gem.name} #{tag_name}",
52
+ descr: descr,
53
+ token: token
54
+ }
55
+ end
56
+
57
+ def tag_name
58
+ "v#{gem.version}"
59
+ end
60
+
61
+ def repo
62
+ opts[:repo] || repo_from(gem.spec.homepage) || repo_from(gem.spec.metadata[:github_url]) || abort(:no_repo)
63
+ end
64
+
65
+ def repo_from(url)
66
+ url && url =~ %r(https://github\.com/(.*/.*)) && $1
67
+ end
68
+
69
+ def token
70
+ opts[:token]
71
+ end
72
+
73
+ def descr
74
+ opts[:descr]
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -32,8 +32,17 @@ module Gem
32
32
  host: 'Push to a compatible host other than rubygems.org',
33
33
  key: 'Use the API key from ~/.gem/credentials',
34
34
  tag: 'Shortcut for running the `gem tag` command',
35
- push: 'Push tag to the remote git repository',
36
- recurse: 'Recurse into directories that contain gemspec files'
35
+ push: 'Push tag to the remote git repository',
36
+ github: 'Create a GitHub release',
37
+ recurse: 'Recurse into directories that contain gemspec files',
38
+
39
+ # region github
40
+
41
+ descr: 'Description of the release',
42
+ repo: "Full name of the repository on GitHub, e.g. svenfuchs/gem-release (defaults to the repo name from the gemspec's homepage if this is a GitHub URL)",
43
+ token: 'GitHub OAuth token'
44
+
45
+ # endregion github
37
46
  }.freeze
38
47
 
39
48
  opt '-h', '--host HOST', descr(:host) do |value|
@@ -56,6 +65,26 @@ module Gem
56
65
  opts[:recurse] = value
57
66
  end
58
67
 
68
+ # region github
69
+
70
+ opt '-g', '--github', descr(:github) do |value|
71
+ opts[:github] = value
72
+ end
73
+
74
+ opt '-d', '--description DESCRIPTION', descr(:descr) do |value|
75
+ opts[:descr] = value
76
+ end
77
+
78
+ opt '--repo REPO', descr(:repo) do |value|
79
+ opts[:repo] = value
80
+ end
81
+
82
+ opt '--token TOKEN', descr(:token) do |value|
83
+ opts[:token] = value
84
+ end
85
+
86
+ # endregion github
87
+
59
88
  MSGS = {
60
89
  release: 'Releasing %s with version %s',
61
90
  build: 'Building %s',
@@ -73,7 +102,8 @@ module Gem
73
102
  validate
74
103
  release
75
104
  end
76
- tag if opts[:tag]
105
+ tag if opts[:tag]
106
+ github if opts[:github]
77
107
  end
78
108
 
79
109
  private
@@ -84,16 +114,13 @@ module Gem
84
114
 
85
115
  def release
86
116
  announce :release, gem.name, target_version
117
+ return if pretend?
87
118
  build
88
119
  push
89
120
  ensure
90
121
  cleanup
91
122
  end
92
123
 
93
- def tag
94
- Tag.new(context, args, opts).run
95
- end
96
-
97
124
  def build
98
125
  gem_cmd :build, gem.spec_filename
99
126
  end
@@ -102,6 +129,14 @@ module Gem
102
129
  gem_cmd :push, gem.filename, *push_args
103
130
  end
104
131
 
132
+ def tag
133
+ Tag.new(context, args, opts).run
134
+ end
135
+
136
+ def github
137
+ Github.new(context, args, opts).run
138
+ end
139
+
105
140
  def push_args
106
141
  args = [:key, :host].map { |opt| ["--#{opt}", opts[opt]] if opts[opt] }
107
142
  args << "--quiet" if quiet?
@@ -9,6 +9,10 @@ module Gem
9
9
  @filename = name && "#{name}.gemspec" || filenames.first
10
10
  end
11
11
 
12
+ def exists?
13
+ filename && File.exist?(filename)
14
+ end
15
+
12
16
  def gem_name
13
17
  gemspec.name if gemspec
14
18
  end
@@ -21,8 +25,12 @@ module Gem
21
25
  gemspec.file_name if gemspec
22
26
  end
23
27
 
24
- def exists?
25
- filename && File.exist?(filename)
28
+ def metadata
29
+ gemspec && gemspec.metadata || {}
30
+ end
31
+
32
+ def homepage
33
+ gemspec.homepage if gemspec
26
34
  end
27
35
 
28
36
  private
@@ -0,0 +1,62 @@
1
+ require 'json'
2
+ require 'gem/release/helper/http'
3
+ require 'gem/release/version'
4
+
5
+ module Gem
6
+ module Release
7
+ class Context
8
+ class Github
9
+ include Helper::Http
10
+
11
+ URL = 'https://api.github.com/repos/%s/releases'
12
+
13
+ MSGS = {
14
+ error: 'GitHub returned %s (body: %p)'
15
+ }.freeze
16
+
17
+ attr_reader :repo, :data
18
+
19
+ def initialize(repo, data)
20
+ @repo = repo
21
+ @data = data
22
+ end
23
+
24
+ def release
25
+ # Create a release
26
+ # https://developer.github.com/v3/repos/releases/#create-a-release
27
+ resp = post(url, body, headers)
28
+ status, body = resp
29
+ # success status code is 201 (created) not 200 (ok)
30
+ raise Abort, MSGS.fetch(:error) % [status, body] unless status == 201
31
+ end
32
+
33
+ private
34
+
35
+ def url
36
+ URL % repo
37
+ end
38
+
39
+ def body
40
+ JSON.dump(
41
+ tag_name: data[:tag_name],
42
+ name: data[:name],
43
+ body: data[:descr],
44
+ prerelease: pre?(data[:version])
45
+ )
46
+ end
47
+
48
+ def headers
49
+ {
50
+ 'User-Agent' => "gem-release/v#{::Gem::Release::VERSION}",
51
+ 'Content-Type' => 'text/json',
52
+ 'Authorization' => "token #{data[:token]}",
53
+ }
54
+ end
55
+
56
+ def pre?(version)
57
+ Version::Number.new(version).pre?
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -34,9 +34,12 @@ module Gem
34
34
  end
35
35
 
36
36
  def abort(msg, *args)
37
- msg = self.class::MSGS[msg] % args if msg.is_a?(Symbol)
38
- msg = "#{msg} Aborting."
39
- context.abort(msg)
37
+ processed_msg = if msg.is_a?(Symbol)
38
+ self.class::MSGS.fetch(msg) % args
39
+ else
40
+ msg
41
+ end
42
+ context.abort("#{processed_msg} Aborting.")
40
43
  end
41
44
  end
42
45
  end
@@ -0,0 +1,39 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+
4
+ module Gem
5
+ module Release
6
+ module Helper
7
+ module Http
8
+ class Client < Struct.new(:method, :url, :body, :headers)
9
+ def request
10
+ req = const.new(uri.request_uri, headers)
11
+ req.body = body if body
12
+ resp = client.request(req)
13
+ [resp.code.to_i, resp.body]
14
+ end
15
+
16
+ private
17
+
18
+ def uri
19
+ @uri ||= URI.parse(url)
20
+ end
21
+
22
+ def client
23
+ http_client = Net::HTTP.new(uri.host, uri.port)
24
+ http_client.use_ssl = (uri.scheme == 'https')
25
+ http_client
26
+ end
27
+
28
+ def const
29
+ Net::HTTP.const_get(method.to_s.capitalize)
30
+ end
31
+ end
32
+
33
+ def post(url, body = nil, headers = {})
34
+ Client.new(:post, url, body, headers).request
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -52,8 +52,8 @@ module Gem
52
52
 
53
53
  def execute
54
54
  Cmds::Runner.new(cmd, opts.delete(:args), opts).run
55
- rescue Abort
56
- abort
55
+ rescue Abort => ex
56
+ abort(ex.message)
57
57
  end
58
58
 
59
59
  def cmd
@@ -1,5 +1,5 @@
1
1
  module Gem
2
2
  module Release
3
- VERSION = '2.0.4'
3
+ VERSION = '2.1.0'
4
4
  end
5
5
  end
@@ -14,6 +14,10 @@ module Gem
14
14
  parts.join(stage_delim)
15
15
  end
16
16
 
17
+ def pre?
18
+ !!parts[4]
19
+ end
20
+
17
21
  private
18
22
 
19
23
  def specific?
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gem-release
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.4
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Fuchs
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-10-10 00:00:00.000000000 Z
12
+ date: 2019-10-17 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Release your ruby gems with ease. (What a bold statement for such a tiny
15
15
  plugin ...)
@@ -31,6 +31,7 @@ files:
31
31
  - lib/gem/release/cmds/bootstrap.rb
32
32
  - lib/gem/release/cmds/bump.rb
33
33
  - lib/gem/release/cmds/gemspec.rb
34
+ - lib/gem/release/cmds/github.rb
34
35
  - lib/gem/release/cmds/release.rb
35
36
  - lib/gem/release/cmds/runner.rb
36
37
  - lib/gem/release/cmds/tag.rb
@@ -41,6 +42,7 @@ files:
41
42
  - lib/gem/release/context/gem.rb
42
43
  - lib/gem/release/context/gemspec.rb
43
44
  - lib/gem/release/context/git.rb
45
+ - lib/gem/release/context/github.rb
44
46
  - lib/gem/release/context/paths.rb
45
47
  - lib/gem/release/context/ui.rb
46
48
  - lib/gem/release/data.rb
@@ -51,6 +53,7 @@ files:
51
53
  - lib/gem/release/files/version.rb
52
54
  - lib/gem/release/helper.rb
53
55
  - lib/gem/release/helper/hash.rb
56
+ - lib/gem/release/helper/http.rb
54
57
  - lib/gem/release/helper/string.rb
55
58
  - lib/gem/release/support/gem_command.rb
56
59
  - lib/gem/release/support/registry.rb