puppet-module 0.3.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/CHANGES.markdown +91 -0
- data/LICENSE +17 -0
- data/README.markdown +221 -0
- data/Rakefile +87 -0
- data/VERSION +1 -0
- data/bin/puppet-module +7 -0
- data/lib/puppet/module/tool.rb +124 -0
- data/lib/puppet/module/tool/applications.rb +18 -0
- data/lib/puppet/module/tool/applications/application.rb +83 -0
- data/lib/puppet/module/tool/applications/builder.rb +88 -0
- data/lib/puppet/module/tool/applications/checksummer.rb +38 -0
- data/lib/puppet/module/tool/applications/cleaner.rb +14 -0
- data/lib/puppet/module/tool/applications/freezer.rb +20 -0
- data/lib/puppet/module/tool/applications/generator.rb +117 -0
- data/lib/puppet/module/tool/applications/installer.rb +83 -0
- data/lib/puppet/module/tool/applications/registrar.rb +34 -0
- data/lib/puppet/module/tool/applications/releaser.rb +48 -0
- data/lib/puppet/module/tool/applications/searcher.rb +34 -0
- data/lib/puppet/module/tool/applications/unpacker.rb +69 -0
- data/lib/puppet/module/tool/applications/unreleaser.rb +42 -0
- data/lib/puppet/module/tool/cache.rb +56 -0
- data/lib/puppet/module/tool/checksums.rb +52 -0
- data/lib/puppet/module/tool/cli.rb +127 -0
- data/lib/puppet/module/tool/contents_description.rb +84 -0
- data/lib/puppet/module/tool/dependency.rb +26 -0
- data/lib/puppet/module/tool/metadata.rb +80 -0
- data/lib/puppet/module/tool/modulefile.rb +47 -0
- data/lib/puppet/module/tool/repository.rb +74 -0
- data/lib/puppet/module/tool/skeleton.rb +39 -0
- data/lib/puppet/module/tool/utils.rb +9 -0
- data/lib/puppet/module/tool/utils/interrogation.rb +39 -0
- data/lib/puppet/module/tool/utils/settings.rb +36 -0
- data/lib/puppet/module/tool/utils/uri.rb +16 -0
- data/spec/fixtures/releases/jamtur01-apache/Modulefile +2 -0
- data/spec/fixtures/releases/jamtur01-apache/files/httpd +24 -0
- data/spec/fixtures/releases/jamtur01-apache/files/test.vhost +18 -0
- data/spec/fixtures/releases/jamtur01-apache/lib/puppet/provider/a2mod/debian.rb +21 -0
- data/spec/fixtures/releases/jamtur01-apache/lib/puppet/type/a2mod.rb +12 -0
- data/spec/fixtures/releases/jamtur01-apache/manifests/dev.pp +5 -0
- data/spec/fixtures/releases/jamtur01-apache/manifests/init.pp +34 -0
- data/spec/fixtures/releases/jamtur01-apache/manifests/params.pp +17 -0
- data/spec/fixtures/releases/jamtur01-apache/manifests/php.pp +5 -0
- data/spec/fixtures/releases/jamtur01-apache/manifests/ssl.pp +15 -0
- data/spec/fixtures/releases/jamtur01-apache/manifests/vhost.pp +15 -0
- data/spec/fixtures/releases/jamtur01-apache/metadata.json +1 -0
- data/spec/fixtures/releases/jamtur01-apache/templates/vhost-default.conf.erb +20 -0
- data/spec/fixtures/releases/jamtur01-apache/tests/apache.pp +1 -0
- data/spec/fixtures/releases/jamtur01-apache/tests/dev.pp +1 -0
- data/spec/fixtures/releases/jamtur01-apache/tests/init.pp +1 -0
- data/spec/fixtures/releases/jamtur01-apache/tests/php.pp +1 -0
- data/spec/fixtures/releases/jamtur01-apache/tests/ssl.pp +1 -0
- data/spec/fixtures/releases/jamtur01-apache/tests/vhost.pp +2 -0
- data/spec/integration/cli_spec.rb +373 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/output_support.rb +19 -0
- data/spec/support/stub_http_support.rb +14 -0
- data/spec/support/testdir_support.rb +26 -0
- data/spec/unit/application_spec.rb +25 -0
- data/spec/unit/repository_spec.rb +51 -0
- data/templates/generator/Modulefile.erb +5 -0
- data/templates/generator/README.erb +3 -0
- data/templates/generator/files/README.markdown +22 -0
- data/templates/generator/lib/puppet/facter/README.markdown +22 -0
- data/templates/generator/lib/puppet/parser/functions/README.markdown +17 -0
- data/templates/generator/lib/puppet/provider/README.markdown +14 -0
- data/templates/generator/lib/puppet/type/README.markdown +14 -0
- data/templates/generator/manifests/README.markdown +28 -0
- data/templates/generator/manifests/init.pp.erb +17 -0
- data/templates/generator/metadata.json +12 -0
- data/templates/generator/spec/README.markdown +7 -0
- data/templates/generator/spec/spec.opts +6 -0
- data/templates/generator/spec/spec_helper.rb +18 -0
- data/templates/generator/spec/unit/puppet/provider/README.markdown +4 -0
- data/templates/generator/spec/unit/puppet/type/README.markdown +4 -0
- data/templates/generator/templates/README.markdown +23 -0
- data/templates/generator/tests/init.pp.erb +1 -0
- data/vendor/facets-2.8.2-partial/lib/facets/kernel/returning.rb +23 -0
- data/vendor/facets-2.8.2-partial/lib/facets/kernel/tap.rb +39 -0
- data/vendor/multipart-post-1.0/Manifest.txt +9 -0
- data/vendor/multipart-post-1.0/README.txt +61 -0
- data/vendor/multipart-post-1.0/Rakefile +21 -0
- data/vendor/multipart-post-1.0/lib/composite_io.rb +89 -0
- data/vendor/multipart-post-1.0/lib/multipartable.rb +13 -0
- data/vendor/multipart-post-1.0/lib/net/http/post/multipart.rb +27 -0
- data/vendor/multipart-post-1.0/lib/parts.rb +66 -0
- data/vendor/multipart-post-1.0/test/net/http/post/test_multipart.rb +55 -0
- data/vendor/multipart-post-1.0/test/test_composite_io.rb +50 -0
- data/vendor/thor-852190ae/CHANGELOG.rdoc +89 -0
- data/vendor/thor-852190ae/LICENSE +20 -0
- data/vendor/thor-852190ae/README.rdoc +297 -0
- data/vendor/thor-852190ae/REVISION +1 -0
- data/vendor/thor-852190ae/Thorfile +69 -0
- data/vendor/thor-852190ae/bin/rake2thor +86 -0
- data/vendor/thor-852190ae/bin/thor +6 -0
- data/vendor/thor-852190ae/lib/thor.rb +244 -0
- data/vendor/thor-852190ae/lib/thor/actions.rb +275 -0
- data/vendor/thor-852190ae/lib/thor/actions/create_file.rb +103 -0
- data/vendor/thor-852190ae/lib/thor/actions/directory.rb +91 -0
- data/vendor/thor-852190ae/lib/thor/actions/empty_directory.rb +134 -0
- data/vendor/thor-852190ae/lib/thor/actions/file_manipulation.rb +223 -0
- data/vendor/thor-852190ae/lib/thor/actions/inject_into_file.rb +104 -0
- data/vendor/thor-852190ae/lib/thor/base.rb +540 -0
- data/vendor/thor-852190ae/lib/thor/core_ext/file_binary_read.rb +9 -0
- data/vendor/thor-852190ae/lib/thor/core_ext/hash_with_indifferent_access.rb +75 -0
- data/vendor/thor-852190ae/lib/thor/core_ext/ordered_hash.rb +100 -0
- data/vendor/thor-852190ae/lib/thor/error.rb +30 -0
- data/vendor/thor-852190ae/lib/thor/group.rb +271 -0
- data/vendor/thor-852190ae/lib/thor/invocation.rb +180 -0
- data/vendor/thor-852190ae/lib/thor/parser.rb +4 -0
- data/vendor/thor-852190ae/lib/thor/parser/argument.rb +67 -0
- data/vendor/thor-852190ae/lib/thor/parser/arguments.rb +150 -0
- data/vendor/thor-852190ae/lib/thor/parser/option.rb +128 -0
- data/vendor/thor-852190ae/lib/thor/parser/options.rb +169 -0
- data/vendor/thor-852190ae/lib/thor/rake_compat.rb +66 -0
- data/vendor/thor-852190ae/lib/thor/runner.rb +314 -0
- data/vendor/thor-852190ae/lib/thor/shell.rb +83 -0
- data/vendor/thor-852190ae/lib/thor/shell/basic.rb +239 -0
- data/vendor/thor-852190ae/lib/thor/shell/color.rb +108 -0
- data/vendor/thor-852190ae/lib/thor/task.rb +102 -0
- data/vendor/thor-852190ae/lib/thor/util.rb +230 -0
- data/vendor/thor-852190ae/lib/thor/version.rb +3 -0
- data/vendor/thor-852190ae/spec/actions/create_file_spec.rb +170 -0
- data/vendor/thor-852190ae/spec/actions/directory_spec.rb +131 -0
- data/vendor/thor-852190ae/spec/actions/empty_directory_spec.rb +91 -0
- data/vendor/thor-852190ae/spec/actions/file_manipulation_spec.rb +271 -0
- data/vendor/thor-852190ae/spec/actions/inject_into_file_spec.rb +135 -0
- data/vendor/thor-852190ae/spec/actions_spec.rb +292 -0
- data/vendor/thor-852190ae/spec/base_spec.rb +263 -0
- data/vendor/thor-852190ae/spec/core_ext/hash_with_indifferent_access_spec.rb +43 -0
- data/vendor/thor-852190ae/spec/core_ext/ordered_hash_spec.rb +115 -0
- data/vendor/thor-852190ae/spec/fixtures/application.rb +2 -0
- data/vendor/thor-852190ae/spec/fixtures/bundle/execute.rb +6 -0
- data/vendor/thor-852190ae/spec/fixtures/bundle/main.thor +1 -0
- data/vendor/thor-852190ae/spec/fixtures/doc/%file_name%.rb.tt +1 -0
- data/vendor/thor-852190ae/spec/fixtures/doc/README +3 -0
- data/vendor/thor-852190ae/spec/fixtures/doc/config.rb +1 -0
- data/vendor/thor-852190ae/spec/fixtures/group.thor +83 -0
- data/vendor/thor-852190ae/spec/fixtures/invoke.thor +112 -0
- data/vendor/thor-852190ae/spec/fixtures/script.thor +140 -0
- data/vendor/thor-852190ae/spec/fixtures/task.thor +10 -0
- data/vendor/thor-852190ae/spec/group_spec.rb +171 -0
- data/vendor/thor-852190ae/spec/invocation_spec.rb +107 -0
- data/vendor/thor-852190ae/spec/parser/argument_spec.rb +47 -0
- data/vendor/thor-852190ae/spec/parser/arguments_spec.rb +64 -0
- data/vendor/thor-852190ae/spec/parser/option_spec.rb +202 -0
- data/vendor/thor-852190ae/spec/parser/options_spec.rb +292 -0
- data/vendor/thor-852190ae/spec/rake_compat_spec.rb +68 -0
- data/vendor/thor-852190ae/spec/runner_spec.rb +202 -0
- data/vendor/thor-852190ae/spec/shell/basic_spec.rb +205 -0
- data/vendor/thor-852190ae/spec/shell/color_spec.rb +41 -0
- data/vendor/thor-852190ae/spec/shell_spec.rb +34 -0
- data/vendor/thor-852190ae/spec/spec.opts +1 -0
- data/vendor/thor-852190ae/spec/spec_helper.rb +54 -0
- data/vendor/thor-852190ae/spec/task_spec.rb +69 -0
- data/vendor/thor-852190ae/spec/thor_spec.rb +237 -0
- data/vendor/thor-852190ae/spec/util_spec.rb +167 -0
- data/vendor/thor-852190ae/thor.gemspec +120 -0
- metadata +229 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Puppet::Module::Tool
|
|
2
|
+
module Applications
|
|
3
|
+
|
|
4
|
+
require 'puppet/module/tool/applications/application'
|
|
5
|
+
require 'puppet/module/tool/applications/builder'
|
|
6
|
+
require 'puppet/module/tool/applications/checksummer'
|
|
7
|
+
require 'puppet/module/tool/applications/cleaner'
|
|
8
|
+
require 'puppet/module/tool/applications/freezer'
|
|
9
|
+
require 'puppet/module/tool/applications/generator'
|
|
10
|
+
require 'puppet/module/tool/applications/installer'
|
|
11
|
+
require 'puppet/module/tool/applications/registrar'
|
|
12
|
+
require 'puppet/module/tool/applications/releaser'
|
|
13
|
+
require 'puppet/module/tool/applications/searcher'
|
|
14
|
+
require 'puppet/module/tool/applications/unpacker'
|
|
15
|
+
require 'puppet/module/tool/applications/unreleaser'
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require 'net/http'
|
|
2
|
+
|
|
3
|
+
module Puppet::Module::Tool
|
|
4
|
+
module Applications
|
|
5
|
+
|
|
6
|
+
class Application
|
|
7
|
+
include Utils::Interrogation
|
|
8
|
+
|
|
9
|
+
def self.run(*args)
|
|
10
|
+
new(*args).run
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
attr_accessor :options
|
|
14
|
+
|
|
15
|
+
def initialize(options = {})
|
|
16
|
+
@options = options
|
|
17
|
+
Puppet::Module::Tool.prepare_settings(options)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def repository
|
|
21
|
+
@repository ||= Repository.new(Puppet.settings[:puppet_module_repository])
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def run
|
|
25
|
+
raise NotImplementedError, "Should be implemented in child classes."
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def discuss(response, success, failure)
|
|
29
|
+
case response
|
|
30
|
+
when Net::HTTPOK, Net::HTTPCreated
|
|
31
|
+
say success
|
|
32
|
+
else
|
|
33
|
+
errors = PSON.parse(response.body)['error'] rescue "HTTP #{response.code}, #{response.body}"
|
|
34
|
+
say "#{failure} (#{errors})"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def metadata(require_modulefile = false)
|
|
39
|
+
unless @metadata
|
|
40
|
+
unless @path
|
|
41
|
+
abort "Could not determine module path"
|
|
42
|
+
end
|
|
43
|
+
@metadata = Metadata.new
|
|
44
|
+
contents = ContentsDescription.new(@path)
|
|
45
|
+
contents.annotate(@metadata)
|
|
46
|
+
checksums = Checksums.new(@path)
|
|
47
|
+
checksums.annotate(@metadata)
|
|
48
|
+
modulefile_path = File.join(@path, 'Modulefile')
|
|
49
|
+
if File.file?(modulefile_path)
|
|
50
|
+
Modulefile.evaluate(@metadata, modulefile_path)
|
|
51
|
+
elsif require_modulefile
|
|
52
|
+
abort "No Modulefile found."
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
@metadata
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def load_modulefile!
|
|
59
|
+
@metadata = nil
|
|
60
|
+
metadata(true)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Use to extract and validate a module name and version from a
|
|
64
|
+
#filename
|
|
65
|
+
# Note: Must have @filename set to use this
|
|
66
|
+
def parse_filename!
|
|
67
|
+
@release_name = File.basename(@filename,'.tar.gz')
|
|
68
|
+
@username, @module_name, @version = @release_name.split('-', 3)
|
|
69
|
+
@full_name = [@username, @module_name].join('-')
|
|
70
|
+
unless @username && @module_name
|
|
71
|
+
abort "Username and Module name not provided"
|
|
72
|
+
end
|
|
73
|
+
begin
|
|
74
|
+
Gem::Version.new(@version)
|
|
75
|
+
rescue ArgumentError => e
|
|
76
|
+
abort "Invalid version format: #{@version}"
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
|
|
3
|
+
module Puppet::Module::Tool
|
|
4
|
+
|
|
5
|
+
module Applications
|
|
6
|
+
|
|
7
|
+
class Builder < Application
|
|
8
|
+
|
|
9
|
+
def initialize(path, options)
|
|
10
|
+
@path = File.expand_path(path)
|
|
11
|
+
@pkg_path = File.join(@path, 'pkg')
|
|
12
|
+
super(options)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def run
|
|
16
|
+
load_modulefile!
|
|
17
|
+
create_directory
|
|
18
|
+
copy_contents
|
|
19
|
+
add_metadata
|
|
20
|
+
header "Building #{@path} for release"
|
|
21
|
+
tar
|
|
22
|
+
gzip
|
|
23
|
+
relative = Pathname.new(File.join(@pkg_path, filename('tar.gz'))).relative_path_from(Pathname.new(Dir.pwd))
|
|
24
|
+
# TODO Implement "release" feature.
|
|
25
|
+
### say "Done. Now you probably want to:\n $ puppet-module release #{relative}"
|
|
26
|
+
say "Done. Built: #{relative}"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def filename(ext)
|
|
32
|
+
ext.sub!(/^\./, '')
|
|
33
|
+
"#{metadata.release_name}.#{ext}"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def tar
|
|
37
|
+
tar_name = filename('tar')
|
|
38
|
+
Dir.chdir(@pkg_path) do
|
|
39
|
+
FileUtils.rm tar_name rescue nil
|
|
40
|
+
unless system "tar -cf #{tar_name} #{metadata.release_name}"
|
|
41
|
+
abort "Could not create #{tar_name}"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def gzip
|
|
47
|
+
Dir.chdir(@pkg_path) do
|
|
48
|
+
FileUtils.rm filename('tar.gz') rescue nil
|
|
49
|
+
unless system "gzip #{filename('tar')}"
|
|
50
|
+
abort "Could not compress #{filename('tar')}"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def create_directory
|
|
56
|
+
FileUtils.mkdir(@pkg_path) rescue nil
|
|
57
|
+
if File.directory?(build_path)
|
|
58
|
+
FileUtils.rm_rf(build_path)
|
|
59
|
+
end
|
|
60
|
+
FileUtils.mkdir(build_path)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def copy_contents
|
|
64
|
+
Dir[File.join(@path, '*')].each do |path|
|
|
65
|
+
case File.basename(path)
|
|
66
|
+
when *Puppet::Module::Tool::ARTIFACTS
|
|
67
|
+
next
|
|
68
|
+
else
|
|
69
|
+
FileUtils.cp_r path, build_path
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def add_metadata
|
|
75
|
+
File.open(File.join(build_path, 'metadata.json'), 'w') do |f|
|
|
76
|
+
f.write(PSON.pretty_generate(metadata))
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def build_path
|
|
81
|
+
@build_path ||= File.join(@pkg_path, metadata.release_name)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Puppet::Module::Tool
|
|
2
|
+
module Applications
|
|
3
|
+
|
|
4
|
+
class Checksummer < Application
|
|
5
|
+
|
|
6
|
+
def initialize(path, options = {})
|
|
7
|
+
@path = Pathname.new(path)
|
|
8
|
+
super(options)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def run
|
|
12
|
+
if metadata_file.exist?
|
|
13
|
+
sums = Checksums.new(@path)
|
|
14
|
+
(metadata['checksums'] || {}).each do |child_path, canonical_checksum|
|
|
15
|
+
path = @path + child_path
|
|
16
|
+
if canonical_checksum != sums.checksum(path)
|
|
17
|
+
say child_path
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
else
|
|
21
|
+
abort "No metadata.json found."
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def metadata
|
|
28
|
+
PSON.parse(metadata_file.read)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def metadata_file
|
|
32
|
+
(@path + 'metadata.json')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Puppet::Module::Tool
|
|
2
|
+
module Applications
|
|
3
|
+
|
|
4
|
+
class Freezer < Application
|
|
5
|
+
# TODO Review whether the 'freeze' feature should be fixed or deleted.
|
|
6
|
+
=begin
|
|
7
|
+
def skeleton
|
|
8
|
+
@skeleton ||= Skeleton.new
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def run
|
|
12
|
+
header "Freezing in #{skeleton.custom_path}"
|
|
13
|
+
skeleton.freeze!
|
|
14
|
+
say "Done. Modify these files for the `generate` task."
|
|
15
|
+
end
|
|
16
|
+
=end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
require 'pathname'
|
|
2
|
+
require 'fileutils'
|
|
3
|
+
require 'erb'
|
|
4
|
+
|
|
5
|
+
module Puppet::Module::Tool
|
|
6
|
+
module Applications
|
|
7
|
+
|
|
8
|
+
class Generator < Application
|
|
9
|
+
|
|
10
|
+
def initialize(full_name, options)
|
|
11
|
+
begin
|
|
12
|
+
@metadata = Metadata.new(:full_name => full_name)
|
|
13
|
+
rescue ArgumentError
|
|
14
|
+
abort "Could not generate directory #{full_name.inspect}, you must specify a dash-separated username and module name."
|
|
15
|
+
end
|
|
16
|
+
super(options)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def skeleton
|
|
20
|
+
@skeleton ||= Skeleton.new
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def run
|
|
24
|
+
if destination.directory?
|
|
25
|
+
abort "#{destination} already exists."
|
|
26
|
+
end
|
|
27
|
+
header "Generating module at #{Dir.pwd}/#{@metadata.dashed_name}"
|
|
28
|
+
skeleton.path.find do |path|
|
|
29
|
+
if path == skeleton
|
|
30
|
+
destination.mkpath
|
|
31
|
+
else
|
|
32
|
+
node = Node.on(path, self)
|
|
33
|
+
if node
|
|
34
|
+
node.install!
|
|
35
|
+
say node.target
|
|
36
|
+
else
|
|
37
|
+
say "Could not generate from #{path}"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def destination
|
|
44
|
+
@destination ||= Pathname.new(@metadata.dashed_name)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
class Node
|
|
48
|
+
def self.types
|
|
49
|
+
@types ||= []
|
|
50
|
+
end
|
|
51
|
+
def self.inherited(klass)
|
|
52
|
+
types << klass
|
|
53
|
+
end
|
|
54
|
+
def self.on(path, generator)
|
|
55
|
+
klass = types.detect { |t| t.matches?(path) }
|
|
56
|
+
if klass
|
|
57
|
+
klass.new(path, generator)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
def initialize(source, generator)
|
|
61
|
+
@generator = generator
|
|
62
|
+
@source = source
|
|
63
|
+
end
|
|
64
|
+
def read
|
|
65
|
+
@source.read
|
|
66
|
+
end
|
|
67
|
+
def target
|
|
68
|
+
target = @generator.destination + @source.relative_path_from(@generator.skeleton.path)
|
|
69
|
+
components = target.to_s.split(File::SEPARATOR).map do |part|
|
|
70
|
+
part == 'NAME' ? @generator.metadata.name : part
|
|
71
|
+
end
|
|
72
|
+
Pathname.new(components.join(File::SEPARATOR))
|
|
73
|
+
end
|
|
74
|
+
def install!
|
|
75
|
+
raise NotImplementedError, "Abstract"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
class DirectoryNode < Node
|
|
80
|
+
def self.matches?(path)
|
|
81
|
+
path.directory?
|
|
82
|
+
end
|
|
83
|
+
def install!
|
|
84
|
+
target.mkpath
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
class ParsedFileNode < Node
|
|
89
|
+
def self.matches?(path)
|
|
90
|
+
path.file? && path.extname == '.erb'
|
|
91
|
+
end
|
|
92
|
+
def target
|
|
93
|
+
path = super
|
|
94
|
+
path.parent + path.basename('.erb')
|
|
95
|
+
end
|
|
96
|
+
def contents
|
|
97
|
+
template = ERB.new(read)
|
|
98
|
+
template.result(@generator.send(:binding))
|
|
99
|
+
end
|
|
100
|
+
def install!
|
|
101
|
+
target.open('w') { |f| f.write contents }
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
class FileNode < Node
|
|
106
|
+
def self.matches?(path)
|
|
107
|
+
path.file?
|
|
108
|
+
end
|
|
109
|
+
def install!
|
|
110
|
+
FileUtils.cp(@source, target)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require 'open-uri'
|
|
2
|
+
require 'pathname'
|
|
3
|
+
require 'tmpdir'
|
|
4
|
+
|
|
5
|
+
module Puppet::Module::Tool
|
|
6
|
+
|
|
7
|
+
module Applications
|
|
8
|
+
|
|
9
|
+
class Installer < Application
|
|
10
|
+
|
|
11
|
+
def initialize(name, options = {})
|
|
12
|
+
if File.exist?(name)
|
|
13
|
+
if File.directory?(name)
|
|
14
|
+
# TODO Unify this handling with that of Unpacker#check_clobber!
|
|
15
|
+
abort "Module already installed: #{name}"
|
|
16
|
+
end
|
|
17
|
+
@source = :filesystem
|
|
18
|
+
@filename = File.expand_path(name)
|
|
19
|
+
parse_filename!
|
|
20
|
+
else
|
|
21
|
+
@source = :repository
|
|
22
|
+
begin
|
|
23
|
+
@username, @module_name = Puppet::Module::Tool::username_and_modname_from(name)
|
|
24
|
+
rescue ArgumentError
|
|
25
|
+
abort "Could not install module with invalid name: #{name}"
|
|
26
|
+
end
|
|
27
|
+
@version_requirement = options[:version]
|
|
28
|
+
end
|
|
29
|
+
super(options)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def force?
|
|
33
|
+
options[:force]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def run
|
|
37
|
+
case @source
|
|
38
|
+
when :repository
|
|
39
|
+
if match['file']
|
|
40
|
+
begin
|
|
41
|
+
cache_path = repository.retrieve(match['file'])
|
|
42
|
+
rescue OpenURI::HTTPError => e
|
|
43
|
+
abort "Could not install module: #{e.message}"
|
|
44
|
+
end
|
|
45
|
+
Unpacker.run(cache_path, Dir.pwd, options)
|
|
46
|
+
else
|
|
47
|
+
abort "Malformed response from module repository."
|
|
48
|
+
end
|
|
49
|
+
when :filesystem
|
|
50
|
+
repository = Repository.new('file:///')
|
|
51
|
+
uri = URI.parse("file://#{File.expand_path(@filename)}")
|
|
52
|
+
cache_path = repository.retrieve(uri)
|
|
53
|
+
Unpacker.run(cache_path, Dir.pwd, options)
|
|
54
|
+
else
|
|
55
|
+
abort "Could not determine installation source"
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def match
|
|
62
|
+
return @match ||= begin
|
|
63
|
+
url = repository.uri + "/users/#{@username}/modules/#{@module_name}/releases/find.json"
|
|
64
|
+
if @version_requirement
|
|
65
|
+
url.query = "version=#{URI.escape(@version_requirement)}"
|
|
66
|
+
end
|
|
67
|
+
begin
|
|
68
|
+
raw_result = read_match(url)
|
|
69
|
+
rescue => e
|
|
70
|
+
abort "Could not request version match (#{e.message})"
|
|
71
|
+
end
|
|
72
|
+
@match = PSON.parse(raw_result)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def read_match(url)
|
|
77
|
+
return url.read
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
end
|
|
83
|
+
end
|