bumpit 0.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 +7 -0
- data/exe/bumpit +40 -0
- data/lib/bumpit/managers/base.rb +53 -0
- data/lib/bumpit/managers/bundler.rb +102 -0
- data/lib/bumpit/managers/yarn.rb +71 -0
- data/lib/bumpit/managers.rb +10 -0
- data/lib/bumpit/version.rb +5 -0
- data/lib/bumpit.rb +101 -0
- metadata +78 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 694d73b95855e15d8cb8cbb1a1875dfcff628a7ca89d00cd9b824797df4a7e7b
|
|
4
|
+
data.tar.gz: 1e61d9c60c989436b2dd6990e6a49ffedc418613254e661d192d9870eaae4c3c
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: b8d873aede2f02470a26806390a24cd1316d3d1150b567ba9b5c9acf85e69a2f3ef3477ceac00137a1ea1c17da9f25018f1e4c8cf0ef48d29cf3103b8f286fda
|
|
7
|
+
data.tar.gz: e04b18b5cf89a647f1a3e1433bd3a16f5725fc80af659b9e7699e75b7de7845624b30cba8269f28f53d148a888dcfad8eb45a8f283eb9ea4a71c07866d7015e7
|
data/exe/bumpit
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
|
|
5
|
+
require "bumpit"
|
|
6
|
+
require "optparse"
|
|
7
|
+
|
|
8
|
+
options = {}
|
|
9
|
+
|
|
10
|
+
OptionParser.new do |parser|
|
|
11
|
+
parser.on("-c", "--commit", "Output a commit message.") do |commit|
|
|
12
|
+
options[:commit] = commit
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
parser.on("-h", "--help", "Prints this help message.") do
|
|
16
|
+
puts <<~HELP
|
|
17
|
+
USAGE
|
|
18
|
+
$ bumpit [options]
|
|
19
|
+
|
|
20
|
+
OPTIONS
|
|
21
|
+
#{parser.summarize.join.strip}
|
|
22
|
+
|
|
23
|
+
EXAMPLES
|
|
24
|
+
$ bumpit --commit --pristine --verify="bundle exec rake && yarn test"
|
|
25
|
+
|
|
26
|
+
HELP
|
|
27
|
+
|
|
28
|
+
exit
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
parser.on("-p", "--pristine", "Don't bump if not in a clean state.") do |pristine|
|
|
32
|
+
options[:pristine] = pristine
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
parser.on("--verify [COMMAND]", String, "Run a command to verify changes.") do |verify|
|
|
36
|
+
options[:verify] = verify
|
|
37
|
+
end
|
|
38
|
+
end.parse!
|
|
39
|
+
|
|
40
|
+
Bumpit.new(**options).call
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler"
|
|
4
|
+
|
|
5
|
+
# :nocov:
|
|
6
|
+
class Bumpit
|
|
7
|
+
module Managers
|
|
8
|
+
class Base
|
|
9
|
+
# Return if an executable exists or not.
|
|
10
|
+
#
|
|
11
|
+
# @return [Boolean]
|
|
12
|
+
def self.executable?(executable)
|
|
13
|
+
!::Bundler.which(executable).nil?
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
protected
|
|
17
|
+
|
|
18
|
+
# Silence the output of the provided block.
|
|
19
|
+
#
|
|
20
|
+
# @param block [Block] The block to silence output for.
|
|
21
|
+
# @return [void]
|
|
22
|
+
def silence_output(&)
|
|
23
|
+
original_stdout = $stdout.clone
|
|
24
|
+
original_stderr = $stderr.clone
|
|
25
|
+
|
|
26
|
+
$stdout = $stderr = File.new(File::NULL, "w")
|
|
27
|
+
|
|
28
|
+
yield
|
|
29
|
+
ensure
|
|
30
|
+
$stdout = original_stdout
|
|
31
|
+
$stderr = original_stderr
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Convert an array to a sentence.
|
|
35
|
+
#
|
|
36
|
+
# @param [Array] array The array to convert to a sentence.
|
|
37
|
+
# @return [String]
|
|
38
|
+
def to_sentence(array)
|
|
39
|
+
case array.length
|
|
40
|
+
when 0
|
|
41
|
+
+""
|
|
42
|
+
when 1
|
|
43
|
+
array.first
|
|
44
|
+
when 2
|
|
45
|
+
"#{array[0]} and #{array[1]}"
|
|
46
|
+
else
|
|
47
|
+
"#{array[0...-1].join(", ")}, and #{array[-1]}"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
# :nocov:
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler/cli/update"
|
|
4
|
+
require "pathname"
|
|
5
|
+
|
|
6
|
+
class Bumpit
|
|
7
|
+
module Managers
|
|
8
|
+
class Bundler < Base
|
|
9
|
+
DEPENDENCY_MATCH = /gem "([^"]+)"/
|
|
10
|
+
FILENAMES = %w(Gemfile Gemfile.lock).freeze
|
|
11
|
+
OUTDATED_COMMAND = "bundle outdated --only-explicit --parseable 2>/dev/null"
|
|
12
|
+
OUTDATED_MATCHER = /\A(.+) \(newest (.+), installed (.+), requested = (.+)\)\z/
|
|
13
|
+
|
|
14
|
+
# Determine if the manager is valid.
|
|
15
|
+
#
|
|
16
|
+
# @return [Boolean]
|
|
17
|
+
def self.valid?
|
|
18
|
+
executable?("bundle") &&
|
|
19
|
+
FILENAMES.all? do |filename|
|
|
20
|
+
File.exist?(Pathname.new(Dir.pwd).join(filename))
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Bump the dependencies, if there are any.
|
|
25
|
+
#
|
|
26
|
+
# @return [void]
|
|
27
|
+
def bump
|
|
28
|
+
if outdated.any?
|
|
29
|
+
write_contents
|
|
30
|
+
bundler_update
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Return a message for which dependencies were bumped.
|
|
35
|
+
#
|
|
36
|
+
# @return [String]
|
|
37
|
+
def message
|
|
38
|
+
if outdated.any?
|
|
39
|
+
"Updates #{to_sentence(outdated.keys.sort)} in Ruby."
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
# Reset the existing cache and settings and run update for Bundler.
|
|
46
|
+
#
|
|
47
|
+
# @return [void]
|
|
48
|
+
def bundler_update
|
|
49
|
+
silence_output do
|
|
50
|
+
::Bundler.clear_gemspec_cache
|
|
51
|
+
::Bundler.reset!
|
|
52
|
+
::Bundler.reset_settings_and_root!
|
|
53
|
+
|
|
54
|
+
::Bundler::CLI::Update.new({ all: true }, []).run
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Return the contents of the Gemfile.
|
|
59
|
+
#
|
|
60
|
+
# @return [String] The contents of the Gemfile.
|
|
61
|
+
def contents
|
|
62
|
+
@contents ||= File.read("Gemfile")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Return the modified contents of the Gemfile.
|
|
66
|
+
#
|
|
67
|
+
# @return [Array]
|
|
68
|
+
def modified_contents
|
|
69
|
+
contents.split("\n").map do |line|
|
|
70
|
+
_, name = line.match(DEPENDENCY_MATCH).to_a
|
|
71
|
+
dependency = outdated[name]
|
|
72
|
+
|
|
73
|
+
if dependency
|
|
74
|
+
line.gsub(dependency[:current], dependency[:latest])
|
|
75
|
+
else
|
|
76
|
+
line
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Return the outdated dependencies.
|
|
82
|
+
#
|
|
83
|
+
# @return [Hash]
|
|
84
|
+
def outdated
|
|
85
|
+
@outdated ||= `#{OUTDATED_COMMAND}`.split("\n").each.with_object({}) do |dependency, result|
|
|
86
|
+
if dependency.match(OUTDATED_MATCHER)
|
|
87
|
+
_, name, latest, _, current = dependency.match(OUTDATED_MATCHER).to_a
|
|
88
|
+
|
|
89
|
+
result[name] = { current: current, latest: latest }
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Write the file with the bumped dependencies.
|
|
95
|
+
#
|
|
96
|
+
# @return [void]
|
|
97
|
+
def write_contents
|
|
98
|
+
File.write("Gemfile", "#{modified_contents.join("\n")}\n")
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "pathname"
|
|
5
|
+
|
|
6
|
+
class Bumpit
|
|
7
|
+
module Managers
|
|
8
|
+
class Yarn < Base
|
|
9
|
+
FILENAMES = %w(package.json yarn.lock).freeze
|
|
10
|
+
OUTDATED_COMMAND = "npm outdated --json"
|
|
11
|
+
|
|
12
|
+
# Determine if the manager is valid.
|
|
13
|
+
#
|
|
14
|
+
# @return [Boolean]
|
|
15
|
+
def self.valid?
|
|
16
|
+
executable?("npm") &&
|
|
17
|
+
executable?("yarn") &&
|
|
18
|
+
FILENAMES.all? do |filename|
|
|
19
|
+
File.exist?(Pathname.new(Dir.pwd).join(filename))
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Bump the dependencies, if there are any.
|
|
24
|
+
#
|
|
25
|
+
# @return [void]
|
|
26
|
+
def bump
|
|
27
|
+
if outdated.any?
|
|
28
|
+
package_update
|
|
29
|
+
yarn_update
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Return a message for which dependencies were bumped.
|
|
34
|
+
#
|
|
35
|
+
# @return [String]
|
|
36
|
+
def message
|
|
37
|
+
if outdated.any?
|
|
38
|
+
"Updates #{to_sentence(outdated.keys.sort)} in JavaScript."
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
# Update the package.json dependencies.
|
|
45
|
+
#
|
|
46
|
+
# @return [void]
|
|
47
|
+
def package_update
|
|
48
|
+
`yarn up --exact "*"`
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Return the outdated dependencies.
|
|
52
|
+
#
|
|
53
|
+
# @return [Hash]
|
|
54
|
+
def outdated
|
|
55
|
+
@outdated ||= JSON.parse(`#{OUTDATED_COMMAND}`)
|
|
56
|
+
.each
|
|
57
|
+
.with_object({}) do |(name, details), result|
|
|
58
|
+
result[name] = { current: details["current"], latest: details["latest"] }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Update all Yarn dependencies.
|
|
63
|
+
#
|
|
64
|
+
# @return [void]
|
|
65
|
+
def yarn_update
|
|
66
|
+
`rm yarn.lock`
|
|
67
|
+
`yarn`
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
data/lib/bumpit.rb
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "english"
|
|
4
|
+
|
|
5
|
+
require_relative "bumpit/managers"
|
|
6
|
+
require_relative "bumpit/version"
|
|
7
|
+
|
|
8
|
+
class Bumpit
|
|
9
|
+
WORD_WRAP_MATCHER = /(.{1,78})(?:[^\S\n]+\n?|\n*\Z|\n)|\n/
|
|
10
|
+
WORD_WRAP_PREFIX = "* "
|
|
11
|
+
|
|
12
|
+
# Initialize an instance.
|
|
13
|
+
#
|
|
14
|
+
# @param commit [Boolean] Whether or not to commit the changes.
|
|
15
|
+
# @param pristine [Boolean] Whether or not to require a pristine directory.
|
|
16
|
+
# @param verify [String] Optional command to verify the changes.
|
|
17
|
+
# @return [void]
|
|
18
|
+
def initialize(commit: false, pristine: false, verify: nil)
|
|
19
|
+
@commit = commit
|
|
20
|
+
@pristine = pristine
|
|
21
|
+
@verify = verify
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Bump it!
|
|
25
|
+
#
|
|
26
|
+
# @return [void]
|
|
27
|
+
def call
|
|
28
|
+
ensure_pristine!
|
|
29
|
+
bump!
|
|
30
|
+
verify!
|
|
31
|
+
commit!
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
attr_reader :commit, :pristine, :verify
|
|
37
|
+
|
|
38
|
+
# Find valid dependency managers and bump their dependencies.
|
|
39
|
+
#
|
|
40
|
+
# @return [void]
|
|
41
|
+
def bump!
|
|
42
|
+
managers.each(&:bump)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Print a commit message, if requested and messages are present.
|
|
46
|
+
#
|
|
47
|
+
# @return [void]
|
|
48
|
+
def commit!
|
|
49
|
+
if commit
|
|
50
|
+
messages = managers.filter_map(&:message).flatten
|
|
51
|
+
|
|
52
|
+
if messages.any?
|
|
53
|
+
puts "Update dependencies.\n\n"
|
|
54
|
+
puts(messages.map { |message| word_wrap(message) })
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Ensure the working directory is pristine, if requested.
|
|
60
|
+
#
|
|
61
|
+
# @return [void]
|
|
62
|
+
def ensure_pristine!
|
|
63
|
+
if pristine && `git status --porcelain`.strip != ""
|
|
64
|
+
warn "Working directory must be pristine to run."
|
|
65
|
+
exit 1
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Return instances of valid managers.
|
|
70
|
+
#
|
|
71
|
+
# @return [Array]
|
|
72
|
+
def managers
|
|
73
|
+
@managers ||= [
|
|
74
|
+
Managers::Bundler,
|
|
75
|
+
Managers::Yarn
|
|
76
|
+
].select(&:valid?).map(&:new)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Verify the changes via a system command, if requested.
|
|
80
|
+
#
|
|
81
|
+
# @return [void]
|
|
82
|
+
def verify!
|
|
83
|
+
if verify
|
|
84
|
+
system(verify)
|
|
85
|
+
|
|
86
|
+
unless $CHILD_STATUS.success?
|
|
87
|
+
warn "The `#{verify}` verification command failed."
|
|
88
|
+
|
|
89
|
+
exit $CHILD_STATUS.exitstatus
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Wrap text to fit within 80 characters.
|
|
95
|
+
#
|
|
96
|
+
# @param [String] text The text to wrap.
|
|
97
|
+
# @return [String] The wrapped text.
|
|
98
|
+
def word_wrap(text)
|
|
99
|
+
WORD_WRAP_PREFIX + text.gsub(WORD_WRAP_MATCHER, "\\1\n#{" " * WORD_WRAP_PREFIX.size}").strip
|
|
100
|
+
end
|
|
101
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: bumpit
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Tristan Dunn
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: bundler
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '2.6'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '2.6'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: json
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '2.10'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '2.10'
|
|
40
|
+
description: Automatically bump dependencies in multiple package managers.
|
|
41
|
+
email: hello@tristandunn.com
|
|
42
|
+
executables:
|
|
43
|
+
- bumpit
|
|
44
|
+
extensions: []
|
|
45
|
+
extra_rdoc_files: []
|
|
46
|
+
files:
|
|
47
|
+
- exe/bumpit
|
|
48
|
+
- lib/bumpit.rb
|
|
49
|
+
- lib/bumpit/managers.rb
|
|
50
|
+
- lib/bumpit/managers/base.rb
|
|
51
|
+
- lib/bumpit/managers/bundler.rb
|
|
52
|
+
- lib/bumpit/managers/yarn.rb
|
|
53
|
+
- lib/bumpit/version.rb
|
|
54
|
+
homepage: https://github.com/tristandunn/bumpit
|
|
55
|
+
licenses:
|
|
56
|
+
- MIT
|
|
57
|
+
metadata:
|
|
58
|
+
bug_tracker_uri: https://github.com/tristandunn/bumpit/issues
|
|
59
|
+
changelog_uri: https://github.com/tristandunn/bumpit/blob/main/CHANGELOG.md
|
|
60
|
+
rubygems_mfa_required: 'true'
|
|
61
|
+
rdoc_options: []
|
|
62
|
+
require_paths:
|
|
63
|
+
- lib
|
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '3.4'
|
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - ">="
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '0'
|
|
74
|
+
requirements: []
|
|
75
|
+
rubygems_version: 3.6.7
|
|
76
|
+
specification_version: 4
|
|
77
|
+
summary: Automatically bump dependencies in multiple package managers.
|
|
78
|
+
test_files: []
|