librarian-puppet-simple.haf 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.
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .rspec
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ vendor/
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1 @@
1
+ Apache License 2.0
data/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # librarian-puppet-simple
2
+
3
+ This project was created out of my frustration with dependency management in librarian-puppet, some people need external dependencies, I just need to be able to pin revisions for a collection of modules, and I found the dependency managment features of librarian-puppet too heavy for my simple use case.
4
+
5
+ This project just has fewer commands, but they should be compatible with the original librarian-puppet:
6
+
7
+ ### Clean
8
+ Remove the directory where the modules will be installed. At the moment the supported options are:
9
+ * `--verbose` display progress messages
10
+ * `--path` override the default `./modules` where modules will be installed
11
+
12
+ ```
13
+ librarian-puppet clean [--verbose] [--path]
14
+ ```
15
+
16
+ ### Install
17
+ Iterates through your Puppetfile and installs git sources. At the moment the supported options are:
18
+ * `--verbose` display progress messages
19
+ * `--clean` remove the directory before installing modules
20
+ * `--path` override the default `./modules` where modules will be installed
21
+ * `--puppetfile` override the default `./Puppetfile` used to find the modules
22
+
23
+ ```
24
+ librarian-puppet install [--verbose] [--clean] [--path] [--puppetfile]
25
+ ```
26
+
27
+ ### Update
28
+ Iterates through your Puppetfile and updates git sources. If a SHA-1 hash is specified in the `:ref`, the module will not be updated.
29
+
30
+ Supported options are:<br/>
31
+ <li>`--verbose` display progress messages</li>
32
+ <li>`--path` override the default `./modules` where modules will be installed</li>
33
+ <li> `--puppetfile` override the default `./Puppetfile` used to find the modules</li>
34
+
35
+ ```
36
+ librarian-puppet update [--verbose] [--path] [--puppetfile]
37
+ ```
38
+
39
+ ## Puppetfile
40
+ The processed Puppetfile may contain two different types of modules, `git` and `tarball`. The `git` option accepts an optional `ref` parameter.
41
+
42
+ The module names can be namespaced, but the created directory will only contain the last part of the name. For example, a module named `puppetlabs/ntp` will generate a directory `ntp`, and so will a module simply named `ntp`.
43
+
44
+ Here's an example of a valid Puppetfile showcasing all valid options:
45
+
46
+ ```
47
+ mod "puppetlabs/ntp",
48
+ :git => "git://github.com/puppetlabs/puppetlabs-ntp.git",
49
+ :ref => "99bae40f225db0dd052efbf1d4078a21f0333331"
50
+
51
+ mod "apache",
52
+ :tarball => "https://forge.puppetlabs.com/puppetlabs/apache/0.6.0.tar.gz"
53
+
54
+ #Deploy mysql module into modules/databases/mysql with the :subdir param
55
+ mod "mysql",
56
+ :git => "gitolite@myserver.com:mysql.git",
57
+ :subdir => "databases"
58
+ ```
59
+ ## Setting up for development and running the specs
60
+ Just clone the repo and run the following commands:
61
+ ```
62
+ bundle exec install --path=vendor
63
+ bundle exec rspec
64
+ ```
65
+
66
+ Beware that the functional tests will download files from GitHub and PuppetForge and will break if either is unavailable.
67
+
68
+ ## License
69
+
70
+ See [LICENSE](/LICENSE)
71
+
72
+ ## Credits
73
+ The untar and ungzip methods came from https://gist.github.com/sinisterchipmunk/1335041
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'thor'
4
+ lib = File.expand_path('../../lib', __FILE__)
5
+ $:.unshift(lib) unless $:.include?(lib)
6
+ require 'librarian/puppet/simple/cli'
7
+
8
+ Librarian::Puppet::Simple::CLI.bin!
@@ -0,0 +1,281 @@
1
+ require 'librarian/puppet/simple/installer'
2
+ require 'librarian/puppet/simple/iterator'
3
+ require 'fileutils'
4
+
5
+ module Librarian
6
+ module Puppet
7
+ module Simple
8
+ class CLI < Thor
9
+
10
+ include Librarian::Puppet::Simple::Util
11
+ include Librarian::Puppet::Simple::Installer
12
+ include Librarian::Puppet::Simple::Iterator
13
+
14
+ class_option :verbose, :type => :boolean,
15
+ :desc => 'verbose output for executed commands'
16
+
17
+ class_option :path, :type => :string,
18
+ :desc => "overrides target directory, default is ./modules"
19
+ class_option :puppetfile, :type => :string,
20
+ :desc => "overrides used Puppetfile",
21
+ :default => './Puppetfile'
22
+
23
+
24
+ def self.bin!
25
+ start
26
+ end
27
+
28
+ desc 'install', 'installs all git sources from your Puppetfile'
29
+ method_option :clean, :type => :boolean, :desc => "calls clean before executing install"
30
+ def install
31
+ @verbose = options[:verbose]
32
+ clean if options[:clean]
33
+ @custom_module_path = options[:path]
34
+ # evaluate the file to populate @modules
35
+ eval(File.read(File.expand_path(options[:puppetfile])))
36
+ install!
37
+ end
38
+
39
+ desc 'update', 'updates all git sources from your Puppetfile'
40
+ method_option :update, :type => :boolean, :desc => "Updates git sources"
41
+ def update
42
+ @verbose = options[:verbose]
43
+ @custom_module_path = options[:path]
44
+ eval(File.read(File.expand_path(options[:puppetfile])))
45
+ each_module_of_type(:git) do |repo|
46
+ Dir.chdir(File.join(module_path, repo[:name])) do
47
+ # if no ref is given, assume master
48
+ if repo[:ref] == nil
49
+ checkout_ref = 'origin/master'
50
+ remote_branch = 'master'
51
+ else
52
+ checkout_ref = repo[:ref]
53
+ remote_branch = repo[:ref].gsub(/^origin\//, '')
54
+ end
55
+ print_verbose "\n\n#{repo[:name]} -- git fetch origin && git checkout #{checkout_ref}"
56
+ git_pull_cmd = system_cmd("git fetch origin && git checkout #{checkout_ref}")
57
+ end
58
+ end
59
+ end
60
+
61
+ desc 'clean', 'clean modules directory'
62
+ def clean
63
+ target_directory = options[:path] || File.expand_path("./modules")
64
+ puts "Target Directory: #{target_directory}" if options[:verbose]
65
+ FileUtils.rm_rf target_directory
66
+ end
67
+
68
+ desc 'git_status', 'determine the current status of checked out git repos'
69
+ def git_status
70
+ @custom_module_path = options[:path]
71
+ # populate @modules
72
+ eval(File.read(File.expand_path(options[:puppetfile])))
73
+ each_module_of_type(:git) do |repo|
74
+ Dir.chdir(File.join(module_path, repo[:name])) do
75
+ status = system_cmd('git status')
76
+ if status.include?('nothing to commit (working directory clean)')
77
+ puts "Module #{repo[:name]} has not changed" if options[:verbose]
78
+ else
79
+ puts "Uncommitted changes for: #{repo[:name]}"
80
+ puts " #{status.join("\n ")}"
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ desc 'dev_setup', 'adds development r/w remotes to each repo (assumes remote has the same name as current repo)'
87
+ def dev_setup(remote_name)
88
+ @custom_module_path = options[:path]
89
+ # populate @modules
90
+ eval(File.read(File.expand_path(options[:puppetfile])))
91
+ each_module_of_type(:git) do |repo|
92
+ Dir.chdir(File.join((options[:path] || 'modules'), repo[:name])) do
93
+ print_verbose "Adding development remote for git repo #{repo[:name]}"
94
+ remotes = system_cmd('git remote')
95
+ if remotes.include?(remote_name)
96
+ puts "Did not have to add remote #{remote_name} to #{repo[:name]}"
97
+ elsif ! remotes.include?('origin')
98
+ raise(TestException, "Repo #{repo[:name]} has no remote called origin, failing")
99
+ else
100
+ remote_url = system_cmd('git remote show origin').detect {|x| x =~ /\s+Push\s+URL: / }
101
+ if remote_url =~ /(git|https?):\/\/(.+)\/(.+)?\/(.+)/
102
+ url = "git@#{$2}:#{remote_name}/#{$4}"
103
+ puts "Adding remote #{remote_name} as #{url}"
104
+ system_cmd("git remote add #{remote_name} #{url}")
105
+ elsif remote_url =~ /^git@/
106
+ puts "Origin is already a read/write remote, skipping b/c this is unexpected"
107
+ else
108
+ puts "remote_url #{remote_url} did not have the expected format. weird..."
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+
115
+ #
116
+ # I am not sure if anyone besides me (Dan Bode) should use this command.
117
+ # It is specifically for the use case where you are managing downstream versions
118
+ # of Puppet modules, where you want to track the relationship between your downstream
119
+ # forks and upstream.
120
+ # It required a specially formatted Puppetfile that expects an environment variable called
121
+ # repo_to_use that accepts the values 'upstream' and 'downstream'. It should use that environment
122
+ # variable to be able to generate either the upstream or downstream set of repos.
123
+ #
124
+ # Given those requirements, it can be used to compare the revision history differences betwee
125
+ # those commits.
126
+ #
127
+ desc 'compare_repos', 'compares the specified upstream and downstream repos'
128
+ method_option :output_file, :type => :string,
129
+ :desc => "Name of Puppetfile to save the results as"
130
+ method_option :ignore_merges, :type => :boolean,
131
+ :desc => 'Indicates that merge commits should be ignored'
132
+ method_option :show_diffs, :type => :boolean,
133
+ :desc => 'Show code differences of divergent commits (add -u)'
134
+ # I was really just using this for testing
135
+ # not sure if end users need it
136
+ method_option :existing_tmp_dir, :type => :string,
137
+ :desc => 'Uses an existing directory. Assumes the downstream repos have already been populated.'
138
+ method_option :upstream_only, :type => :boolean,
139
+ :desc => 'Only show commits that are only in the upstream'
140
+ method_option :downstream_only, :type => :boolean,
141
+ :desc => 'Only show commits that are only in downstream'
142
+ method_option :oneline, :type => :boolean,
143
+ :desc => 'Condense log output to one line'
144
+
145
+
146
+ def compare_repos
147
+
148
+ repo_hash = {}
149
+ @verbose = options[:verbose]
150
+ abort('path not supported by compare_repos command') if options[:path]
151
+ if options[:downstream_only] and options[:upstream_only]
152
+ abort('Cannot specify both downstream_only and upstream_only')
153
+ end
154
+
155
+ # create path where code will be stored
156
+ if options[:existing_tmp_dir]
157
+ path = options[:existing_tmp_dir]
158
+ else
159
+ path = File.join('.tmp', Time.now.strftime("%Y_%m_%d_%H_%S"))
160
+ end
161
+
162
+ FileUtils.mkdir_p(path)
163
+ @custom_module_path = path
164
+
165
+ # install the downstream modules in our tmp directory and build out a hash
166
+ downstream = build_puppetfile_hash('downstream', !options[:existing_tmp_dir])
167
+ # just build a hash of the downstream modules
168
+ upstream = build_puppetfile_hash('upstream', false)
169
+
170
+ unless ( (downstream.keys - upstream.keys) == [] and
171
+ (upstream.keys - downstream.keys)
172
+ )
173
+ abort('Your Puppetfile did not produce the same upstream and downstream repos, this is not yet supported')
174
+ else
175
+
176
+ upstream.each do |us_name, us_repo|
177
+ # compare to see if the source of revisions are the same
178
+ ds_repo = downstream[us_name]
179
+ if ds_repo[:git] == us_repo[:git] and ds_repo[:ref] == us_repo[:ref]
180
+ print_verbose("\nSources of #{us_name} are the same, nothing to compare.")
181
+ else
182
+ Dir.chdir(File.join(path, us_name)) do
183
+ if us_repo[:git] =~ /(git|https?):\/\/(.+)\/(.+)?\/(.+)/
184
+ remote_name = $3
185
+ remotes = system_cmd('git remote')
186
+ if remotes.include?(remote_name)
187
+ puts "Did not have to add remote #{remote_name} to #{us_repo[:name]}, it was already there"
188
+ else
189
+ puts "Adding remote #{remote_name} #{us_repo[:git]}"
190
+ system_cmd("git remote add #{remote_name} #{us_repo[:git]}")
191
+ end
192
+ system_cmd("git fetch #{remote_name}")
193
+ if us_repo[:ref] =~ /^origin\/(\S+)$/
194
+ compare_ref = "#{remote_name}/#{$1}"
195
+ else
196
+ compare_ref = "#{remote_name}/#{us_repo[:ref]}"
197
+ end
198
+
199
+ # set up parameters for git log call
200
+ ignore_merges = options[:ignore_merges] ? '--no-merges' : ''
201
+ show_diffs = options[:show_diffs] ? '-u' : ''
202
+ oneline = options[:oneline] ? '--oneline' : ''
203
+ # show the results, this assumes that HEAD is up-to-date (which it should be)
204
+
205
+ if options[:downstream_only] and options[:upstream_only]
206
+ abort('Cannot specify both downstream_only and upstream_only')
207
+ end
208
+ puts "########## Results for #{us_name} ##########"
209
+ unless options[:upstream_only]
210
+ puts " ######## Commits only in downstream ########"
211
+ results = system_cmd("git log --left-only HEAD...#{compare_ref} #{ignore_merges} #{show_diffs} #{oneline}", true)
212
+ puts " ######## End Downstream results ########"
213
+ end
214
+ unless options[:downstream_only]
215
+ puts " ######## Commits only in upstream ########"
216
+ results = system_cmd("git log --right-only HEAD...#{compare_ref} #{ignore_merges} #{show_diffs} #{oneline}", true)
217
+ puts " ######## End upstream ########"
218
+ end
219
+ puts "########## End of Results for #{us_name} ##########"
220
+ else
221
+ abort("Unrecognizable upstream url #{us_repo[:git]}")
222
+ end
223
+ end
224
+ end
225
+ end
226
+ end
227
+ end
228
+
229
+ desc 'generate_puppetfile', 'generates a static version of the Puppetfile'
230
+ method_option :out_file,
231
+ :desc => 'output file where static puppetfile should be written to'
232
+ def generate_puppetfile
233
+ eval(File.read(File.expand_path(options[:puppetfile])))
234
+ if options[:out_file]
235
+ File.open(options[:out_file], 'w') do |fh|
236
+ print_puppet_file(fh)
237
+ end
238
+ else
239
+ print_puppet_file(STDOUT)
240
+ end
241
+ end
242
+
243
+ private
244
+
245
+ def print_puppet_file(stream)
246
+ each_module do |repo|
247
+ repo.delete(:name)
248
+ out_str = repo.delete(:full_name)
249
+ repo.each do |k,v|
250
+ out_str << ", :#{k} => #{v}"
251
+ end
252
+ stream.puts(out_str)
253
+ end
254
+ end
255
+
256
+ # builds out a certain type of repo
257
+ def build_puppetfile_hash(name, perform_installation=false)
258
+ repo_hash = {}
259
+ # set environment variable to determine what version of modules to install
260
+ # this assumes that the environment variable repos_to_use has been coded in
261
+ # your Puppetfile to allow installation of different versions of modules
262
+ ENV['repos_to_use'] = name
263
+ # parse Puppetfile and install modules in our tmp directory.
264
+ eval(File.read(File.expand_path(options[:puppetfile])))
265
+ # install modules if desired
266
+ install! if perform_installation
267
+
268
+ # iterate through all git modules
269
+ each_module_of_type(:git) do |git_repo|
270
+ abort("Module git_repo[:name] was defined multiple times in same Puppetfile") if repo_hash[git_repo[:name]]
271
+ repo_hash[git_repo[:name]] = git_repo
272
+ end
273
+ # clear out the modules once finished
274
+ clear_modules
275
+ repo_hash
276
+ end
277
+
278
+ end
279
+ end
280
+ end
281
+ end
@@ -0,0 +1,116 @@
1
+ require 'fileutils'
2
+ require 'rubygems/package'
3
+ require 'zlib'
4
+ require 'open-uri'
5
+ require 'librarian/puppet/simple/util'
6
+ require 'librarian/puppet/simple/iterator'
7
+
8
+ # This is an extremely simple file that can consume
9
+ # a Puppet file with git references
10
+ #
11
+ # It does absolutely no dependency resolution by design.
12
+ #
13
+ module Librarian
14
+ module Puppet
15
+ module Simple
16
+ module Installer
17
+
18
+ include Librarian::Puppet::Simple::Util
19
+ include Librarian::Puppet::Simple::Iterator
20
+
21
+ # installs modules using the each_module method from our
22
+ # iterator mixin
23
+ def install!
24
+ each_module do |repo|
25
+ print_verbose "\n##### processing module #{repo[:name]}..."
26
+ module_path = module_path()
27
+ if repo[:subdir]
28
+ module_path = File.join(module_path, repo[:subdir])
29
+ FileUtils.mkdir_p(module_path) unless File.exists?(module_path)
30
+ end
31
+ module_dir = File.join(module_path, repo[:name])
32
+
33
+ unless File.exists?(module_dir)
34
+ case
35
+ when repo[:git]
36
+ install_git module_path, repo[:name], repo[:git], repo[:ref]
37
+ when repo[:tarball]
38
+ install_tarball module_path, repo[:name], repo[:tarball]
39
+ else
40
+ abort('only the :git and :tarball provider are currently supported')
41
+ end
42
+ else
43
+ print_verbose "\nModule #{repo[:name]} already installed in #{module_path}"
44
+ end
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ # installs sources that are git repos
51
+ def install_git(module_path, module_name, repo, ref = nil)
52
+ module_dir = File.join(module_path, module_name)
53
+
54
+ Dir.chdir(module_path) do
55
+ print_verbose "cloning #{repo}"
56
+ system_cmd("git clone #{repo} #{module_name}")
57
+ Dir.chdir(module_dir) do
58
+ system_cmd('git branch -r')
59
+ system_cmd("git checkout #{ref}") if ref
60
+ end
61
+ end
62
+ end
63
+
64
+ def install_tarball(module_path, module_name, remote_tarball)
65
+ Dir.mktmpdir do |tmp|
66
+ temp_file = File.join(tmp,"downloaded_module.tar.gz")
67
+ File.open(temp_file, "w+b") do |saved_file|
68
+ print_verbose "Downloading #{remote_tarball}..."
69
+ open(remote_tarball, 'rb') do |read_file|
70
+ saved_file.write(read_file.read)
71
+ end
72
+ saved_file.rewind
73
+
74
+ target_directory = File.join(module_path, module_name)
75
+ print_verbose "Extracting #{remote_tarball} to #{target_directory}..."
76
+ unzipped_target = ungzip(saved_file)
77
+ tarfile_full_name = untar(unzipped_target, module_path)
78
+ FileUtils.mv File.join(module_path, tarfile_full_name), target_directory
79
+ end
80
+ end
81
+ end
82
+
83
+ # un-gzips the given IO, returning the
84
+ # decompressed version as a StringIO
85
+ def ungzip(tarfile)
86
+ z = Zlib::GzipReader.new(tarfile)
87
+ unzipped = StringIO.new(z.read)
88
+ z.close
89
+ unzipped
90
+ end
91
+
92
+ # untars the given IO into the specified
93
+ # directory
94
+ def untar(io, destination)
95
+ tarfile_full_name = nil
96
+ Gem::Package::TarReader.new io do |tar|
97
+ tar.each do |tarfile|
98
+ tarfile_full_name ||= tarfile.full_name
99
+ destination_file = File.join destination, tarfile.full_name
100
+ if tarfile.directory?
101
+ FileUtils.mkdir_p destination_file
102
+ else
103
+ destination_directory = File.dirname(destination_file)
104
+ FileUtils.mkdir_p destination_directory unless File.directory?(destination_directory)
105
+ File.open destination_file, "wb" do |f|
106
+ f.write tarfile.read
107
+ end
108
+ end
109
+ end
110
+ end
111
+ tarfile_full_name
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,56 @@
1
+ require 'librarian/puppet/simple/util'
2
+
3
+ module Librarian
4
+ module Puppet
5
+ module Simple
6
+ module Iterator
7
+
8
+ # evaluate a module and add it our @modules instance variable
9
+ def mod(name, options = {})
10
+ @modules ||= {}
11
+ full_name = name
12
+ module_name = name.split('/', 2).last
13
+
14
+ case
15
+ when options[:git]
16
+ @modules[:git] ||= []
17
+ @modules[:git].push(options.merge(:name => module_name, :full_name => full_name))
18
+ when options[:tarball]
19
+ @modules[:tarball] ||= []
20
+ @modules[:tarball].push(options.merge(:name => module_name, :full_name => full_name))
21
+ else
22
+ @modules[:forge] ||= []
23
+ @modules[:forge].push(options.merge(:name => module_name, :full_name => full_name))
24
+ #abort('only the :git and :tarball providers are currently supported')
25
+ end
26
+ end
27
+
28
+ def modules
29
+ @modules
30
+ end
31
+
32
+ def clear_modules
33
+ @modules = nil
34
+ end
35
+
36
+ # iterate through all modules
37
+ def each_module(&block)
38
+ (@modules || {}).each do |type, repos|
39
+ (repos || []).each do |repo|
40
+ yield repo
41
+ end
42
+ end
43
+ end
44
+
45
+ # loop over each module of a certain type
46
+ def each_module_of_type(type, &block)
47
+ abort("undefined type #{type}") unless [:git, :tarball].include?(type)
48
+ ((@modules || {})[type] || []).each do |repo|
49
+ yield repo
50
+ end
51
+ end
52
+
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,51 @@
1
+ #
2
+ # this module contains all of the base helper methods
3
+ # used by the other actions
4
+ #
5
+ module Librarian
6
+ module Puppet
7
+ module Simple
8
+ module Util
9
+
10
+ def forge(repo)
11
+ # this does nothing atm
12
+ end
13
+ # figure out what directory we are working out og
14
+ def base_dir
15
+ @base_dir ||= Dir.pwd
16
+ end
17
+
18
+ # figure out what the modulepath is
19
+ def module_path(dir=base_dir)
20
+ unless @module_path
21
+ if @custom_module_path
22
+ @module_path = File.expand_path @custom_module_path
23
+ else
24
+ @module_path = File.join(dir, 'modules')
25
+ end
26
+ Dir.mkdir(@module_path) unless File.exists?(@module_path)
27
+ end
28
+ @module_path
29
+ end
30
+
31
+ # run a command on the system
32
+ def system_cmd (cmd, print_output=false)
33
+ print_verbose "Running cmd: #{cmd}"
34
+ output = `#{cmd}`.split("\n")
35
+ if print_output
36
+ puts output
37
+ else
38
+ print_verbose output
39
+ end
40
+ raise(StandardError, "Cmd #{cmd} failed") unless $?.success?
41
+ output
42
+ end
43
+
44
+ def print_verbose(text)
45
+ puts text if @verbose
46
+ end
47
+
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,7 @@
1
+ module Librarian
2
+ module Puppet
3
+ module Simple
4
+ VERSION = "0.1.0"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ require "librarian/puppet/simple/version"
2
+
3
+ module Librarian
4
+ module Puppet
5
+ module Simple
6
+ # Your code goes here...
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,25 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ require 'librarian/puppet/simple/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'librarian-puppet-simple.haf'
7
+ s.version = Librarian::Puppet::Simple::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = %w|'Dan Bode', 'haf'|
10
+ s.email = ['bodepd@gmail.com']
11
+ s.homepage = 'https://github.com/haf/librarian-puppet-simple'
12
+ s.summary = 'Bundler for your Puppet modules. A fork until a new version is released by Dan.'
13
+ s.description = 'Simplify deployment of your Puppet infrastructure by
14
+ automatically pulling in modules from the forge and git repositories with
15
+ a single command.'
16
+
17
+ s.files = `git ls-files`.split($/)
18
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency "thor", "~> 0.15"
23
+
24
+ s.add_development_dependency "rspec", "~> 2.13"
25
+ end
@@ -0,0 +1,18 @@
1
+ mod 'puppetlabs/ntp',
2
+ :git => 'git://github.com/puppetlabs/puppetlabs-ntp.git',
3
+ :ref => '99bae40f225db0dd052efbf1d4078a21f0333331'
4
+
5
+ mod 'apache',
6
+ :tarball => 'https://forge.puppetlabs.com/puppetlabs/apache/0.6.0.tar.gz'
7
+
8
+ mod 'ghoneycutt/testlps',
9
+ :git => 'git://github.com/ghoneycutt/testlps.git'
10
+
11
+ mod 'ghoneycutt/dnsclient',
12
+ :git => 'git://github.com/ghoneycutt/puppet-module-dnsclient.git',
13
+ :ref => 'v3.0.4'
14
+
15
+ mod 'haf/empty-repository',
16
+ :git => 'git://github.com/haf/empty-repository.git',
17
+ :subdir => 'subdir-A'
18
+
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ require 'tmpdir'
4
+
5
+ describe "Functional - Clean" do
6
+ it "displays install help message" do
7
+ output, status = execute_captured("bin/librarian-puppet help clean")
8
+ output.should_not include("ERROR")
9
+ output.should_not include("Could not find command")
10
+ status.should == 0
11
+ end
12
+
13
+ describe "when running 'librarian-puppet clean'" do
14
+ temp_directory = nil
15
+
16
+ before :each do
17
+ temp_directory = Dir.mktmpdir
18
+ Dir.entries(temp_directory).should =~ ['.', '..']
19
+ FileUtils.touch File.join(temp_directory, 'trashfile')
20
+ Dir.entries(temp_directory).should =~ ['.', '..', 'trashfile']
21
+ end
22
+
23
+ after :each do
24
+ FileUtils.rm_rf temp_directory if File.exist?(temp_directory)
25
+ end
26
+
27
+ it "with --path it cleans the directory" do
28
+ output, status = execute_captured("bin/librarian-puppet clean --path=#{temp_directory}")
29
+
30
+ status.should == 0
31
+ # Using File.exist? to be compatible with Ruby 1.8.7
32
+ File.exist?(temp_directory).should be_false
33
+ end
34
+
35
+ it "with --verbose it shows progress messages" do
36
+ output, status = execute_captured("bin/librarian-puppet clean --verbose --path=#{temp_directory}")
37
+
38
+ status.should == 0
39
+ output.should include("Target Directory: #{temp_directory}")
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ require 'tmpdir'
4
+
5
+ describe "Functional - Install" do
6
+ before :all do
7
+ warning_message = "ATTENTION: these tests download information from github.com and forge.puppetlabs.com"
8
+ puts '*' * warning_message.length
9
+ puts warning_message
10
+ puts '*' * warning_message.length
11
+ end
12
+
13
+ it "displays install help message" do
14
+ output, status = execute_captured("bin/librarian-puppet help install")
15
+ output.should_not include("ERROR")
16
+ output.should_not include("Could not find command")
17
+ status.should == 0
18
+ end
19
+
20
+ describe "when running 'librarian-puppet install'" do
21
+ temp_directory = nil
22
+
23
+ before :each do
24
+ temp_directory = Dir.mktmpdir
25
+ Dir.entries(temp_directory).should =~ ['.', '..']
26
+ FileUtils.touch File.join(temp_directory, 'trashfile')
27
+ Dir.entries(temp_directory).should =~ ['.', '..', 'trashfile']
28
+ end
29
+
30
+ after :each do
31
+ FileUtils.rm_rf temp_directory
32
+ end
33
+
34
+ it "install the modules in a temp directory" do
35
+ output, status = execute_captured("bin/librarian-puppet install --path=#{temp_directory} --puppetfile=spec/fixtures/Puppetfile")
36
+
37
+ status.should == 0
38
+ Dir.entries(temp_directory).should =~ %w|. .. apache ntp trashfile dnsclient testlps subdir-A|
39
+ end
40
+
41
+ it "with --clean it cleans the directory before installing the modules in a temp directory" do
42
+ output, status = execute_captured("bin/librarian-puppet install --clean --path=#{temp_directory} --puppetfile=spec/fixtures/Puppetfile")
43
+
44
+ status.should == 0
45
+ Dir.entries(temp_directory).should =~ %w|. .. apache ntp dnsclient testlps subdir-A|
46
+ end
47
+
48
+ it "with --verbose it outputs progress messages" do
49
+ output, status = execute_captured("bin/librarian-puppet install --verbose --path=#{temp_directory} --puppetfile=spec/fixtures/Puppetfile")
50
+
51
+ status.should == 0
52
+ output.should include('##### processing module apache')
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 =~ %w|. .. apache ntp dnsclient testlps subdir-A|
70
+ end
71
+ end
72
+ end
73
+
74
+ end
@@ -0,0 +1,25 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ require 'open3'
8
+
9
+ RSpec.configure do |config|
10
+ config.treat_symbols_as_metadata_keys_with_true_values = true
11
+ config.run_all_when_everything_filtered = true
12
+ config.filter_run :focus
13
+
14
+ # Run specs in random order to surface order dependencies. If you find an
15
+ # order dependency and want to debug it, you can fix the order by providing
16
+ # the seed, which is printed after each run.
17
+ # --seed 1234
18
+ config.order = 'random'
19
+
20
+ def execute_captured(command)
21
+ stdin, stdout, stderr = Open3.popen3(command)
22
+ condensed = stdout.readlines.join + stderr.readlines.join
23
+ [condensed, $?.exitstatus]
24
+ end
25
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: librarian-puppet-simple.haf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - ! '''Dan'
9
+ - Bode',
10
+ - ! '''haf'''
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2013-11-03 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: thor
18
+ requirement: !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: '0.15'
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ~>
30
+ - !ruby/object:Gem::Version
31
+ version: '0.15'
32
+ - !ruby/object:Gem::Dependency
33
+ name: rspec
34
+ requirement: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ~>
38
+ - !ruby/object:Gem::Version
39
+ version: '2.13'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '2.13'
48
+ description: ! "Simplify deployment of your Puppet infrastructure by\n automatically
49
+ pulling in modules from the forge and git repositories with\n a single command."
50
+ email:
51
+ - bodepd@gmail.com
52
+ executables:
53
+ - librarian-puppet
54
+ extensions: []
55
+ extra_rdoc_files: []
56
+ files:
57
+ - .gitignore
58
+ - Gemfile
59
+ - LICENSE
60
+ - README.md
61
+ - bin/librarian-puppet
62
+ - lib/librarian/puppet/simple.rb
63
+ - lib/librarian/puppet/simple/cli.rb
64
+ - lib/librarian/puppet/simple/installer.rb
65
+ - lib/librarian/puppet/simple/iterator.rb
66
+ - lib/librarian/puppet/simple/util.rb
67
+ - lib/librarian/puppet/simple/version.rb
68
+ - librarian-puppet-simple.haf.gemspec
69
+ - spec/fixtures/Puppetfile
70
+ - spec/functional/clean_spec.rb
71
+ - spec/functional/install_spec.rb
72
+ - spec/spec_helper.rb
73
+ homepage: https://github.com/haf/librarian-puppet-simple
74
+ licenses: []
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ! '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ! '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubyforge_project:
93
+ rubygems_version: 1.8.24
94
+ signing_key:
95
+ specification_version: 3
96
+ summary: Bundler for your Puppet modules. A fork until a new version is released by
97
+ Dan.
98
+ test_files:
99
+ - spec/fixtures/Puppetfile
100
+ - spec/functional/clean_spec.rb
101
+ - spec/functional/install_spec.rb
102
+ - spec/spec_helper.rb