librarian-puppet-simple 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/librarian/puppet/simple/cli.rb +186 -14
- data/lib/librarian/puppet/simple/installer.rb +13 -6
- data/lib/librarian/puppet/simple/iterator.rb +12 -3
- data/lib/librarian/puppet/simple/util.rb +12 -6
- data/lib/librarian/puppet/simple/version.rb +1 -1
- data/librarian-puppet-simple.gemspec +1 -2
- data/spec/functional/clean_spec.rb +1 -1
- data/spec/functional/install_spec.rb +21 -1
- metadata +26 -11
- checksums.yaml +0 -7
@@ -7,8 +7,10 @@ module Librarian
|
|
7
7
|
module Simple
|
8
8
|
class CLI < Thor
|
9
9
|
|
10
|
+
include Librarian::Puppet::Simple::Util
|
10
11
|
include Librarian::Puppet::Simple::Installer
|
11
12
|
include Librarian::Puppet::Simple::Iterator
|
13
|
+
|
12
14
|
class_option :verbose, :type => :boolean,
|
13
15
|
:desc => 'verbose output for executed commands'
|
14
16
|
|
@@ -44,7 +46,7 @@ module Librarian
|
|
44
46
|
desc 'git_status', 'determine the current status of checked out git repos'
|
45
47
|
def git_status
|
46
48
|
@custom_module_path = options[:path]
|
47
|
-
#
|
49
|
+
# populate @modules
|
48
50
|
eval(File.read(File.expand_path(options[:puppetfile])))
|
49
51
|
each_module_of_type(:git) do |repo|
|
50
52
|
Dir.chdir(File.join(module_path, repo[:name])) do
|
@@ -60,27 +62,197 @@ module Librarian
|
|
60
62
|
end
|
61
63
|
|
62
64
|
desc 'dev_setup', 'adds development r/w remotes to each repo (assumes remote has the same name as current repo)'
|
63
|
-
method_option :remote, :type => :string, :desc => "Account name of remote to add"
|
64
65
|
def dev_setup(remote_name)
|
66
|
+
@custom_module_path = options[:path]
|
67
|
+
# populate @modules
|
68
|
+
eval(File.read(File.expand_path(options[:puppetfile])))
|
65
69
|
each_module_of_type(:git) do |repo|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
if remote_url =~ /(git|https?):\/\/(.+)\/(.+)?\/(.+)/
|
74
|
-
url = "git@#{$2}:#{remote_name}/#{$4}"
|
70
|
+
Dir.chdir(File.join((options[:path] || 'modules'), repo[:name])) do
|
71
|
+
print_verbose "Adding development remote for git repo #{repo[:name]}"
|
72
|
+
remotes = system_cmd('git remote')
|
73
|
+
if remotes.include?(remote_name)
|
74
|
+
puts "Did not have to add remote #{remote_name} to #{repo[:name]}"
|
75
|
+
elsif ! remotes.include?('origin')
|
76
|
+
raise(TestException, "Repo #{repo[:name]} has no remote called origin, failing")
|
75
77
|
else
|
76
|
-
|
78
|
+
remote_url = system_cmd('git remote show origin').detect {|x| x =~ /\s+Push\s+URL: / }
|
79
|
+
if remote_url =~ /(git|https?):\/\/(.+)\/(.+)?\/(.+)/
|
80
|
+
url = "git@#{$2}:#{remote_name}/#{$4}"
|
81
|
+
puts "Adding remote #{remote_name} as #{url}"
|
82
|
+
system_cmd("git remote add #{remote_name} #{url}")
|
83
|
+
elsif remote_url =~ /^git@/
|
84
|
+
puts "Origin is already a read/write remote, skipping b/c this is unexpected"
|
85
|
+
else
|
86
|
+
puts "remote_url #{remote_url} did not have the expected format. weird..."
|
87
|
+
end
|
77
88
|
end
|
78
|
-
puts "Adding remote #{remote_name} as #{url}"
|
79
|
-
git_cmd("remote add #{remote_name} #{url}")
|
80
89
|
end
|
81
90
|
end
|
82
91
|
end
|
83
92
|
|
93
|
+
#
|
94
|
+
# I am not sure if anyone besides me (Dan Bode) should use this command.
|
95
|
+
# It is specifically for the use case where you are managing downstream versions
|
96
|
+
# of Puppet modules, where you want to track the relationship between your downstream
|
97
|
+
# forks and upstream.
|
98
|
+
# It required a specially formatted Puppetfile that expects an environment variable called
|
99
|
+
# repo_to_use that accepts the values 'upstream' and 'downstream'. It should use that environment
|
100
|
+
# variable to be able to generate either the upstream or downstream set of repos.
|
101
|
+
#
|
102
|
+
# Given those requirements, it can be used to compare the revision history differences betwee
|
103
|
+
# those commits.
|
104
|
+
#
|
105
|
+
desc 'compare_repos', 'compares the specified upstream and downstream repos'
|
106
|
+
method_option :output_file, :type => :string,
|
107
|
+
:desc => "Name of Puppetfile to save the results as"
|
108
|
+
method_option :ignore_merges, :type => :boolean,
|
109
|
+
:desc => 'Indicates that merge commits should be ignored'
|
110
|
+
method_option :show_diffs, :type => :boolean,
|
111
|
+
:desc => 'Show code differences of divergent commits (add -u)'
|
112
|
+
# I was really just using this for testing
|
113
|
+
# not sure if end users need it
|
114
|
+
method_option :existing_tmp_dir, :type => :string,
|
115
|
+
:desc => 'Uses an existing directory. Assumes the downstream repos have already been populated.'
|
116
|
+
method_option :upstream_only, :type => :boolean,
|
117
|
+
:desc => 'Only show commits that are only in the upstream'
|
118
|
+
method_option :downstream_only, :type => :boolean,
|
119
|
+
:desc => 'Only show commits that are only in downstream'
|
120
|
+
method_option :oneline, :type => :boolean,
|
121
|
+
:desc => 'Condense log output to one line'
|
122
|
+
|
123
|
+
|
124
|
+
def compare_repos
|
125
|
+
|
126
|
+
repo_hash = {}
|
127
|
+
@verbose = options[:verbose]
|
128
|
+
abort('path not supported by compare_repos command') if options[:path]
|
129
|
+
if options[:downstream_only] and options[:upstream_only]
|
130
|
+
abort('Cannot specify both downstream_only and upstream_only')
|
131
|
+
end
|
132
|
+
|
133
|
+
# create path where code will be stored
|
134
|
+
if options[:existing_tmp_dir]
|
135
|
+
path = options[:existing_tmp_dir]
|
136
|
+
else
|
137
|
+
path = File.join('.tmp', Time.now.strftime("%Y_%m_%d_%H_%S"))
|
138
|
+
end
|
139
|
+
|
140
|
+
FileUtils.mkdir_p(path)
|
141
|
+
@custom_module_path = path
|
142
|
+
|
143
|
+
# install the downstream modules in our tmp directory and build out a hash
|
144
|
+
downstream = build_puppetfile_hash('downstream', !options[:existing_tmp_dir])
|
145
|
+
# just build a hash of the downstream modules
|
146
|
+
upstream = build_puppetfile_hash('upstream', false)
|
147
|
+
|
148
|
+
unless ( (downstream.keys - upstream.keys) == [] and
|
149
|
+
(upstream.keys - downstream.keys)
|
150
|
+
)
|
151
|
+
abort('Your Puppetfile did not produce the same upstream and downstream repos, this is not yet supported')
|
152
|
+
else
|
153
|
+
|
154
|
+
upstream.each do |us_name, us_repo|
|
155
|
+
# compare to see if the source of revisions are the same
|
156
|
+
ds_repo = downstream[us_name]
|
157
|
+
if ds_repo[:git] == us_repo[:git] and ds_repo[:ref] == us_repo[:ref]
|
158
|
+
print_verbose("\nSources of #{us_name} are the same, nothing to compare.")
|
159
|
+
else
|
160
|
+
Dir.chdir(File.join(path, us_name)) do
|
161
|
+
if us_repo[:git] =~ /(git|https?):\/\/(.+)\/(.+)?\/(.+)/
|
162
|
+
remote_name = $3
|
163
|
+
remotes = system_cmd('git remote')
|
164
|
+
if remotes.include?(remote_name)
|
165
|
+
puts "Did not have to add remote #{remote_name} to #{us_repo[:name]}, it was already there"
|
166
|
+
else
|
167
|
+
puts "Adding remote #{remote_name} #{us_repo[:git]}"
|
168
|
+
system_cmd("git remote add #{remote_name} #{us_repo[:git]}")
|
169
|
+
end
|
170
|
+
system_cmd("git fetch #{remote_name}")
|
171
|
+
if us_repo[:ref] =~ /^origin\/(\S+)$/
|
172
|
+
compare_ref = "#{remote_name}/#{$1}"
|
173
|
+
else
|
174
|
+
compare_ref = "#{remote_name}/#{us_repo[:ref]}"
|
175
|
+
end
|
176
|
+
|
177
|
+
# set up parameters for git log call
|
178
|
+
ignore_merges = options[:ignore_merges] ? '--no-merges' : ''
|
179
|
+
show_diffs = options[:show_diffs] ? '-u' : ''
|
180
|
+
oneline = options[:oneline] ? '--oneline' : ''
|
181
|
+
# show the results, this assumes that HEAD is up-to-date (which it should be)
|
182
|
+
|
183
|
+
if options[:downstream_only] and options[:upstream_only]
|
184
|
+
abort('Cannot specify both downstream_only and upstream_only')
|
185
|
+
end
|
186
|
+
puts "########## Results for #{us_name} ##########"
|
187
|
+
unless options[:upstream_only]
|
188
|
+
puts " ######## Commits only in downstream ########"
|
189
|
+
results = system_cmd("git log --left-only HEAD...#{compare_ref} #{ignore_merges} #{show_diffs} #{oneline}", true)
|
190
|
+
puts " ######## End Downstream results ########"
|
191
|
+
end
|
192
|
+
unless options[:downstream_only]
|
193
|
+
puts " ######## Commits only in upstream ########"
|
194
|
+
results = system_cmd("git log --right-only HEAD...#{compare_ref} #{ignore_merges} #{show_diffs} #{oneline}", true)
|
195
|
+
puts " ######## End upstream ########"
|
196
|
+
end
|
197
|
+
puts "########## End of Results for #{us_name} ##########"
|
198
|
+
else
|
199
|
+
abort("Unrecognizable upstream url #{us_repo[:git]}")
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
desc 'generate_puppetfile', 'generates a static version of the Puppetfile'
|
208
|
+
method_option :out_file,
|
209
|
+
:desc => 'output file where static puppetfile should be written to'
|
210
|
+
def generate_puppetfile
|
211
|
+
eval(File.read(File.expand_path(options[:puppetfile])))
|
212
|
+
if options[:out_file]
|
213
|
+
File.open(options[:out_file], 'w') do |fh|
|
214
|
+
print_puppet_file(fh)
|
215
|
+
end
|
216
|
+
else
|
217
|
+
print_puppet_file(STDOUT)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
private
|
222
|
+
|
223
|
+
def print_puppet_file(stream)
|
224
|
+
each_module do |repo|
|
225
|
+
repo.delete(:name)
|
226
|
+
out_str = repo.delete(:full_name)
|
227
|
+
repo.each do |k,v|
|
228
|
+
out_str << ", :#{k} => #{v}"
|
229
|
+
end
|
230
|
+
stream.puts(out_str)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
# builds out a certain type of repo
|
235
|
+
def build_puppetfile_hash(name, perform_installation=false)
|
236
|
+
repo_hash = {}
|
237
|
+
# set environment variable to determine what version of modules to install
|
238
|
+
# this assumes that the environment variable repos_to_use has been coded in
|
239
|
+
# your Puppetfile to allow installation of different versions of modules
|
240
|
+
ENV['repos_to_use'] = name
|
241
|
+
# parse Puppetfile and install modules in our tmp directory.
|
242
|
+
eval(File.read(File.expand_path(options[:puppetfile])))
|
243
|
+
# install modules if desired
|
244
|
+
install! if perform_installation
|
245
|
+
|
246
|
+
# iterate through all git modules
|
247
|
+
each_module_of_type(:git) do |git_repo|
|
248
|
+
abort("Module git_repo[:name] was defined multiple times in same Puppetfile") if repo_hash[git_repo[:name]]
|
249
|
+
repo_hash[git_repo[:name]] = git_repo
|
250
|
+
end
|
251
|
+
# clear out the modules once finished
|
252
|
+
clear_modules
|
253
|
+
repo_hash
|
254
|
+
end
|
255
|
+
|
84
256
|
end
|
85
257
|
end
|
86
258
|
end
|
@@ -25,19 +25,26 @@ module Librarian
|
|
25
25
|
|
26
26
|
print_verbose "\n##### processing module #{repo[:name]}..."
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
module_dir = File.join(module_path, repo[:name])
|
29
|
+
|
30
|
+
unless File.exists?(module_dir)
|
31
|
+
case
|
32
|
+
when repo[:git]
|
33
|
+
install_git module_path, repo[:name], repo[:git], repo[:ref]
|
34
|
+
when repo[:tarball]
|
35
|
+
install_tarball module_path, repo[:name], repo[:tarball]
|
36
|
+
else
|
37
|
+
abort('only the :git and :tarball provider are currently supported')
|
38
|
+
end
|
33
39
|
else
|
34
|
-
|
40
|
+
print_verbose "\nModule #{repo[:name]} already installed in #{module_path}"
|
35
41
|
end
|
36
42
|
end
|
37
43
|
end
|
38
44
|
|
39
45
|
private
|
40
46
|
|
47
|
+
# installs sources that are git repos
|
41
48
|
def install_git(module_path, module_name, repo, ref = nil)
|
42
49
|
module_dir = File.join(module_path, module_name)
|
43
50
|
|
@@ -8,22 +8,31 @@ module Librarian
|
|
8
8
|
# evaluate a module and add it our @modules instance variable
|
9
9
|
def mod(name, options = {})
|
10
10
|
@modules ||= {}
|
11
|
+
full_name = name
|
11
12
|
module_name = name.split('/', 2).last
|
12
13
|
|
13
14
|
case
|
14
15
|
when options[:git]
|
15
16
|
@modules[:git] ||= []
|
16
|
-
@modules[:git].push(options.merge(:name => module_name))
|
17
|
+
@modules[:git].push(options.merge(:name => module_name, :full_name => full_name))
|
17
18
|
when options[:tarball]
|
18
19
|
@modules[:tarball] ||= []
|
19
|
-
@modules[:tarball].push(options.merge(:name => module_name))
|
20
|
+
@modules[:tarball].push(options.merge(:name => module_name, :full_name => full_name))
|
20
21
|
else
|
21
22
|
@modules[:forge] ||= []
|
22
|
-
@modules[:forge].push(options.merge(:name => module_name))
|
23
|
+
@modules[:forge].push(options.merge(:name => module_name, :full_name => full_name))
|
23
24
|
#abort('only the :git and :tarball providers are currently supported')
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
28
|
+
def modules
|
29
|
+
@modules
|
30
|
+
end
|
31
|
+
|
32
|
+
def clear_modules
|
33
|
+
@modules = nil
|
34
|
+
end
|
35
|
+
|
27
36
|
# iterate through all modules
|
28
37
|
def each_module(&block)
|
29
38
|
(@modules || {}).each do |type, repos|
|
@@ -7,6 +7,9 @@ module Librarian
|
|
7
7
|
module Simple
|
8
8
|
module Util
|
9
9
|
|
10
|
+
def forge(repo)
|
11
|
+
# this does nothing atm
|
12
|
+
end
|
10
13
|
# figure out what directory we are working out og
|
11
14
|
def base_dir
|
12
15
|
@base_dir ||= Dir.pwd
|
@@ -26,18 +29,21 @@ module Librarian
|
|
26
29
|
end
|
27
30
|
|
28
31
|
# run a command on the system
|
29
|
-
def system_cmd (cmd)
|
32
|
+
def system_cmd (cmd, print_output=false)
|
30
33
|
print_verbose "Running cmd: #{cmd}"
|
31
34
|
output = `#{cmd}`.split("\n")
|
32
|
-
|
35
|
+
if print_output
|
36
|
+
puts output
|
37
|
+
else
|
38
|
+
print_verbose output
|
39
|
+
end
|
33
40
|
raise(StandardError, "Cmd #{cmd} failed") unless $?.success?
|
34
41
|
output
|
35
42
|
end
|
36
43
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
44
|
+
def print_verbose(text)
|
45
|
+
puts text if @verbose
|
46
|
+
end
|
41
47
|
|
42
48
|
end
|
43
49
|
end
|
@@ -13,7 +13,6 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.description = 'Simplify deployment of your Puppet infrastructure by
|
14
14
|
automatically pulling in modules from the forge and git repositories with
|
15
15
|
a single command.'
|
16
|
-
s.license = 'Apache v2.0'
|
17
16
|
|
18
17
|
s.files = `git ls-files`.split($/)
|
19
18
|
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
@@ -23,4 +22,4 @@ Gem::Specification.new do |s|
|
|
23
22
|
s.add_dependency "thor", "~> 0.15"
|
24
23
|
|
25
24
|
s.add_development_dependency "rspec", "~> 2.13"
|
26
|
-
end
|
25
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
require 'tmpdir'
|
4
4
|
|
@@ -51,5 +51,25 @@ describe "Functional - Install" do
|
|
51
51
|
status.should == 0
|
52
52
|
output.should include('##### processing module apache')
|
53
53
|
end
|
54
|
+
|
55
|
+
describe 'when modules are already installed' do
|
56
|
+
temp_directory = nil
|
57
|
+
|
58
|
+
before :each do
|
59
|
+
temp_directory = Dir.mktmpdir
|
60
|
+
Dir.entries(temp_directory).should =~ ['.', '..']
|
61
|
+
FileUtils.touch File.join(temp_directory, 'apache')
|
62
|
+
Dir.entries(temp_directory).should =~ ['.', '..', 'apache']
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'without clean it should only install ntp' do
|
66
|
+
output, status = execute_captured("bin/librarian-puppet install --verbose --path=#{temp_directory} --puppetfile=spec/fixtures/Puppetfile")
|
67
|
+
status.should == 0
|
68
|
+
output.should include('Module apache already installed')
|
69
|
+
Dir.entries(temp_directory).should =~ ['.', '..', 'apache', 'ntp']
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
54
73
|
end
|
74
|
+
|
55
75
|
end
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: librarian-puppet-simple
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Dan Bode
|
@@ -9,7 +14,8 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2013-
|
17
|
+
date: 2013-06-12 00:00:00 -07:00
|
18
|
+
default_executable:
|
13
19
|
dependencies:
|
14
20
|
- !ruby/object:Gem::Dependency
|
15
21
|
name: thor
|
@@ -18,6 +24,9 @@ dependencies:
|
|
18
24
|
requirements:
|
19
25
|
- - ~>
|
20
26
|
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
- 15
|
21
30
|
version: "0.15"
|
22
31
|
type: :runtime
|
23
32
|
version_requirements: *id001
|
@@ -28,6 +37,9 @@ dependencies:
|
|
28
37
|
requirements:
|
29
38
|
- - ~>
|
30
39
|
- !ruby/object:Gem::Version
|
40
|
+
segments:
|
41
|
+
- 2
|
42
|
+
- 13
|
31
43
|
version: "2.13"
|
32
44
|
type: :development
|
33
45
|
version_requirements: *id002
|
@@ -60,10 +72,9 @@ files:
|
|
60
72
|
- spec/functional/clean_spec.rb
|
61
73
|
- spec/functional/install_spec.rb
|
62
74
|
- spec/spec_helper.rb
|
75
|
+
has_rdoc: true
|
63
76
|
homepage: https://github.com/bodepd/librarian-puppet-simple
|
64
|
-
licenses:
|
65
|
-
- Apache v2.0
|
66
|
-
metadata: {}
|
77
|
+
licenses: []
|
67
78
|
|
68
79
|
post_install_message:
|
69
80
|
rdoc_options: []
|
@@ -72,23 +83,27 @@ require_paths:
|
|
72
83
|
- lib
|
73
84
|
required_ruby_version: !ruby/object:Gem::Requirement
|
74
85
|
requirements:
|
75
|
-
-
|
76
|
-
- ">="
|
86
|
+
- - ">="
|
77
87
|
- !ruby/object:Gem::Version
|
88
|
+
segments:
|
89
|
+
- 0
|
78
90
|
version: "0"
|
79
91
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
92
|
requirements:
|
81
|
-
-
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
segments:
|
96
|
+
- 0
|
97
|
+
version: "0"
|
82
98
|
requirements: []
|
83
99
|
|
84
100
|
rubyforge_project:
|
85
|
-
rubygems_version:
|
101
|
+
rubygems_version: 1.3.6
|
86
102
|
signing_key:
|
87
|
-
specification_version:
|
103
|
+
specification_version: 3
|
88
104
|
summary: Bundler for your Puppet modules
|
89
105
|
test_files:
|
90
106
|
- spec/fixtures/Puppetfile
|
91
107
|
- spec/functional/clean_spec.rb
|
92
108
|
- spec/functional/install_spec.rb
|
93
109
|
- spec/spec_helper.rb
|
94
|
-
has_rdoc:
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
data.tar.gz: e70ab85f22c10e06549a8e4084512224a7a85de8
|
4
|
-
metadata.gz: cfad763618e6817a981167e95edaf026908b8ea8
|
5
|
-
SHA512:
|
6
|
-
data.tar.gz: 8450ff50735e8083b294e379a9652175688ac9ef27454e00c519d5842d0331131891aad460dc112f02508de7082c57451b2d0e7e61deee4eaed1ee100992c706
|
7
|
-
metadata.gz: 1f1fe4db05d288c0eb566f2e9e39eef07cea6264e312b1b0bff07d084d4855ada399f70429b8d1bdfc3dece7c283ba74c258ff64f6ee907f820027f66847fbfd
|