captive-release 0.9.0 → 0.11.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/lib/captive_release/cli.rb +13 -4
- data/lib/captive_release/github_http.rb +11 -7
- data/lib/captive_release/locales/en.yml +5 -2
- data/lib/captive_release/locales/fr.yml +5 -2
- data/lib/captive_release/prerelease_iteration.rb +19 -0
- data/lib/captive_release/update_check.rb +43 -0
- data/lib/captive_release/version.rb +1 -1
- data/lib/captive_release/version_bumper.rb +2 -0
- data/lib/captive_release/version_choice.rb +3 -3
- data/lib/captive_release.rb +2 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 90b817eaab2a7cab41857f499ee8cac77d460bbf073f9074016b96621a5df027
|
|
4
|
+
data.tar.gz: b66c7485162d298b516b2dfb8e6e90bc7ae13d2a88fa59ca12254dacbadea8a4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9c75bc8285c685ef3c2b2969de5259e1078ccb45f76849f503177c1891352ab38b9705125c4a9787681c931540d7fe3187dc92f1c0184a71e1876ee380659675
|
|
7
|
+
data.tar.gz: 4fb8ee0668d2b2848817ba8a4eccaf45f38dec0dd216eaf410e08ef7373edfcef20d7cd7c76563bbdef2629240ec0e1b9e54a18962bd2383307b0eb3551b100a
|
data/lib/captive_release/cli.rb
CHANGED
|
@@ -8,11 +8,22 @@ module CaptiveRelease
|
|
|
8
8
|
new(argv.dup).run
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
def initialize(argv)
|
|
12
|
-
@options
|
|
11
|
+
def initialize(argv, update_check: UpdateCheck.new)
|
|
12
|
+
@options = Options.new(argv)
|
|
13
|
+
@update_check = update_check
|
|
13
14
|
end
|
|
14
15
|
|
|
16
|
+
# Le verdict de mise à jour s'affiche après une commande menée à terme ; une commande
|
|
17
|
+
# inconnue sort avant (exit 1) et n'en a pas.
|
|
15
18
|
def run
|
|
19
|
+
@update_check.start
|
|
20
|
+
dispatch
|
|
21
|
+
@update_check.report
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def dispatch
|
|
16
27
|
command = @options.next_argument
|
|
17
28
|
|
|
18
29
|
case command
|
|
@@ -25,8 +36,6 @@ module CaptiveRelease
|
|
|
25
36
|
end
|
|
26
37
|
end
|
|
27
38
|
|
|
28
|
-
private
|
|
29
|
-
|
|
30
39
|
def run_init
|
|
31
40
|
InitCommand.new(terminal: terminal).run(@options.value("--files"))
|
|
32
41
|
end
|
|
@@ -4,7 +4,7 @@ require "net/http"
|
|
|
4
4
|
require "uri"
|
|
5
5
|
|
|
6
6
|
module CaptiveRelease
|
|
7
|
-
# Le transport : poster sur l'API GitHub, authentifié, en suivant les redirections qu'elle
|
|
7
|
+
# Le transport : lire et poster sur l'API GitHub, authentifié, en suivant les redirections qu'elle
|
|
8
8
|
# sert quand un dépôt a été renommé. Elle ne sait rien de ce qui est posté ni de ce qui
|
|
9
9
|
# compte comme un échec, qui appartiennent à GithubApi.
|
|
10
10
|
class GithubHttp
|
|
@@ -20,9 +20,17 @@ module CaptiveRelease
|
|
|
20
20
|
@token = token
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
+
def get(uri) = suivre(uri) { |cible| Net::HTTP::Get.new(cible.path) }
|
|
24
|
+
|
|
23
25
|
def post(uri, corps)
|
|
26
|
+
suivre(uri) { |cible| Net::HTTP::Post.new(cible.path).tap { |requete| requete.body = corps } }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def suivre(uri)
|
|
24
32
|
MAX_REDIRECTIONS.times do
|
|
25
|
-
reponse = envoyer(uri,
|
|
33
|
+
reponse = envoyer(uri, yield(uri))
|
|
26
34
|
return reponse unless REDIRECTIONS.include?(reponse.code)
|
|
27
35
|
|
|
28
36
|
uri = URI(ailleurs!(reponse))
|
|
@@ -31,15 +39,11 @@ module CaptiveRelease
|
|
|
31
39
|
raise Messages.t(:too_many_redirects)
|
|
32
40
|
end
|
|
33
41
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def envoyer(uri, corps)
|
|
42
|
+
def envoyer(uri, requete)
|
|
37
43
|
http = Net::HTTP.new(uri.host, uri.port)
|
|
38
44
|
http.use_ssl = true
|
|
39
|
-
requete = Net::HTTP::Post.new(uri.path)
|
|
40
45
|
EN_TETES.each { |nom, valeur| requete[nom] = valeur }
|
|
41
46
|
requete["Authorization"] = "token #{@token}"
|
|
42
|
-
requete.body = corps
|
|
43
47
|
http.request(requete)
|
|
44
48
|
end
|
|
45
49
|
|
|
@@ -5,7 +5,7 @@ en:
|
|
|
5
5
|
|
|
6
6
|
Usage:
|
|
7
7
|
captive-release init [--files path[:type],...]
|
|
8
|
-
captive-release new [patch|minor|major|promote|x.y.z] [--yes]
|
|
8
|
+
captive-release new [patch|minor|major|promote|pre|x.y.z] [--yes]
|
|
9
9
|
captive-release build [--profile staging|production]
|
|
10
10
|
captive-release version
|
|
11
11
|
|
|
@@ -41,6 +41,7 @@ en:
|
|
|
41
41
|
'no': 'No'
|
|
42
42
|
invalid_choice: Invalid choice.
|
|
43
43
|
unknown_command: 'Unknown command: %{command}'
|
|
44
|
+
update_available: 'A new version of captive-release is available: %{current} → %{latest}. Run: brew upgrade captive-release'
|
|
44
45
|
scanning: Scanning for version files...
|
|
45
46
|
no_version_files_found: No version files found (package.json, VERSION).
|
|
46
47
|
no_files_selected: No files selected.
|
|
@@ -85,11 +86,13 @@ en:
|
|
|
85
86
|
bump_patch: Patch
|
|
86
87
|
bump_minor: Minor
|
|
87
88
|
bump_major: Major
|
|
89
|
+
bump_pre: Iterate
|
|
90
|
+
nothing_to_iterate: 'No pre-release to iterate: enter x.y.z-alpha.1'
|
|
88
91
|
bump_promote: Promote
|
|
89
92
|
bump_from_prerelease: 'Cannot %{type} from a pre-release: promote it or enter a version.'
|
|
90
93
|
prerelease_on_app: 'Cannot release pre-release %{version}: %{path} carries an app version, which allows no suffix.'
|
|
91
94
|
enter_version: 'Enter version (x.y.z or x.y.z-alpha.1): '
|
|
92
|
-
invalid_bump_type: 'Invalid bump type: %{type}. Use patch|minor|major|x.y.z'
|
|
95
|
+
invalid_bump_type: 'Invalid bump type: %{type}. Use patch|minor|major|promote|pre|x.y.z'
|
|
93
96
|
invalid_semver: 'Invalid semver: %{value}'
|
|
94
97
|
invalid_version: 'Invalid version: %{value}'
|
|
95
98
|
bump_warning: "⚠️ Commits suggest a %{suggestion} bump, but the chosen version is only a %{chosen}."
|
|
@@ -5,7 +5,7 @@ fr:
|
|
|
5
5
|
|
|
6
6
|
Utilisation :
|
|
7
7
|
captive-release init [--files path[:type],...]
|
|
8
|
-
captive-release new [patch|minor|major|promote|x.y.z] [--yes]
|
|
8
|
+
captive-release new [patch|minor|major|promote|pre|x.y.z] [--yes]
|
|
9
9
|
captive-release build [--profile staging|production]
|
|
10
10
|
captive-release version
|
|
11
11
|
|
|
@@ -41,6 +41,7 @@ fr:
|
|
|
41
41
|
'no': Non
|
|
42
42
|
invalid_choice: Choix invalide.
|
|
43
43
|
unknown_command: 'Commande inconnue : %{command}'
|
|
44
|
+
update_available: 'Une nouvelle version de captive-release est disponible : %{current} → %{latest}. Lancez : brew upgrade captive-release'
|
|
44
45
|
scanning: Recherche des fichiers de version...
|
|
45
46
|
no_version_files_found: Aucun fichier de version trouvé (package.json, VERSION).
|
|
46
47
|
no_files_selected: Aucun fichier sélectionné.
|
|
@@ -85,11 +86,13 @@ fr:
|
|
|
85
86
|
bump_patch: Patch
|
|
86
87
|
bump_minor: Minor
|
|
87
88
|
bump_major: Major
|
|
89
|
+
bump_pre: Itérer
|
|
90
|
+
nothing_to_iterate: 'Pas de pré-release à itérer : saisissez x.y.z-alpha.1'
|
|
88
91
|
bump_promote: Promouvoir
|
|
89
92
|
bump_from_prerelease: 'Impossible de faire un %{type} depuis une pré-release : promouvez-la ou saisissez une version.'
|
|
90
93
|
prerelease_on_app: "Pré-release %{version} impossible : %{path} porte une version d'app, qui n'admet pas de suffixe."
|
|
91
94
|
enter_version: 'Saisissez la version (x.y.z ou x.y.z-alpha.1) : '
|
|
92
|
-
invalid_bump_type: 'Type de bump invalide : %{type}. Utilisez patch|minor|major|x.y.z'
|
|
95
|
+
invalid_bump_type: 'Type de bump invalide : %{type}. Utilisez patch|minor|major|promote|pre|x.y.z'
|
|
93
96
|
invalid_semver: 'Semver invalide : %{value}'
|
|
94
97
|
invalid_version: 'Version invalide : %{value}'
|
|
95
98
|
bump_warning: "⚠️ Les commits suggèrent un bump %{suggestion}, mais la version choisie n'est qu'un %{chosen}."
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module CaptiveRelease
|
|
4
|
+
# L'itération d'une pré-release : même canal, dernier identifiant + 1 ; sans numéro final,
|
|
5
|
+
# on en ouvre un (.1). Changer de canal (alpha → beta) reste une saisie manuelle.
|
|
6
|
+
#
|
|
7
|
+
# Cette unité change quand la règle d'itération change, VersionBumper quand les types de
|
|
8
|
+
# bump changent.
|
|
9
|
+
module PrereleaseIteration
|
|
10
|
+
def self.next(version)
|
|
11
|
+
raise ArgumentError, Messages.t(:nothing_to_iterate) unless Semver.prerelease?(version)
|
|
12
|
+
|
|
13
|
+
dernier = version[/\d+\z/]
|
|
14
|
+
return "#{version}.1" unless dernier && version.match?(/[.-]\d+\z/)
|
|
15
|
+
|
|
16
|
+
version.delete_suffix(dernier) + (dernier.to_i + 1).to_s
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
5
|
+
module CaptiveRelease
|
|
6
|
+
# Signale qu'une version plus récente est publiée, à la manière de Scalingo CLI : la requête
|
|
7
|
+
# part au démarrage dans un thread, le verdict s'affiche après la commande. Le dépôt est
|
|
8
|
+
# privé, d'où le jeton ; sans jeton, pas de vérification.
|
|
9
|
+
#
|
|
10
|
+
# Cette unité change quand la source de la dernière version change. Toute erreur est muette :
|
|
11
|
+
# un réseau absent ne doit jamais gêner une release. L'attente est bornée par le join, pas
|
|
12
|
+
# par la requête : un thread encore en vol meurt avec le process.
|
|
13
|
+
class UpdateCheck
|
|
14
|
+
LATEST = URI("https://api.github.com/repos/captive-studio/captive-release/releases/latest")
|
|
15
|
+
ATTENTE = 2
|
|
16
|
+
DESACTIVE = "CAPTIVE_RELEASE_DISABLE_UPDATE_CHECKER"
|
|
17
|
+
|
|
18
|
+
def initialize(output: $stderr, token_provider: GithubToken.method(:call))
|
|
19
|
+
@output = output
|
|
20
|
+
@token_provider = token_provider
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def start
|
|
24
|
+
@thread = Thread.new { derniere_version rescue nil } unless ENV[DESACTIVE] # rubocop:disable Style/RescueModifier
|
|
25
|
+
self
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def report(courante = VERSION)
|
|
29
|
+
derniere = @thread&.join(ATTENTE)&.value
|
|
30
|
+
return unless derniere && Gem::Version.new(derniere) > Gem::Version.new(courante)
|
|
31
|
+
|
|
32
|
+
@output.puts "\e[31m#{Messages.t(:update_available, current: courante, latest: derniere)}\e[0m"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def derniere_version
|
|
38
|
+
token = @token_provider.call or return
|
|
39
|
+
reponse = GithubHttp.new(token: token).get(LATEST)
|
|
40
|
+
JSON.parse(reponse.body).fetch("tag_name").delete_prefix("v") if reponse.is_a?(Net::HTTPSuccess)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -4,6 +4,7 @@ module CaptiveRelease
|
|
|
4
4
|
class VersionBumper
|
|
5
5
|
BUMP_TYPES = %w[patch minor major].freeze
|
|
6
6
|
PROMOTE = "promote"
|
|
7
|
+
ITERATE = "pre"
|
|
7
8
|
|
|
8
9
|
def self.bump(current, type)
|
|
9
10
|
new(current).bump(type)
|
|
@@ -25,6 +26,7 @@ module CaptiveRelease
|
|
|
25
26
|
when "minor" then "#{@major}.#{@minor + 1}.0"
|
|
26
27
|
when "patch" then "#{@major}.#{@minor}.#{@patch + 1}"
|
|
27
28
|
when PROMOTE then promouvoir
|
|
29
|
+
when ITERATE then PrereleaseIteration.next(@current)
|
|
28
30
|
else saisie(type)
|
|
29
31
|
end
|
|
30
32
|
end
|
|
@@ -7,7 +7,7 @@ module CaptiveRelease
|
|
|
7
7
|
# Cette unité change quand les façons de nommer une version changent, ReleaseCommand quand
|
|
8
8
|
# le geste de release change.
|
|
9
9
|
class VersionChoice
|
|
10
|
-
BUMP_TYPES = (VersionBumper::BUMP_TYPES + [ VersionBumper::PROMOTE ]).freeze
|
|
10
|
+
BUMP_TYPES = (VersionBumper::BUMP_TYPES + [ VersionBumper::PROMOTE, VersionBumper::ITERATE ]).freeze
|
|
11
11
|
CUSTOM = "Custom"
|
|
12
12
|
|
|
13
13
|
def initialize(terminal:)
|
|
@@ -32,10 +32,10 @@ module CaptiveRelease
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
# La valeur rendue est la version elle-même, sauf pour Custom qui n'en a pas encore une.
|
|
35
|
-
# Depuis une pré-release,
|
|
35
|
+
# Depuis une pré-release, seules l'itération et la promotion sont proposées : patch, minor et major y
|
|
36
36
|
# prêteraient à confusion.
|
|
37
37
|
def candidates_for(current)
|
|
38
|
-
types = Semver.prerelease?(current) ? [ VersionBumper::PROMOTE ] : VersionBumper::BUMP_TYPES
|
|
38
|
+
types = Semver.prerelease?(current) ? [ VersionBumper::ITERATE, VersionBumper::PROMOTE ] : VersionBumper::BUMP_TYPES
|
|
39
39
|
candidats = types.to_h do |type|
|
|
40
40
|
version = VersionBumper.bump(current, type)
|
|
41
41
|
[ "#{Messages.t(:"bump_#{type}")} → #{@terminal.bold(version)}", version ]
|
data/lib/captive_release.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require_relative "captive_release/version"
|
|
4
4
|
require_relative "captive_release/messages"
|
|
5
5
|
require_relative "captive_release/semver"
|
|
6
|
+
require_relative "captive_release/prerelease_iteration"
|
|
6
7
|
require_relative "captive_release/version_bumper"
|
|
7
8
|
require_relative "captive_release/ruby_gems_version"
|
|
8
9
|
require_relative "captive_release/version_format"
|
|
@@ -50,6 +51,7 @@ require_relative "captive_release/release_preconditions"
|
|
|
50
51
|
require_relative "captive_release/release_overview"
|
|
51
52
|
require_relative "captive_release/release_confirmation"
|
|
52
53
|
require_relative "captive_release/release_command"
|
|
54
|
+
require_relative "captive_release/update_check"
|
|
53
55
|
require_relative "captive_release/help"
|
|
54
56
|
require_relative "captive_release/cli"
|
|
55
57
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: captive-release
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Captive Studio
|
|
@@ -55,6 +55,7 @@ files:
|
|
|
55
55
|
- lib/captive_release/messages.rb
|
|
56
56
|
- lib/captive_release/options.rb
|
|
57
57
|
- lib/captive_release/prerelease_guard.rb
|
|
58
|
+
- lib/captive_release/prerelease_iteration.rb
|
|
58
59
|
- lib/captive_release/release_command.rb
|
|
59
60
|
- lib/captive_release/release_confirmation.rb
|
|
60
61
|
- lib/captive_release/release_overview.rb
|
|
@@ -65,6 +66,7 @@ files:
|
|
|
65
66
|
- lib/captive_release/semver.rb
|
|
66
67
|
- lib/captive_release/shell.rb
|
|
67
68
|
- lib/captive_release/terminal.rb
|
|
69
|
+
- lib/captive_release/update_check.rb
|
|
68
70
|
- lib/captive_release/version.rb
|
|
69
71
|
- lib/captive_release/version_bumper.rb
|
|
70
72
|
- lib/captive_release/version_choice.rb
|
|
@@ -94,7 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
94
96
|
- !ruby/object:Gem::Version
|
|
95
97
|
version: '0'
|
|
96
98
|
requirements: []
|
|
97
|
-
rubygems_version: 4.0.
|
|
99
|
+
rubygems_version: 4.0.20
|
|
98
100
|
specification_version: 4
|
|
99
101
|
summary: CLI de release semver pour projets Captive
|
|
100
102
|
test_files: []
|