modulesync 1.2.0 → 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 +4 -4
- data/.config/cucumber.yml +1 -0
- data/.github/workflows/ci.yml +29 -0
- data/.github/workflows/release.yml +30 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +8 -1
- data/.rubocop_todo.yml +16 -35
- data/CHANGELOG.md +82 -1
- data/Gemfile +5 -1
- data/HISTORY.md +227 -0
- data/README.md +29 -6
- data/Rakefile +24 -0
- data/features/cli.feature +14 -6
- data/features/hook.feature +3 -5
- data/features/step_definitions/git_steps.rb +73 -35
- data/features/support/env.rb +4 -0
- data/features/update.feature +163 -341
- data/features/update/bad_context.feature +26 -0
- data/features/update/bump_version.feature +87 -0
- data/lib/modulesync.rb +92 -51
- data/lib/modulesync/cli.rb +10 -4
- data/lib/modulesync/cli/thor.rb +24 -0
- data/lib/modulesync/pr/github.rb +25 -9
- data/lib/modulesync/pr/gitlab.rb +27 -13
- data/lib/modulesync/puppet_module.rb +37 -0
- data/lib/modulesync/repository.rb +158 -0
- data/lib/modulesync/source_code.rb +57 -0
- data/lib/modulesync/util.rb +4 -1
- data/lib/monkey_patches.rb +9 -48
- data/modulesync.gemspec +4 -4
- data/spec/helpers/faker.rb +14 -0
- data/spec/helpers/faker/puppet_module_remote_repo.rb +146 -0
- data/spec/unit/modulesync_spec.rb +7 -3
- metadata +30 -10
- data/.travis.yml +0 -27
- data/lib/modulesync/git.rb +0 -194
@@ -5,17 +5,21 @@ describe ModuleSync do
|
|
5
5
|
it 'loads the managed modules from the specified :managed_modules_conf' do
|
6
6
|
allow(ModuleSync).to receive(:find_template_files).and_return([])
|
7
7
|
allow(ModuleSync::Util).to receive(:parse_config).with('./config_defaults.yml').and_return({})
|
8
|
-
expect(ModuleSync).to receive(:managed_modules).with(
|
8
|
+
expect(ModuleSync).to receive(:managed_modules).with(no_args).and_return([])
|
9
9
|
|
10
10
|
options = { managed_modules_conf: 'test_file.yml' }
|
11
11
|
ModuleSync.update(options)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
context '::
|
15
|
+
context '::pr' do
|
16
16
|
describe "Raise Error" do
|
17
|
+
let(:puppet_module) do
|
18
|
+
ModuleSync::PuppetModule.new 'puppet-test', remote: 'dummy'
|
19
|
+
end
|
20
|
+
|
17
21
|
it 'raises an error when neither GITHUB_TOKEN nor GITLAB_TOKEN are set for PRs' do
|
18
|
-
expect { ModuleSync.
|
22
|
+
expect { ModuleSync.pr(puppet_module) }.to raise_error(RuntimeError).and output(/No GitHub or GitLab token specified for --pr/).to_stderr
|
19
23
|
end
|
20
24
|
end
|
21
25
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: modulesync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vox Pupuli
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-06-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aruba
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '1.
|
89
|
+
version: '1.7'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '1.
|
96
|
+
version: '1.7'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: gitlab
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -126,16 +126,22 @@ dependencies:
|
|
126
126
|
name: puppet-blacksmith
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- - "
|
129
|
+
- - ">="
|
130
130
|
- !ruby/object:Gem::Version
|
131
131
|
version: '3.0'
|
132
|
+
- - "<"
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '7'
|
132
135
|
type: :runtime
|
133
136
|
prerelease: false
|
134
137
|
version_requirements: !ruby/object:Gem::Requirement
|
135
138
|
requirements:
|
136
|
-
- - "
|
139
|
+
- - ">="
|
137
140
|
- !ruby/object:Gem::Version
|
138
141
|
version: '3.0'
|
142
|
+
- - "<"
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '7'
|
139
145
|
- !ruby/object:Gem::Dependency
|
140
146
|
name: thor
|
141
147
|
requirement: !ruby/object:Gem::Requirement
|
@@ -158,13 +164,16 @@ executables:
|
|
158
164
|
extensions: []
|
159
165
|
extra_rdoc_files: []
|
160
166
|
files:
|
167
|
+
- ".config/cucumber.yml"
|
168
|
+
- ".github/workflows/ci.yml"
|
169
|
+
- ".github/workflows/release.yml"
|
161
170
|
- ".gitignore"
|
162
171
|
- ".rspec"
|
163
172
|
- ".rubocop.yml"
|
164
173
|
- ".rubocop_todo.yml"
|
165
|
-
- ".travis.yml"
|
166
174
|
- CHANGELOG.md
|
167
175
|
- Gemfile
|
176
|
+
- HISTORY.md
|
168
177
|
- LICENSE
|
169
178
|
- README.md
|
170
179
|
- Rakefile
|
@@ -175,18 +184,25 @@ files:
|
|
175
184
|
- features/step_definitions/git_steps.rb
|
176
185
|
- features/support/env.rb
|
177
186
|
- features/update.feature
|
187
|
+
- features/update/bad_context.feature
|
188
|
+
- features/update/bump_version.feature
|
178
189
|
- lib/modulesync.rb
|
179
190
|
- lib/modulesync/cli.rb
|
191
|
+
- lib/modulesync/cli/thor.rb
|
180
192
|
- lib/modulesync/constants.rb
|
181
|
-
- lib/modulesync/git.rb
|
182
193
|
- lib/modulesync/hook.rb
|
183
194
|
- lib/modulesync/pr/github.rb
|
184
195
|
- lib/modulesync/pr/gitlab.rb
|
196
|
+
- lib/modulesync/puppet_module.rb
|
185
197
|
- lib/modulesync/renderer.rb
|
198
|
+
- lib/modulesync/repository.rb
|
186
199
|
- lib/modulesync/settings.rb
|
200
|
+
- lib/modulesync/source_code.rb
|
187
201
|
- lib/modulesync/util.rb
|
188
202
|
- lib/monkey_patches.rb
|
189
203
|
- modulesync.gemspec
|
204
|
+
- spec/helpers/faker.rb
|
205
|
+
- spec/helpers/faker/puppet_module_remote_repo.rb
|
190
206
|
- spec/spec_helper.rb
|
191
207
|
- spec/unit/modulesync/pr/github_spec.rb
|
192
208
|
- spec/unit/modulesync/pr/gitlab_spec.rb
|
@@ -204,14 +220,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
204
220
|
requirements:
|
205
221
|
- - ">="
|
206
222
|
- !ruby/object:Gem::Version
|
207
|
-
version: 2.
|
223
|
+
version: 2.5.0
|
208
224
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
209
225
|
requirements:
|
210
226
|
- - ">="
|
211
227
|
- !ruby/object:Gem::Version
|
212
228
|
version: '0'
|
213
229
|
requirements: []
|
214
|
-
rubygems_version: 3.
|
230
|
+
rubygems_version: 3.2.15
|
215
231
|
signing_key:
|
216
232
|
specification_version: 4
|
217
233
|
summary: Puppet Module Synchronizer
|
@@ -221,6 +237,10 @@ test_files:
|
|
221
237
|
- features/step_definitions/git_steps.rb
|
222
238
|
- features/support/env.rb
|
223
239
|
- features/update.feature
|
240
|
+
- features/update/bad_context.feature
|
241
|
+
- features/update/bump_version.feature
|
242
|
+
- spec/helpers/faker.rb
|
243
|
+
- spec/helpers/faker/puppet_module_remote_repo.rb
|
224
244
|
- spec/spec_helper.rb
|
225
245
|
- spec/unit/modulesync/pr/github_spec.rb
|
226
246
|
- spec/unit/modulesync/pr/gitlab_spec.rb
|
data/.travis.yml
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
---
|
2
|
-
sudo: false
|
3
|
-
language: ruby
|
4
|
-
cache: bundler
|
5
|
-
dist: trusty
|
6
|
-
script: 'bundle exec rake test'
|
7
|
-
rvm:
|
8
|
-
- 2.0
|
9
|
-
- 2.1
|
10
|
-
- 2.2
|
11
|
-
- 2.3
|
12
|
-
- 2.4
|
13
|
-
- 2.5
|
14
|
-
- 2.6
|
15
|
-
- 2.7
|
16
|
-
notifications:
|
17
|
-
email: false
|
18
|
-
deploy:
|
19
|
-
provider: rubygems
|
20
|
-
api_key:
|
21
|
-
secure: "Tbf1EbLEobIIox+fftJZADZsfQQ6kl0urcMNetK7NJzFo/negD/WyJIUj3kro/B7buyYADEjTui/JR4o8EPbugfM3ie5vYOd5k3AesSzbdr4BSwGe/cGbGOB7/PZuGfFLkb94/FiCU2mIwibkbh1rHWGlBoPj7ntL0+5ZtdvsM4="
|
22
|
-
gem: modulesync
|
23
|
-
on:
|
24
|
-
rvm: 2.7
|
25
|
-
tags: true
|
26
|
-
all_branches: true
|
27
|
-
repo: voxpupuli/modulesync
|
data/lib/modulesync/git.rb
DELETED
@@ -1,194 +0,0 @@
|
|
1
|
-
require 'git'
|
2
|
-
require 'puppet_blacksmith'
|
3
|
-
|
4
|
-
module ModuleSync
|
5
|
-
module Git # rubocop:disable Metrics/ModuleLength
|
6
|
-
include Constants
|
7
|
-
|
8
|
-
def self.remote_branch_exists?(repo, branch)
|
9
|
-
repo.branches.remote.collect(&:name).include?(branch)
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.local_branch_exists?(repo, branch)
|
13
|
-
repo.branches.local.collect(&:name).include?(branch)
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.remote_branch_differ?(repo, local_branch, remote_branch)
|
17
|
-
!remote_branch_exists?(repo, remote_branch) ||
|
18
|
-
repo.diff("#{local_branch}..origin/#{remote_branch}").any?
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.default_branch(repo)
|
22
|
-
symbolic_ref = repo.branches.find { |b| b.full =~ %r{remotes/origin/HEAD} }
|
23
|
-
return unless symbolic_ref
|
24
|
-
%r{remotes/origin/HEAD\s+->\s+origin/(?<branch>.+?)$}.match(symbolic_ref.full)[:branch]
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.switch_branch(repo, branch)
|
28
|
-
unless branch
|
29
|
-
branch = default_branch(repo)
|
30
|
-
puts "Using repository's default branch: #{branch}"
|
31
|
-
end
|
32
|
-
return if repo.current_branch == branch
|
33
|
-
|
34
|
-
if local_branch_exists?(repo, branch)
|
35
|
-
puts "Switching to branch #{branch}"
|
36
|
-
repo.checkout(branch)
|
37
|
-
elsif remote_branch_exists?(repo, branch)
|
38
|
-
puts "Creating local branch #{branch} from origin/#{branch}"
|
39
|
-
repo.checkout("origin/#{branch}")
|
40
|
-
repo.branch(branch).checkout
|
41
|
-
else
|
42
|
-
repo.checkout('origin/master')
|
43
|
-
puts "Creating new branch #{branch}"
|
44
|
-
repo.branch(branch).checkout
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def self.pull(git_base, name, branch, project_root, opts)
|
49
|
-
puts "Syncing #{name}"
|
50
|
-
Dir.mkdir(project_root) unless Dir.exist?(project_root)
|
51
|
-
|
52
|
-
# Repo needs to be cloned in the cwd
|
53
|
-
if !Dir.exist?("#{project_root}/#{name}") || !Dir.exist?("#{project_root}/#{name}/.git")
|
54
|
-
puts 'Cloning repository fresh'
|
55
|
-
remote = opts[:remote] || (git_base.start_with?('file://') ? "#{git_base}#{name}" : "#{git_base}#{name}.git")
|
56
|
-
local = "#{project_root}/#{name}"
|
57
|
-
puts "Cloning from #{remote}"
|
58
|
-
repo = ::Git.clone(remote, local)
|
59
|
-
switch_branch(repo, branch)
|
60
|
-
# Repo already cloned, check out master and override local changes
|
61
|
-
else
|
62
|
-
# Some versions of git can't properly handle managing a repo from outside the repo directory
|
63
|
-
Dir.chdir("#{project_root}/#{name}") do
|
64
|
-
puts "Overriding any local changes to repositories in #{project_root}"
|
65
|
-
repo = ::Git.open('.')
|
66
|
-
repo.fetch
|
67
|
-
repo.reset_hard
|
68
|
-
switch_branch(repo, branch)
|
69
|
-
repo.pull('origin', branch) if remote_branch_exists?(repo, branch)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def self.update_changelog(repo, version, message, module_root)
|
75
|
-
changelog = "#{module_root}/CHANGELOG.md"
|
76
|
-
if File.exist?(changelog)
|
77
|
-
puts "Updating #{changelog} for version #{version}"
|
78
|
-
changes = File.readlines(changelog)
|
79
|
-
File.open(changelog, 'w') do |f|
|
80
|
-
date = Time.now.strftime('%Y-%m-%d')
|
81
|
-
f.puts "## #{date} - Release #{version}\n\n"
|
82
|
-
f.puts "#{message}\n\n"
|
83
|
-
# Add old lines again
|
84
|
-
f.puts changes
|
85
|
-
end
|
86
|
-
repo.add('CHANGELOG.md')
|
87
|
-
else
|
88
|
-
puts 'No CHANGELOG.md file found, not updating.'
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def self.bump(repo, m, message, module_root, changelog = false)
|
93
|
-
new = m.bump!
|
94
|
-
puts "Bumped to version #{new}"
|
95
|
-
repo.add('metadata.json')
|
96
|
-
update_changelog(repo, new, message, module_root) if changelog
|
97
|
-
repo.commit("Release version #{new}")
|
98
|
-
repo.push
|
99
|
-
new
|
100
|
-
end
|
101
|
-
|
102
|
-
def self.tag(repo, version, tag_pattern)
|
103
|
-
tag = tag_pattern % version
|
104
|
-
puts "Tagging with #{tag}"
|
105
|
-
repo.add_tag(tag)
|
106
|
-
repo.push('origin', tag)
|
107
|
-
end
|
108
|
-
|
109
|
-
def self.checkout_branch(repo, branch)
|
110
|
-
selected_branch = branch || repo.current_branch || 'master'
|
111
|
-
repo.branch(selected_branch).checkout
|
112
|
-
selected_branch
|
113
|
-
end
|
114
|
-
private_class_method :checkout_branch
|
115
|
-
|
116
|
-
# Git add/rm, git commit, git push
|
117
|
-
def self.update(name, files, options)
|
118
|
-
module_root = "#{options[:project_root]}/#{name}"
|
119
|
-
message = options[:message]
|
120
|
-
repo = ::Git.open(module_root)
|
121
|
-
branch = checkout_branch(repo, options[:branch])
|
122
|
-
files.each do |file|
|
123
|
-
if repo.status.deleted.include?(file)
|
124
|
-
repo.remove(file)
|
125
|
-
elsif File.exist?("#{module_root}/#{file}")
|
126
|
-
repo.add(file)
|
127
|
-
end
|
128
|
-
end
|
129
|
-
begin
|
130
|
-
opts_commit = {}
|
131
|
-
opts_push = {}
|
132
|
-
opts_commit = { :amend => true } if options[:amend]
|
133
|
-
opts_push = { :force => true } if options[:force]
|
134
|
-
if options[:pre_commit_script]
|
135
|
-
script = "#{File.dirname(File.dirname(__FILE__))}/../contrib/#{options[:pre_commit_script]}"
|
136
|
-
`#{script} #{module_root}`
|
137
|
-
end
|
138
|
-
repo.commit(message, opts_commit)
|
139
|
-
if options[:remote_branch]
|
140
|
-
if remote_branch_differ?(repo, branch, options[:remote_branch])
|
141
|
-
repo.push('origin', "#{branch}:#{options[:remote_branch]}", opts_push)
|
142
|
-
end
|
143
|
-
else
|
144
|
-
repo.push('origin', branch, opts_push)
|
145
|
-
end
|
146
|
-
# Only bump/tag if pushing didn't fail (i.e. there were changes)
|
147
|
-
m = Blacksmith::Modulefile.new("#{module_root}/metadata.json")
|
148
|
-
if options[:bump]
|
149
|
-
new = bump(repo, m, message, module_root, options[:changelog])
|
150
|
-
tag(repo, new, options[:tag_pattern]) if options[:tag]
|
151
|
-
end
|
152
|
-
rescue ::Git::GitExecuteError => git_error
|
153
|
-
if git_error.message =~ /working (directory|tree) clean/
|
154
|
-
puts "There were no files to update in #{name}. Not committing."
|
155
|
-
return false
|
156
|
-
else
|
157
|
-
puts git_error
|
158
|
-
raise
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
true
|
163
|
-
end
|
164
|
-
|
165
|
-
# Needed because of a bug in the git gem that lists ignored files as
|
166
|
-
# untracked under some circumstances
|
167
|
-
# https://github.com/schacon/ruby-git/issues/130
|
168
|
-
def self.untracked_unignored_files(repo)
|
169
|
-
ignore_path = "#{repo.dir.path}/.gitignore"
|
170
|
-
ignored = File.exist?(ignore_path) ? File.read(ignore_path).split : []
|
171
|
-
repo.status.untracked.keep_if { |f, _| ignored.none? { |i| File.fnmatch(i, f) } }
|
172
|
-
end
|
173
|
-
|
174
|
-
def self.update_noop(name, options)
|
175
|
-
puts "Using no-op. Files in #{name} may be changed but will not be committed."
|
176
|
-
|
177
|
-
repo = ::Git.open("#{options[:project_root]}/#{name}")
|
178
|
-
checkout_branch(repo, options[:branch])
|
179
|
-
|
180
|
-
puts 'Files changed:'
|
181
|
-
repo.diff('HEAD', '--').each do |diff|
|
182
|
-
puts diff.patch
|
183
|
-
end
|
184
|
-
|
185
|
-
puts 'Files added:'
|
186
|
-
untracked_unignored_files(repo).each_key do |file|
|
187
|
-
puts file
|
188
|
-
end
|
189
|
-
|
190
|
-
puts "\n\n"
|
191
|
-
puts '--------------------------------'
|
192
|
-
end
|
193
|
-
end
|
194
|
-
end
|