packer-binary 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -0
- data/.rubocop_todo.yml +18 -0
- data/.yardopts +3 -0
- data/Gemfile +2 -2
- data/README.md +7 -11
- data/Rakefile +3 -3
- data/bin/console +3 -3
- data/lib/packer/binary.rb +51 -20
- data/lib/packer/binary/command.rb +12 -1
- data/lib/packer/binary/compressor.rb +16 -21
- data/lib/packer/binary/executable.rb +24 -11
- data/lib/packer/binary/helpers.rb +6 -2
- data/lib/packer/binary/version.rb +5 -1
- data/packer-binary.gemspec +14 -12
- metadata +20 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5873799b8897ad2c339a83886a1761188d62995c
|
4
|
+
data.tar.gz: 71c9bfff2134207674d6b8b66ede36c8725d4fe6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 01b015e3e484fd0243b7355a6efe2f8c71af312b635e6030058d390a1074f1ec7e4ddda35c73e56e1049981f2c1f7c80bbad4064456e35008ceff6522a663204
|
7
|
+
data.tar.gz: 6b86a57a41bf451eb50017bbf6e872331d2d8cb114dec579ae4c209c794dcbe26ffcb622989e4dd77c87d656fc073368e7e1807f39aa0a5e34c8fe390ee514f0
|
data/.rubocop.yml
ADDED
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2017-09-05 13:53:42 -0400 using RuboCop version 0.49.1.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 15
|
10
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
11
|
+
# URISchemes: http, https
|
12
|
+
Metrics/LineLength:
|
13
|
+
Max: 113
|
14
|
+
|
15
|
+
# Offense count: 1
|
16
|
+
# Configuration parameters: CountComments.
|
17
|
+
Metrics/MethodLength:
|
18
|
+
Max: 13
|
data/.yardopts
ADDED
data/Gemfile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
3
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
4
4
|
|
5
5
|
# Specify your gem's dependencies in packer-binary.gemspec
|
6
6
|
gemspec
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
[![Gem Version](https://badge.fury.io/rb/packer-binary.svg)](https://badge.fury.io/rb/packer-binary)
|
2
2
|
[![Build Status](https://travis-ci.org/NathanTCz/packer-binary.svg?branch=master)](https://travis-ci.org/NathanTCz/packer-binary)
|
3
3
|
[![Coverage Status](https://coveralls.io/repos/github/NathanTCz/packer-binary/badge.svg?branch=master)](https://coveralls.io/github/NathanTCz/packer-binary?branch=master)
|
4
|
-
[![
|
4
|
+
[![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://www.rubydoc.info/gems/packer-binary)
|
5
5
|
|
6
6
|
# Packer::Binary
|
7
7
|
|
@@ -35,18 +35,14 @@ Packer::Binary.configure do |config|
|
|
35
35
|
end
|
36
36
|
```
|
37
37
|
|
38
|
-
###
|
39
|
-
{Packer::Binary
|
38
|
+
### Dynamic Methods
|
39
|
+
The {Packer::Binary} module will automagically map method calls to `packer` commands. This serves to better support future versions of `packer` and potentially new commands. For example, the equivalent of `packer build test.json` in Ruby:
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
{Packer::Binary.Push} - Run the `push` command. Optionally pass any arguments supported by Packer.
|
46
|
-
|
47
|
-
{Packer::Binary.Validate} - Run the `validate` command. Optionally pass any arguments supported by Packer.
|
41
|
+
```ruby
|
42
|
+
Packer::Binary.build('test.json')
|
43
|
+
```
|
48
44
|
|
49
|
-
|
45
|
+
If you call a method not supported by the `packer` binary, you will get a {Packer::Binary::Command::CommandFailure} exception.
|
50
46
|
|
51
47
|
## Development
|
52
48
|
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'packer/binary'
|
5
5
|
|
6
6
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
7
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -10,5 +10,5 @@ require "packer/binary"
|
|
10
10
|
# require "pry"
|
11
11
|
# Pry.start
|
12
12
|
|
13
|
-
require
|
13
|
+
require 'irb'
|
14
14
|
IRB.start(__FILE__)
|
data/lib/packer/binary.rb
CHANGED
@@ -1,55 +1,86 @@
|
|
1
1
|
require 'os'
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'packer/binary/version'
|
4
4
|
require 'packer/binary/helpers'
|
5
5
|
require 'packer/binary/compressor'
|
6
6
|
require 'packer/binary/executable'
|
7
7
|
require 'packer/binary/command'
|
8
8
|
|
9
|
+
# This module handles downloading and extracting of the associated binary as well
|
10
|
+
# as providing a dynamic namespace and ruby client for sub-commands of said binary
|
9
11
|
module Packer
|
12
|
+
# The Binary namespace handles sub-commands using {#method_missing} metaprogramming
|
13
|
+
# as well as the global configuration object
|
10
14
|
module Binary
|
11
|
-
|
12
|
-
|
15
|
+
# @!attribute config
|
16
|
+
# @return [Configuration] the global configuration object
|
13
17
|
attr_writer :config
|
14
18
|
|
19
|
+
module_function
|
20
|
+
|
21
|
+
# defines the @config class variable
|
15
22
|
def config
|
16
23
|
@config ||= Configuration.new
|
17
24
|
end
|
18
25
|
|
26
|
+
# Set the global settings. See the {file:README.md README} for more information
|
19
27
|
def configure
|
20
28
|
yield(config)
|
21
29
|
end
|
22
30
|
|
23
|
-
|
24
|
-
|
31
|
+
# This method maps Packer::Binary method calls to Packer sub-commands
|
32
|
+
# Ex. to run `packer build test.json -machine-readable`:
|
33
|
+
#
|
34
|
+
# ```ruby
|
35
|
+
# Packer::Binary.build('test.json -machine-readable')
|
36
|
+
# ```
|
37
|
+
#
|
38
|
+
# @note if the method is an invalid sub-command or if the command fails
|
39
|
+
# you will get a {Command::CommandFailure} exception
|
40
|
+
# @since 0.2.0
|
41
|
+
def method_missing(method, *args, &block)
|
42
|
+
if method.to_s =~ /(\w+)/
|
43
|
+
Command.run("#{method.to_s.downcase} #{args}")
|
44
|
+
else
|
45
|
+
super
|
46
|
+
end
|
25
47
|
end
|
26
48
|
|
27
|
-
def
|
28
|
-
|
49
|
+
def respond_to_missing?(method, *)
|
50
|
+
method =~ /(\w+)/ || super
|
29
51
|
end
|
30
52
|
|
31
|
-
|
32
|
-
|
33
|
-
end
|
53
|
+
# @deprecated Use {#method_missing} dynamic method handling for
|
54
|
+
# binary sub-commands
|
55
|
+
def Build; end
|
34
56
|
|
35
|
-
|
36
|
-
|
37
|
-
end
|
57
|
+
# @deprecated Use {#method_missing} dynamic method handling for
|
58
|
+
# binary sub-commands
|
59
|
+
def Fix; end
|
38
60
|
|
39
|
-
|
40
|
-
|
41
|
-
end
|
61
|
+
# @deprecated Use {#method_missing} dynamic method handling for
|
62
|
+
# binary sub-commands
|
63
|
+
def Inspect; end
|
42
64
|
|
43
|
-
|
44
|
-
|
45
|
-
end
|
65
|
+
# @deprecated Use {#method_missing} dynamic method handling for
|
66
|
+
# binary sub-commands
|
67
|
+
def Push; end
|
68
|
+
|
69
|
+
# @deprecated Use {#method_missing} dynamic method handling for
|
70
|
+
# binary sub-commands
|
71
|
+
def Validate; end
|
72
|
+
|
73
|
+
# @deprecated Use {#method_missing} dynamic method handling for
|
74
|
+
# binary sub-commands
|
75
|
+
def Version; end
|
46
76
|
|
77
|
+
# This class holds the global configuration items
|
47
78
|
class Configuration
|
48
79
|
attr_accessor :version
|
49
80
|
attr_accessor :download_path
|
50
81
|
|
51
82
|
def initialize
|
52
|
-
@version =
|
83
|
+
@version = PACKER_VERSION
|
53
84
|
@download_path = '/tmp'
|
54
85
|
end
|
55
86
|
end
|
@@ -1,15 +1,26 @@
|
|
1
1
|
module Packer
|
2
2
|
module Binary
|
3
|
+
# This module handles running the actual CLI commands
|
3
4
|
module Command
|
4
5
|
module_function
|
5
6
|
|
7
|
+
# Raised when a command either fails or is invalid
|
8
|
+
class CommandFailure < StandardError; end
|
9
|
+
|
10
|
+
# Runs the given command with `Core::Kernel.system`
|
11
|
+
# Example `run('sub-command -var "key=value" -machine-readable')`
|
12
|
+
# @param [String] command the full sub-command to run (including cli arguments)
|
13
|
+
# @return [String] true or {CommandFailure}
|
6
14
|
def run(command)
|
7
|
-
system("#{binary} #{command}")
|
15
|
+
system("#{binary} #{command}") || (raise CommandFailure)
|
8
16
|
end
|
9
17
|
|
18
|
+
# Downloads, extracts and returns the path to the binary
|
19
|
+
# @return [String] absolute path of the binary
|
10
20
|
def binary
|
11
21
|
e = Executable.new
|
12
22
|
e.download
|
23
|
+
e.extract
|
13
24
|
e.binary
|
14
25
|
end
|
15
26
|
end
|
@@ -1,30 +1,24 @@
|
|
1
|
-
# This is a simple example which uses rubyzip to
|
2
|
-
# recursively generate a zip file from the contents of
|
3
|
-
# a specified directory. The directory itself is not
|
4
|
-
# included in the archive, rather just its contents.
|
5
|
-
#
|
6
|
-
# Usage:
|
7
|
-
# directoryToZip = "/tmp/input"
|
8
|
-
# output_file = "/tmp/out.zip"
|
9
|
-
# zf = Zip.new(directoryToZip, output_file)
|
10
|
-
# zf.write()
|
11
1
|
require 'zip'
|
12
2
|
|
13
3
|
module Packer
|
14
4
|
module Binary
|
5
|
+
# This class is used to zip and unzip files and directories
|
15
6
|
class Compressor
|
16
7
|
class << self
|
17
8
|
include Packer::Binary::Helpers
|
18
9
|
|
19
10
|
# Zip the input directory.
|
20
11
|
def write(input_dir, output_file)
|
21
|
-
entries = Dir.entries(input_dir)
|
22
|
-
|
12
|
+
entries = Dir.entries(input_dir)
|
13
|
+
entries.delete('.')
|
14
|
+
entries.delete('..')
|
15
|
+
io = Zip::File.open(output_file, Zip::File::CREATE)
|
23
16
|
|
24
|
-
write_entries(entries,
|
25
|
-
io.close
|
17
|
+
write_entries(entries, '', io, input_dir, output_file)
|
18
|
+
io.close
|
26
19
|
end
|
27
20
|
|
21
|
+
# Unzip the input zipfile
|
28
22
|
def extract(input_file, output_dir)
|
29
23
|
Zip::File.open(input_file) do |zip_file|
|
30
24
|
# Handle entries one by one
|
@@ -41,19 +35,20 @@ module Packer
|
|
41
35
|
|
42
36
|
# A helper method to make the recursion work.
|
43
37
|
def write_entries(entries, path, io, input_dir, output_file)
|
44
|
-
|
45
|
-
|
46
|
-
zip_file_path = path == "" ? e : File.join(path, e)
|
38
|
+
entries.each do |e|
|
39
|
+
zip_file_path = path == '' ? e : File.join(path, e)
|
47
40
|
disk_file_path = File.join(input_dir, zip_file_path)
|
48
41
|
|
49
|
-
if
|
42
|
+
if File.directory?(disk_file_path)
|
50
43
|
io.mkdir(zip_file_path)
|
51
|
-
subdir =Dir.entries(disk_file_path)
|
44
|
+
subdir = Dir.entries(disk_file_path)
|
45
|
+
subdir.delete('.')
|
46
|
+
subdir.delete('..')
|
52
47
|
write_entries(subdir, zip_file_path, io, input_dir, output_file)
|
53
48
|
else
|
54
|
-
io.get_output_stream(zip_file_path) { |f| f.puts(File.open(disk_file_path,
|
49
|
+
io.get_output_stream(zip_file_path) { |f| f.puts(File.open(disk_file_path, 'rb').read) }
|
55
50
|
end
|
56
|
-
|
51
|
+
end
|
57
52
|
end
|
58
53
|
end
|
59
54
|
end
|
@@ -1,8 +1,18 @@
|
|
1
1
|
module Packer
|
2
2
|
module Binary
|
3
|
+
# This class handles downloading, extracting, and saving the associated
|
4
|
+
# binary file
|
3
5
|
class Executable
|
4
6
|
include Packer::Binary::Helpers
|
5
7
|
|
8
|
+
# Raised when the current platform is unsupported
|
9
|
+
class PlatformUnsupported < StandardError; end
|
10
|
+
|
11
|
+
# The download URI for the binary package
|
12
|
+
PACKER_DOWNLOAD_URI = 'releases.hashicorp.com'.freeze
|
13
|
+
|
14
|
+
# Loads global config values and creates the download directory if the
|
15
|
+
# current platform is supported
|
6
16
|
def initialize
|
7
17
|
@packer_version = Packer::Binary.config.version
|
8
18
|
@download_path = "#{Packer::Binary.config.download_path.chomp('/')}/packer-binary/#{@packer_version}/bin"
|
@@ -10,28 +20,36 @@ module Packer
|
|
10
20
|
|
11
21
|
FileUtils.mkdir_p @download_path
|
12
22
|
|
13
|
-
raise
|
23
|
+
raise PlatformUnsupported unless supported?
|
14
24
|
end
|
15
25
|
|
26
|
+
# Returns the path to the binary if it exists
|
27
|
+
# @return [String] absolute path of the binary
|
16
28
|
def binary
|
17
29
|
Dir["#{@download_path}/packer*"][0]
|
18
30
|
end
|
19
31
|
|
32
|
+
# Downloads the zipfile from the origin
|
20
33
|
def download
|
21
|
-
return
|
34
|
+
return if binary_exist?
|
22
35
|
|
23
36
|
msg("Downloading https://#{download_domain}/#{download_uri}")
|
24
37
|
|
25
38
|
require 'open-uri'
|
26
39
|
|
27
|
-
File.open("#{@download_path}/#{@download_filename}",
|
40
|
+
File.open("#{@download_path}/#{@download_filename}", 'wb') do |saved_file|
|
28
41
|
# the following "open" is provided by open-uri
|
29
|
-
open("https://#{download_domain}/#{download_uri}",
|
42
|
+
open("https://#{download_domain}/#{download_uri}", 'rb') do |read_file|
|
30
43
|
saved_file.write(read_file.read)
|
31
44
|
end
|
32
45
|
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Extracts the binary from the zipfile and makes it executable
|
49
|
+
def extract
|
50
|
+
return if binary_exist?
|
33
51
|
|
34
|
-
extract
|
52
|
+
Compressor.extract("#{@download_path}/#{@download_filename}", @download_path)
|
35
53
|
make_exe
|
36
54
|
end
|
37
55
|
|
@@ -49,10 +67,6 @@ module Packer
|
|
49
67
|
FileUtils.chmod('a+x', binary) if binary_exist?
|
50
68
|
end
|
51
69
|
|
52
|
-
def extract
|
53
|
-
Compressor::extract("#{@download_path}/#{@download_filename}", @download_path)
|
54
|
-
end
|
55
|
-
|
56
70
|
def download_uri
|
57
71
|
"packer/#{@packer_version}/packer_#{@packer_version}_freebsd_amd64.zip" if OS.freebsd?
|
58
72
|
"packer/#{@packer_version}/packer_#{@packer_version}_darwin_amd64.zip" if OS.mac?
|
@@ -61,9 +75,8 @@ module Packer
|
|
61
75
|
end
|
62
76
|
|
63
77
|
def download_domain
|
64
|
-
|
78
|
+
PACKER_DOWNLOAD_URI
|
65
79
|
end
|
66
|
-
|
67
80
|
end
|
68
81
|
end
|
69
82
|
end
|
@@ -1,29 +1,33 @@
|
|
1
1
|
module Packer
|
2
2
|
module Binary
|
3
|
+
# Generic helper methods
|
3
4
|
module Helpers
|
4
5
|
module_function
|
5
6
|
|
6
|
-
#
|
7
7
|
# Runs given commands using mixlib-shellout
|
8
|
-
#
|
9
8
|
def system_command(*command_args)
|
10
9
|
cmd = Mixlib::ShellOut.new(*command_args)
|
11
10
|
cmd.run_command
|
12
11
|
cmd
|
13
12
|
end
|
14
13
|
|
14
|
+
# prints to `stderr`
|
15
15
|
def err(message)
|
16
16
|
stderr.print("#{message}\n")
|
17
17
|
end
|
18
18
|
|
19
|
+
# prints to `stdout`
|
19
20
|
def msg(message)
|
20
21
|
stdout.print("#{message}\n")
|
21
22
|
end
|
22
23
|
|
24
|
+
# prints to `stfout` if `ENV['DEBUG']` is set
|
23
25
|
def debug(message)
|
24
26
|
stdout.print("#{message}\n") if ENV['DEBUG']
|
25
27
|
end
|
26
28
|
|
29
|
+
private
|
30
|
+
|
27
31
|
def stdout
|
28
32
|
$stdout
|
29
33
|
end
|
data/packer-binary.gemspec
CHANGED
@@ -1,28 +1,30 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
5
|
+
require 'packer/binary/version'
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
8
|
+
spec.name = 'packer-binary'
|
8
9
|
spec.version = Packer::Binary::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
10
|
+
spec.authors = ['Nathan Cazell']
|
11
|
+
spec.email = ['nathan.cazell@imageapi.com']
|
11
12
|
|
12
|
-
spec.summary =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
13
|
+
spec.summary = "A gem to install and interface with HashiCorp's Packer utility"
|
14
|
+
spec.homepage = 'https://github.com/nathantcz/packer-binary'
|
15
|
+
spec.license = 'MIT'
|
15
16
|
|
16
17
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
18
|
f.match(%r{^(test|spec|features)/})
|
18
19
|
end
|
19
20
|
|
20
|
-
spec.require_paths = [
|
21
|
+
spec.require_paths = ['lib']
|
21
22
|
|
22
|
-
spec.add_development_dependency
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.15'
|
23
24
|
spec.add_development_dependency 'pry'
|
24
|
-
spec.add_development_dependency
|
25
|
-
spec.add_development_dependency
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
27
|
+
spec.add_development_dependency 'rubocop', '~> 0.49'
|
26
28
|
spec.add_development_dependency 'yard'
|
27
29
|
spec.add_development_dependency 'coveralls'
|
28
30
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: packer-binary
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Cazell
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-09-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.49'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.49'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: yard
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -131,7 +145,10 @@ extra_rdoc_files: []
|
|
131
145
|
files:
|
132
146
|
- ".gitignore"
|
133
147
|
- ".rspec"
|
148
|
+
- ".rubocop.yml"
|
149
|
+
- ".rubocop_todo.yml"
|
134
150
|
- ".travis.yml"
|
151
|
+
- ".yardopts"
|
135
152
|
- Gemfile
|
136
153
|
- LICENSE.txt
|
137
154
|
- README.md
|
@@ -165,7 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
165
182
|
version: '0'
|
166
183
|
requirements: []
|
167
184
|
rubyforge_project:
|
168
|
-
rubygems_version: 2.6.
|
185
|
+
rubygems_version: 2.6.13
|
169
186
|
signing_key:
|
170
187
|
specification_version: 4
|
171
188
|
summary: A gem to install and interface with HashiCorp's Packer utility
|