provision-vagrant 1.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f33f4fffa23760ab39bfab3226f5a1aacfcc4dee67106ca6986b7693a6c51920
4
+ data.tar.gz: c860b10affe58159b45918d42c4e714389319c00151e5df470138bdcf2c88b0b
5
+ SHA512:
6
+ metadata.gz: ef56df7f3a324e8dd2b9c456c6940776c9f68cd53b303266048c75d3d2b3b100b5b1c0170d55a9411020f6b0f54aae130667e67ead08ac38992f277ed9a97f00
7
+ data.tar.gz: d5e53c32ca810d69cb6c4a0d46013600819496d7d14fc0f5ac0e292a91e462da617e2c216d9f63d50c10f3257ce5aa9d7f3260fb8f6ac633d56fde7d19c038c1
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/provision_vagrant'
4
+
5
+ # Require all Ruby files in 'lib/'
6
+ Dir[File.join(__dir__, '..', 'lib', '*.rb')].each do |file|
7
+ require file unless file.end_with?('porvision-vagrant')
8
+ end
9
+
10
+ def main
11
+ include ProvisionVagrant
12
+
13
+ options_klass_obj = ProvisionVagrant::Options.new
14
+ options = options_klass_obj.parse_options
15
+ options_klass_obj.help 'New project name must be specified. Ex: provision-vagrant foo-app' if ARGV.empty?
16
+
17
+ project_name = ARGV[0]
18
+ options[:project_name] = project_name
19
+
20
+ puts "\n\n options in main bin app: #{options.inspect}\n\n"
21
+ generator = Generator.new(options)
22
+ generator.generate
23
+ end
24
+
25
+ main
data/lib/generator.rb ADDED
@@ -0,0 +1,107 @@
1
+ require 'options'
2
+ require 'yaml'
3
+
4
+ module ProvisionVagrant
5
+
6
+ class Generator
7
+
8
+ def initialize(opts = {})
9
+ @opts = opts
10
+ @project_name = opts[:project_name]
11
+ @initializer = PvInitializer.new(opts)
12
+ @config_opts = read_config_opts(opts[:config])
13
+ end
14
+
15
+ def generate
16
+ puts "\nNew box name: #{project_name}"
17
+ create_new_project_dir
18
+
19
+ if !File.exist?(dev_box_dir_path)
20
+ ProvisionVagrant.help("Error: there was a problem creating target project directory: #{dev_box_dir_path}")
21
+ end
22
+
23
+ copy_vagrantfile
24
+ puts "\nNext, cd into your new project directory: #{dev_box_dir_path}"
25
+ puts "\nAnd start/provision your new vagrant box:\n\n vagrant up\n"
26
+ puts "\nOnce your vagrant vm is running, ssh in as usual:\n\n vagrant ssh\n"
27
+ puts "\nThe first time you login, run the post hooks installation script:\n\n ./#{POST_HOOK_FILE_NAME}\n"
28
+ puts "\nSuccess! Exiting.\n"
29
+ end
30
+
31
+ def delete
32
+ [default_config_path,
33
+ default_vagrantilfe_path,
34
+ default_post_hook_path].each do |file_name|
35
+ if File.exist?(file_name)
36
+ puts "Removing: #{file_name}"
37
+ FileUtils.rm_f(file_name)
38
+ end
39
+ end
40
+ end
41
+
42
+ def project_path
43
+ @_project_path ||= File.join(initializer.user_directory, project_name)
44
+ end
45
+
46
+ def dev_box_dir_path
47
+ @_dev_box_dir_path ||= File.join(initializer.user_directory, project_name, "dev-box/")
48
+ end
49
+
50
+ def create_new_project_dir
51
+ puts "Creating #{project_name} directory: #{dev_box_dir_path}"
52
+ FileUtils.mkdir_p(dev_box_dir_path)
53
+ end
54
+
55
+ def copy_vagrantfile
56
+ vars = config_opts.merge({ project_name: project_name })
57
+ interpolator = Interpolator.new( { vars: vars, input: vagrantfile_string })
58
+ interpolated = interpolator.interpolate
59
+
60
+ ProvisionVagrant.write_string_to_File(interpolated, target_vagrantfile_path)
61
+ if File.exist?(target_vagrantfile_path)
62
+ puts "Copied #{vagrantfile_path} (and inerpolated its vars) to: #{target_vagrantfile_path}"
63
+ else
64
+ ProvisionVagrant.help("Error: there was a problem copying over your Vagrantilfe.template (dfeault) from #{vagrantfile_path} to #{target_vagrantfile_path}")
65
+ end
66
+ end
67
+
68
+ def default_config_path
69
+ @_default_config_path ||= File.join(initializer.user_directory, PROVISION_VAGRANT_CONFIG_FILE_NAME)
70
+ end
71
+
72
+ def default_vagrantilfe_path
73
+ @_default_vagrantfile_path ||= File.join(initializer.user_directory, VAGRANTFILE_NAME)
74
+ end
75
+
76
+ def default_post_hook_path
77
+ @_default_post_hook_path ||= File.join(initializer.user_directory, POST_HOOK_FILE_NAME)
78
+ end
79
+
80
+ def vagrantfile_path
81
+ @_vagrantfile_path ||= (opts[:template] || default_vagrantilfe_path)
82
+ end
83
+
84
+ def target_vagrantfile_path
85
+ @_target_vagrantfile_path ||= File.join(dev_box_dir_path, VAGRANTFILE_TARGET_NAME)
86
+ end
87
+
88
+ def vagrantfile_string
89
+ File.read(vagrantfile_path)
90
+ end
91
+
92
+ private
93
+
94
+ attr_accessor :opts, :config_opts, :initializer, :project_name
95
+
96
+ def read_config_opts(config_path = nil)
97
+ config_path ||= default_config_path
98
+ return {} unless File.exist?(config_path)
99
+
100
+ yaml_hash = YAML.load_file(config_path)
101
+ return {} unless yaml_hash && yaml_hash["configuration"]
102
+
103
+ yaml_hash["configuration"]
104
+ end
105
+ end
106
+
107
+ end
@@ -0,0 +1,25 @@
1
+ module ProvisionVagrant
2
+
3
+ class Interpolator
4
+
5
+ DEFAULT_VAGRANTFILE_NAME = "Vagrantfile.template"
6
+ DEFAULT_POST_HOOK_FILE_NAME = "provision-vagrant.post-hook.sh"
7
+
8
+ def initialize(opts = {})
9
+ @vars = opts[:vars]
10
+ @input = opts[:input]
11
+ end
12
+
13
+ # Loops through a Hash (@vars) and replaces any of its keys found in
14
+ # the @input string with the corresponding hash values
15
+ def interpolate
16
+ @vars.each do |k, v|
17
+ var_wrapped = "{{#{k.to_s}}}"
18
+ @input.gsub!(var_wrapped, v.to_s)
19
+ end
20
+
21
+ @input
22
+ end
23
+ end
24
+
25
+ end
data/lib/options.rb ADDED
@@ -0,0 +1,113 @@
1
+
2
+ require 'optparse'
3
+ require 'paint'
4
+
5
+ module ProvisionVagrant
6
+
7
+ class Options
8
+
9
+ def initialize
10
+ end
11
+
12
+ def parse_options
13
+ options = { verbose: false }
14
+ OptionParser.new do |parser|
15
+ @parser = parser
16
+
17
+ parser.on("-c", "--config", "Specify the yml config file to use") do |c|
18
+ options[:config] = c
19
+ end
20
+
21
+ parser.on("-d", "--delete", "Delete files copied over from init command") do |d|
22
+ options[:delete] = true
23
+ end
24
+
25
+ parser.on("-f", "--force", "Force initialization even if target files already exist") do |f|
26
+ options[:force] = true
27
+ end
28
+
29
+ parser.on("-t", "--template", "Specify the path the to the Vagrantfile template") do |t|
30
+ options[:template] = t
31
+ end
32
+
33
+ parser.on("-v", "--version", "Shows the version number") do |v|
34
+ options[:version] = true
35
+ end
36
+
37
+ parser.on("-h", "--help", "Show this help message") do |h|
38
+ options[:help] = true
39
+ end
40
+
41
+ parser.on("-i", "--init", "Initialize provision-vagrant with files it needs to operate") do |i|
42
+ options[:init] = true
43
+ end
44
+ end.parse!
45
+
46
+ if options[:version]
47
+ help(ProvisionVagrant.version)
48
+ end
49
+
50
+ if options[:help]
51
+ help
52
+ end
53
+
54
+ if options[:delete]
55
+ Generator.new.delete
56
+ exit(true)
57
+ end
58
+
59
+ if options[:config] && !File.exist?(options[:config])
60
+ help "Error: Invalid config file specified (not found): #{CONFIG}"
61
+ end
62
+
63
+ if options[:temlpate] && !File.exist(options[:template])
64
+ help "Error: Invalid template file specified (not found): #{TEMPLATE}"
65
+ end
66
+
67
+ if options[:init]
68
+ initiliazer = PvInitializer.new(options)
69
+ initiliazer.init
70
+ exit(true)
71
+ end
72
+
73
+ options
74
+ end
75
+
76
+ def help(msg = nil)
77
+ if msg
78
+ puts(Paint["\n#{msg}\n", :yellow])
79
+ exit(false)
80
+ end
81
+
82
+ msg = <<~END_HELP
83
+ provision-vagrant: Generates and provisions a new vagrant vm box using template files
84
+
85
+ Syntax: provision-vagrant NEW_BOX_NAME
86
+
87
+ Options:
88
+ -c Specify a path to the config yml file to use (default: ~/provision-vagrant.yml)
89
+ -d Delete files copied over from init command
90
+ -h Show this help message
91
+ -t Specify a path to the Vagrantfile template to use (default: ~/Vagrantfile.template)
92
+ -v Show version number
93
+
94
+ Example:
95
+
96
+ provision-vagrant foo-bar-app
97
+
98
+ This will do the following:
99
+
100
+ - Create a new directory "foo-bar-app" under your home directory
101
+ - Create a "dev-box" directory within that directory (~/foo-bar-app/dev-box/)
102
+ - Copy over ~/Vagrantfile.template and replace the {{vars}} with project/config vars
103
+
104
+ See:
105
+ https://github.com/sbraford/provision-vagrant
106
+ END_HELP
107
+
108
+ puts(Paint[msg, :magenta])
109
+ exit(true)
110
+ end
111
+
112
+ end
113
+ end
@@ -0,0 +1,21 @@
1
+ module ProvisionVagrant
2
+
3
+ VAGRANTFILE_NAME = "Vagrantfile.template"
4
+ POST_HOOK_FILE_NAME = "provision-vagrant.post-hook.sh"
5
+ PROVISION_VAGRANT_CONFIG_FILE_NAME = "provision-vagrant.yml"
6
+ VAGRANTFILE_TARGET_NAME = "Vagrantfile"
7
+
8
+ def self.version
9
+ "1.0.1"
10
+ end
11
+
12
+ def self.write_string_to_File(string, file_path)
13
+ File.open(file_path, "w") {|file| file.puts string }
14
+ end
15
+
16
+ def self.help(msg)
17
+ puts(Paint["\n#{msg}\n", :yellow])
18
+ exit(false)
19
+ end
20
+
21
+ end
@@ -0,0 +1,160 @@
1
+ require 'fileutils'
2
+
3
+ module ProvisionVagrant
4
+
5
+ class PvInitializer
6
+
7
+ def initialize(opts = {})
8
+ @opts = opts
9
+ @opts.merge!(read_default_config_opts)
10
+ end
11
+
12
+ def init
13
+ puts "\nUsing home directory: #{user_directory}"
14
+
15
+ if !opts[:force] && (File.exist?(target_vagrantfile_path) || File.exist?(target_post_hook_path))
16
+ help("Aborting. One of the target output files already exists: #{target_file_list}")
17
+ exit(false)
18
+ end
19
+
20
+ copy_vagrantfile_template
21
+ copy_interpolated_post_hook
22
+ copy_provision_vagrant_config
23
+
24
+ if File.exist?(target_vagrantfile_path) &&
25
+ File.exist?(target_post_hook_path) &&
26
+ File.exist?(target_provision_vagrant_config_path)
27
+ puts "\nSuccess! You should now be ready to use provision-vagrant. Usage:\n\n"
28
+ puts " provision-vagrant new-box-name\n\n"
29
+ exit(1)
30
+ else
31
+ msg = "Error: There was a probelm initializing provision-vagrant. One of the following files did not get created: #{target_file_list}"
32
+ help(msg)
33
+ exit(0)
34
+ end
35
+ end
36
+
37
+ def copy_vagrantfile_template
38
+ puts "Copying example Vagrantfile template to: #{target_vagrantfile_path}"
39
+ FileUtils.cp(source_vagrantfile_path, target_vagrantfile_path)
40
+ end
41
+
42
+ def copy_interpolated_post_hook
43
+ complete_opts = opts.merge(fetch_github_vars)
44
+ interpolator = Interpolator.new( { vars: complete_opts, input: post_hook_source_string })
45
+ interpolated = interpolator.interpolate
46
+ copy_post_hook_script(interpolated)
47
+ end
48
+
49
+ def copy_post_hook_script(interpolated)
50
+ puts "Copying example post hook bash script to: #{target_post_hook_path}"
51
+ ProvisionVagrant.write_string_to_File(interpolated, target_post_hook_path)
52
+ end
53
+
54
+ def copy_provision_vagrant_config
55
+ puts "Copying provision-vagrant config yml file to: #{target_provision_vagrant_config_path}"
56
+ FileUtils.cp(source_provision_vagrant_config_path, target_provision_vagrant_config_path)
57
+ end
58
+
59
+ def user_directory
60
+ @_user_directory ||= set_userdir
61
+ end
62
+
63
+ private
64
+
65
+ attr_accessor :opts
66
+
67
+ def source_vagrantfile_path
68
+ @_source_vagrantfile_path ||= File.join(Dir.pwd, "..", VAGRANTFILE_NAME)
69
+ end
70
+
71
+ def target_vagrantfile_path
72
+ @_target_vagrantfile_path ||= File.join(set_userdir, VAGRANTFILE_NAME)
73
+ end
74
+
75
+ def source_post_hook_path
76
+ @_source_post_hook_path ||= File.join(Dir.pwd, "..", POST_HOOK_FILE_NAME)
77
+ end
78
+
79
+ def target_post_hook_path
80
+ @_target_post_hook_path ||= File.join(set_userdir, POST_HOOK_FILE_NAME)
81
+ end
82
+
83
+ def source_provision_vagrant_config_path
84
+ @_source_provision_vagrant_config_path ||= File.join(Dir.pwd, "..", PROVISION_VAGRANT_CONFIG_FILE_NAME)
85
+ end
86
+
87
+ def target_provision_vagrant_config_path
88
+ @_target_provision_vagrant_config_path ||= File.join(set_userdir, PROVISION_VAGRANT_CONFIG_FILE_NAME)
89
+ end
90
+
91
+ def post_hook_source_string
92
+ @_post_hook_source_string ||= File.read(source_post_hook_path)
93
+ end
94
+
95
+ def options_klass_obj
96
+ @_options_klass_obj ||= Options.new
97
+ end
98
+
99
+ def set_userdir
100
+ # default to HOME environment variable
101
+ return ENV['HOME'] if ENV['HOME']
102
+
103
+ # fallback to use the first two dir paths ("/home/username")
104
+ current_dir = Dir.pwd
105
+ parts = current_dir.split("/")
106
+ base_path = File.join("/", parts[1], parts[2])
107
+
108
+ base_path
109
+ end
110
+
111
+ def fetch_github_vars
112
+ git_config = `git config --list`
113
+ unless git_config
114
+ msg = "There was a problem parsing your git config (\"git config --list\". Please ensure git is installed and configured."
115
+ help(msg)
116
+ exit(false)
117
+ end
118
+
119
+ github_vars = {}
120
+
121
+ lines = git_config.split("\n")
122
+ lines.each do |line|
123
+ next unless line && line.size > 0
124
+
125
+ var, value = *line.split('=')
126
+ if var == 'user.name'
127
+ github_vars[:github_name] = value
128
+ end
129
+
130
+ if var == 'user.email'
131
+ github_vars[:github_email] = value
132
+ end
133
+ end
134
+
135
+ github_vars
136
+ end
137
+
138
+ def help(msg = nil)
139
+ options_klass_obj.help(msg)
140
+ end
141
+
142
+ def target_file_list
143
+ target_paths = [
144
+ target_vagrantfile_path,
145
+ target_vagrantfile_path,
146
+ target_post_hook_path
147
+ ]
148
+ joined = target_paths.join("\n")
149
+
150
+ "\n#{joined}"
151
+ end
152
+
153
+ def read_default_config_opts
154
+ yaml_hash = YAML.load_file(source_provision_vagrant_config_path)
155
+ return {} unless yaml_hash && yaml_hash["configuration"]
156
+
157
+ yaml_hash["configuration"]
158
+ end
159
+ end
160
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: provision-vagrant
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Shanti Braford
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-09-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '13.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '13.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: paint
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.3'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: '2.3'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '2.3'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '2.3'
47
+ - !ruby/object:Gem::Dependency
48
+ name: optparse
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: 0.5.0
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: 0.5.0
61
+ description: Easily spin up new Ubuntu/etc vagrant VM development boxes, provisioned
62
+ to your exact specs
63
+ email:
64
+ - shantibraford@gmail.com
65
+ executables:
66
+ - provision-vagrant
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - bin/provision-vagrant
71
+ - lib/generator.rb
72
+ - lib/interpolator.rb
73
+ - lib/options.rb
74
+ - lib/provision_vagrant.rb
75
+ - lib/pv_initializer.rb
76
+ homepage: https://github.com/sbraford/provision-vagrant
77
+ licenses:
78
+ - MIT
79
+ metadata: {}
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: 2.7.0
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubygems_version: 3.5.16
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: Opinionated vagrant box generator and provisioner for Ruby on Rails and beyond
99
+ test_files: []