vagrant-wizard 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.vagrant/rgloader/loader.rb +9 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +142 -0
- data/LICENSE +21 -0
- data/README.md +146 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/vagrant-wizard/commands/wizard.rb +132 -0
- data/lib/vagrant-wizard/config.rb +30 -0
- data/lib/vagrant-wizard/inputs/confirm.rb +14 -0
- data/lib/vagrant-wizard/inputs/input.rb +31 -0
- data/lib/vagrant-wizard/inputs/password.rb +14 -0
- data/lib/vagrant-wizard/inputs/prompt.rb +15 -0
- data/lib/vagrant-wizard/inputs/select.rb +33 -0
- data/lib/vagrant-wizard/loader.rb +13 -0
- data/lib/vagrant-wizard/plugin.rb +25 -0
- data/lib/vagrant-wizard/prompt-parser.rb +39 -0
- data/lib/vagrant-wizard/version.rb +3 -0
- data/lib/vagrant-wizard.rb +8 -0
- data/vagrant-wizard.gemspec +28 -0
- data/vagrant-wizard.sublime-project +8 -0
- metadata +108 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2037e39c36f1bcac7076d8382b341d596458e39fb2706e8f7fd27e63dad674c1
|
4
|
+
data.tar.gz: e954b4f407d95115de932b82ca7dca33b676202aab97ddabc3d66d40ef58a18e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 562bf75d191b95ce0f5d23063d234f5972d53ffa214dc08e8884833b9ec7497847fa9d5c4e622980c8b6ded0a5f98147f635433085278e13c6c6800901665dfb
|
7
|
+
data.tar.gz: ef844d0970ea3f503b3540a7bde147bf8398c48e9b09002607b8f49d45815eda092c456988bb0630416f5aa23089961051a23fceb7cdea16f106abbe97ef484a
|
data/.gitignore
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# This file loads the proper rgloader/loader.rb file that comes packaged
|
2
|
+
# with Vagrant so that encoded files can properly run with Vagrant.
|
3
|
+
|
4
|
+
if ENV["VAGRANT_INSTALLER_EMBEDDED_DIR"]
|
5
|
+
require File.expand_path(
|
6
|
+
"rgloader/loader", ENV["VAGRANT_INSTALLER_EMBEDDED_DIR"])
|
7
|
+
else
|
8
|
+
raise "Encoded files can't be read outside of the Vagrant installer."
|
9
|
+
end
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
GIT
|
2
|
+
remote: https://github.com/hashicorp/vagrant.git
|
3
|
+
revision: 25e11650c3c6b1a2d461ef055aabacb8562b265b
|
4
|
+
tag: v2.2.4
|
5
|
+
specs:
|
6
|
+
vagrant (2.2.4)
|
7
|
+
bcrypt_pbkdf (~> 1.0.0)
|
8
|
+
childprocess (~> 0.6.0)
|
9
|
+
ed25519 (~> 1.2.4)
|
10
|
+
erubis (~> 2.7.0)
|
11
|
+
hashicorp-checkpoint (~> 0.1.5)
|
12
|
+
i18n (~> 1.1.1)
|
13
|
+
listen (~> 3.1.5)
|
14
|
+
log4r (~> 1.1.9, < 1.1.11)
|
15
|
+
net-scp (~> 1.2.0)
|
16
|
+
net-sftp (~> 2.1)
|
17
|
+
net-ssh (~> 5.1.0)
|
18
|
+
rb-kqueue (~> 0.2.0)
|
19
|
+
rest-client (>= 1.6.0, < 3.0)
|
20
|
+
ruby_dep (<= 1.3.1)
|
21
|
+
rubyzip (~> 1.2.2)
|
22
|
+
vagrant_cloud (~> 2.0.2)
|
23
|
+
wdm (~> 0.1.0)
|
24
|
+
winrm (~> 2.1)
|
25
|
+
winrm-elevated (~> 1.1)
|
26
|
+
winrm-fs (~> 1.0)
|
27
|
+
|
28
|
+
PATH
|
29
|
+
remote: .
|
30
|
+
specs:
|
31
|
+
vagrant-wizard (0.1.0)
|
32
|
+
|
33
|
+
GEM
|
34
|
+
remote: https://rubygems.org/
|
35
|
+
specs:
|
36
|
+
bcrypt_pbkdf (1.0.1-x64-mingw32)
|
37
|
+
builder (3.2.3)
|
38
|
+
childprocess (0.6.3)
|
39
|
+
ffi (~> 1.0, >= 1.0.11)
|
40
|
+
concurrent-ruby (1.1.5)
|
41
|
+
domain_name (0.5.20190701)
|
42
|
+
unf (>= 0.0.5, < 1.0.0)
|
43
|
+
ed25519 (1.2.4)
|
44
|
+
equatable (0.6.1)
|
45
|
+
erubis (2.7.0)
|
46
|
+
ffi (1.11.1-x64-mingw32)
|
47
|
+
gssapi (1.3.0)
|
48
|
+
ffi (>= 1.0.1)
|
49
|
+
gyoku (1.3.1)
|
50
|
+
builder (>= 2.1.2)
|
51
|
+
hashicorp-checkpoint (0.1.5)
|
52
|
+
http-cookie (1.0.3)
|
53
|
+
domain_name (~> 0.5)
|
54
|
+
httpclient (2.8.3)
|
55
|
+
i18n (1.1.1)
|
56
|
+
concurrent-ruby (~> 1.0)
|
57
|
+
listen (3.1.5)
|
58
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
59
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
60
|
+
ruby_dep (~> 1.2)
|
61
|
+
little-plugger (1.1.4)
|
62
|
+
log4r (1.1.10)
|
63
|
+
logging (2.2.2)
|
64
|
+
little-plugger (~> 1.1)
|
65
|
+
multi_json (~> 1.10)
|
66
|
+
mime-types (3.2.2)
|
67
|
+
mime-types-data (~> 3.2015)
|
68
|
+
mime-types-data (3.2019.0331)
|
69
|
+
multi_json (1.13.1)
|
70
|
+
necromancer (0.5.0)
|
71
|
+
net-scp (1.2.1)
|
72
|
+
net-ssh (>= 2.6.5)
|
73
|
+
net-sftp (2.1.2)
|
74
|
+
net-ssh (>= 2.6.5)
|
75
|
+
net-ssh (5.1.0)
|
76
|
+
netrc (0.11.0)
|
77
|
+
nori (2.6.0)
|
78
|
+
pastel (0.7.3)
|
79
|
+
equatable (~> 0.6)
|
80
|
+
tty-color (~> 0.5)
|
81
|
+
rake (10.5.0)
|
82
|
+
rb-fsevent (0.10.3)
|
83
|
+
rb-inotify (0.10.0)
|
84
|
+
ffi (~> 1.0)
|
85
|
+
rb-kqueue (0.2.5)
|
86
|
+
ffi (>= 0.5.0)
|
87
|
+
rest-client (2.0.2-x64-mingw32)
|
88
|
+
ffi (~> 1.9)
|
89
|
+
http-cookie (>= 1.0.2, < 2.0)
|
90
|
+
mime-types (>= 1.16, < 4.0)
|
91
|
+
netrc (~> 0.8)
|
92
|
+
ruby_dep (1.3.1)
|
93
|
+
rubyntlm (0.6.2)
|
94
|
+
rubyzip (1.2.3)
|
95
|
+
tty-color (0.5.0)
|
96
|
+
tty-cursor (0.7.0)
|
97
|
+
tty-prompt (0.19.0)
|
98
|
+
necromancer (~> 0.5.0)
|
99
|
+
pastel (~> 0.7.0)
|
100
|
+
tty-reader (~> 0.6.0)
|
101
|
+
tty-reader (0.6.0)
|
102
|
+
tty-cursor (~> 0.7)
|
103
|
+
tty-screen (~> 0.7)
|
104
|
+
wisper (~> 2.0.0)
|
105
|
+
tty-screen (0.7.0)
|
106
|
+
unf (0.1.4)
|
107
|
+
unf_ext
|
108
|
+
unf_ext (0.0.7.6)
|
109
|
+
vagrant_cloud (2.0.2)
|
110
|
+
rest-client (~> 2.0.2)
|
111
|
+
wdm (0.1.1)
|
112
|
+
winrm (2.3.2)
|
113
|
+
builder (>= 2.1.2)
|
114
|
+
erubis (~> 2.7)
|
115
|
+
gssapi (~> 1.2)
|
116
|
+
gyoku (~> 1.0)
|
117
|
+
httpclient (~> 2.2, >= 2.2.0.2)
|
118
|
+
logging (>= 1.6.1, < 3.0)
|
119
|
+
nori (~> 2.0)
|
120
|
+
rubyntlm (~> 0.6.0, >= 0.6.1)
|
121
|
+
winrm-elevated (1.1.1)
|
122
|
+
winrm (~> 2.0)
|
123
|
+
winrm-fs (~> 1.0)
|
124
|
+
winrm-fs (1.3.2)
|
125
|
+
erubis (~> 2.7)
|
126
|
+
logging (>= 1.6.1, < 3.0)
|
127
|
+
rubyzip (~> 1.1)
|
128
|
+
winrm (~> 2.0)
|
129
|
+
wisper (2.0.0)
|
130
|
+
|
131
|
+
PLATFORMS
|
132
|
+
x64-mingw32
|
133
|
+
|
134
|
+
DEPENDENCIES
|
135
|
+
bundler (~> 1.17)
|
136
|
+
rake (~> 10)
|
137
|
+
tty-prompt
|
138
|
+
vagrant!
|
139
|
+
vagrant-wizard!
|
140
|
+
|
141
|
+
BUNDLED WITH
|
142
|
+
1.17.3
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2019 joe-damore
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
# Vagrant Wizard
|
2
|
+
Vagrant plugin to easily generate configuration files.
|
3
|
+
|
4
|
+
## Overview
|
5
|
+
Vagrant Wizard allows users to generate YAML configuration files for their
|
6
|
+
Vagrant environments using a predefined set of prompts described in a
|
7
|
+
**vagrant-wizard.yml** file.
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
By default, prompts are defined in **vagrant-wizard.yml** and determine which
|
11
|
+
information is requested from the user. The path to this file can be changed
|
12
|
+
in your vagrantfile.
|
13
|
+
|
14
|
+
An example **vagrant-wizard.yml** for a MEAN localdev environment might be:
|
15
|
+
|
16
|
+
---
|
17
|
+
prompts:
|
18
|
+
- type: prompt
|
19
|
+
key: vm|name
|
20
|
+
prompt: Enter the name for your virtual machine.
|
21
|
+
default: mean-localdev
|
22
|
+
- type: select
|
23
|
+
key: node|version
|
24
|
+
prompt: What version of Node should be installed?
|
25
|
+
choices:
|
26
|
+
- name: v10
|
27
|
+
value: 10
|
28
|
+
- name: v11
|
29
|
+
value: 11
|
30
|
+
- name: v12
|
31
|
+
value: 12
|
32
|
+
- type: select
|
33
|
+
key: vm|memory
|
34
|
+
prompt: How much memory should this environment have?
|
35
|
+
choices:
|
36
|
+
- name: 512 MB
|
37
|
+
value: 512
|
38
|
+
- name: 1 GB
|
39
|
+
value: 1024
|
40
|
+
- name: 2 GB
|
41
|
+
value: 2048
|
42
|
+
advanced: true
|
43
|
+
default: 512
|
44
|
+
|
45
|
+
When the user runs ``vagrant wizard``, they will be prompted to enter the name
|
46
|
+
for their virtual machine and to select which version of Node they'd like to
|
47
|
+
install.
|
48
|
+
|
49
|
+
If the user passed the ``--advanced`` flag they will also be prompted
|
50
|
+
to select the amount of memory to allow the virtual machine to use.
|
51
|
+
|
52
|
+
Upon completing the prompts, a new YAML file is created containing the values
|
53
|
+
entered by the user. By default, this file is named **vagrant-config.yml**.
|
54
|
+
|
55
|
+
### Prompts
|
56
|
+
The **vagrant-wizard.yml** file has only a ``prompts`` key which contains
|
57
|
+
a list of prompt definitions. Each prompt can accept the following fields:
|
58
|
+
|
59
|
+
|Field |Description |
|
60
|
+
|------------|-----------------------------------------------------------|
|
61
|
+
|``type`` |Type of prompt to display to the user |
|
62
|
+
|``key`` |Unique key for prompt and determines YAML output structure |
|
63
|
+
|``prompt`` |Message to show to user when displaying prompt |
|
64
|
+
|``advanced``|If true, only show when ``--advanced`` flag is passed |
|
65
|
+
|``default`` |Default value. Must be included when ``advanced`` is true |
|
66
|
+
|
67
|
+
#### Types
|
68
|
+
|
69
|
+
##### prompt
|
70
|
+
The ``prompt`` type is the most basic type of prompt. It simply displays
|
71
|
+
a question or statement to the user, and captures their input.
|
72
|
+
|
73
|
+
##### password
|
74
|
+
``password`` prompts work similarly to ``prompt`` prompts, but the user's
|
75
|
+
input is masked for enhanced security.
|
76
|
+
|
77
|
+
This prompt type should be used when requesting sensitive information from
|
78
|
+
the user.
|
79
|
+
|
80
|
+
Prompts of this type do not accept ``default`` values, and will display a
|
81
|
+
warning if one is specified.
|
82
|
+
|
83
|
+
##### confirm
|
84
|
+
``confirm`` prompts simply ask the user to answer yes or no to a question. If
|
85
|
+
the user hits enter without submitting a value, ``yes`` is assumed.
|
86
|
+
|
87
|
+
Prompts of this type do not accept ``default`` values, and will display a
|
88
|
+
warning if one is specified.
|
89
|
+
|
90
|
+
##### select
|
91
|
+
``select`` prompts allow the user to choose a value from a list. Unlike other
|
92
|
+
prompts, ``select`` prompts have a special ``choices`` field which contains
|
93
|
+
a list of choices to show the user.
|
94
|
+
|
95
|
+
Each choice contains a ``name``, which is shown to the user on-screen, and a
|
96
|
+
``value`` which represents the actual value being stored in configuration.
|
97
|
+
|
98
|
+
Prompts of this type do accept a default value, but the default value *must*
|
99
|
+
correspond to one of the ``value``s specified in the ``choices`` field.
|
100
|
+
|
101
|
+
### Default Configuration
|
102
|
+
Occasionally there will be a need to store values in a configuration file that
|
103
|
+
do not actually require user input. These configurations can be specified in
|
104
|
+
**vagrant-wizard.default.yml**, and will automatically be passed to any
|
105
|
+
configuration file that gets generated using Vagrant Wizard.
|
106
|
+
|
107
|
+
If the configuration provided by **vagrant-wizard.default.yml** conflicts
|
108
|
+
with the configuration specified by the user, the configuration specified
|
109
|
+
by the user will overwrite the configuration specified in
|
110
|
+
**vagrant-wizard.default.yml**.
|
111
|
+
|
112
|
+
### Presets
|
113
|
+
Preset configurations can be created and stored in the **wizard-presets**
|
114
|
+
directory. A preset is a YAML file whose filename ends in *.preset.yml* and
|
115
|
+
which contains a list of key/value pairs which can be automatically used to
|
116
|
+
answer prompts specified in **vagrant-wizard.yml**.
|
117
|
+
|
118
|
+
For example, a preset for the example **vagrant-wizard.yml** file above might
|
119
|
+
be named ``node-10.preset.yml`` and look like this:
|
120
|
+
|
121
|
+
meta:
|
122
|
+
name: Node 10
|
123
|
+
config:
|
124
|
+
- key: node|version
|
125
|
+
value: 10
|
126
|
+
|
127
|
+
If presets exist in the **wizard-presets** directory, the user will be asked
|
128
|
+
to select a preset upon running ``vagrant wizard``. Using our example above,
|
129
|
+
if the user were to select the ``Node 10`` preset, the only other prompt they
|
130
|
+
would be required to answer would be the *Enter the name for your virtual
|
131
|
+
machine* prompt.
|
132
|
+
|
133
|
+
### Vagrantfile Configuration
|
134
|
+
Vagrant Wizard's behavior and default file paths can be configured in your
|
135
|
+
vagrantfile.
|
136
|
+
|
137
|
+
The following configuration options are available:
|
138
|
+
|
139
|
+
|Config |Description |Default |
|
140
|
+
|--------------------|------------------------------------------------------------------------|--------------------------------|
|
141
|
+
|``config_path`` |Path to Vagrant Wizard config file |``./vagrant-wizard.yml`` |
|
142
|
+
|``defaults_path`` |Path to default configuration file |``./vagrant-wizard.default.yml``|
|
143
|
+
|``output_path`` |Path to output configuration file |``./vagrant-config.yml`` |
|
144
|
+
|``presets_dir_path``|Path to presets directory |``./wizard-presets`` |
|
145
|
+
|``prompt_overwrite``|Whether or not to prompt for confirmation before overwriting config file|``true`` |
|
146
|
+
|``prompt_presets`` |Whether or not to prompt for preset selection |``true`` |
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "vagrant/wizard"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'vagrant'
|
2
|
+
require 'tty-prompt'
|
3
|
+
|
4
|
+
require 'vagrant-wizard';
|
5
|
+
require 'yaml';
|
6
|
+
|
7
|
+
module VagrantWizard
|
8
|
+
module Commands
|
9
|
+
class WizardCommand < Vagrant.plugin(2, :command)
|
10
|
+
|
11
|
+
def initialize(argv, env)
|
12
|
+
@env = env
|
13
|
+
@config = @env.vagrantfile.config.wizard
|
14
|
+
@advanced = false
|
15
|
+
if argv.include?("--advanced") || argv.include?('-a')
|
16
|
+
@advanced = true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.synopsis
|
21
|
+
'interactively creates configuration file'
|
22
|
+
end
|
23
|
+
|
24
|
+
def execute
|
25
|
+
loader = VagrantWizard::Loader.new(@config.config_path)
|
26
|
+
if (loader.data == nil)
|
27
|
+
puts "Wizard config file cannot be found!"
|
28
|
+
return
|
29
|
+
end
|
30
|
+
|
31
|
+
defaultData = Hash.new
|
32
|
+
if (File.exist?(@config.defaults_path))
|
33
|
+
defaultData = YAML.load(File.read(@config.defaults_path))
|
34
|
+
end
|
35
|
+
|
36
|
+
presets = Hash.new
|
37
|
+
presets['(None)'] = {}
|
38
|
+
preset = nil;
|
39
|
+
if (@config.prompt_presets == true && Dir.exist?(@config.presets_dir_path))
|
40
|
+
presetPrompt = TTY::Prompt.new
|
41
|
+
showPresets = presetPrompt.yes?("Select from a preset configuration?")
|
42
|
+
if (showPresets == true)
|
43
|
+
presetFilesYml = Dir["#{@config.presets_dir_path}/*.preset.yml"]
|
44
|
+
presetFilesYaml = Dir["#{@config.presets_dir_path}/*.preset.yaml"]
|
45
|
+
presetFiles = presetFilesYml + presetFilesYaml
|
46
|
+
|
47
|
+
presetFiles.each do |presetFile|
|
48
|
+
presetData = YAML.load(File.read(presetFile))
|
49
|
+
# Skip preset definitions that do not have a meta section
|
50
|
+
if (presetData == false || !presetData.key?('meta'))
|
51
|
+
next
|
52
|
+
end
|
53
|
+
presets[presetData['meta']['name']] = presetData['config']
|
54
|
+
end
|
55
|
+
|
56
|
+
presetChoice = TTY::Prompt.new
|
57
|
+
preset = presetChoice.select('Select a preset', presets)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
outputData = Hash.new
|
62
|
+
|
63
|
+
loader.data['prompts'].each do |prompt|
|
64
|
+
presetData = nil
|
65
|
+
if (preset != nil)
|
66
|
+
preset.each do |preset|
|
67
|
+
if (!preset.key?('key') || !preset.key?('value'))
|
68
|
+
next
|
69
|
+
end
|
70
|
+
if (preset['key'] == prompt['key'])
|
71
|
+
presetData = preset['value']
|
72
|
+
break
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
output = nil
|
78
|
+
if (presetData != nil)
|
79
|
+
key = prompt['key']
|
80
|
+
output = presetData
|
81
|
+
else
|
82
|
+
parser = PromptParser.new(prompt)
|
83
|
+
parser.advanced = @advanced
|
84
|
+
parser.prompt()
|
85
|
+
key = parser.key
|
86
|
+
output = parser.output
|
87
|
+
end
|
88
|
+
|
89
|
+
keyParts = key.split('|');
|
90
|
+
keyName = keyParts[-1];
|
91
|
+
currentHash = outputData
|
92
|
+
keyParts[0..-2].each do |keyPart|
|
93
|
+
if !currentHash.key?(keyPart)
|
94
|
+
currentHash[keyPart] = Hash.new
|
95
|
+
end
|
96
|
+
currentHash = currentHash[keyPart]
|
97
|
+
end
|
98
|
+
currentHash[keyName] = output
|
99
|
+
end
|
100
|
+
|
101
|
+
def merge_recursively(a, b)
|
102
|
+
a.merge!(b) do |key, a_item, b_item|
|
103
|
+
if a_item.is_a?(Hash)
|
104
|
+
merge_recursively(a_item, b_item)
|
105
|
+
else
|
106
|
+
b_item
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
outputData = merge_recursively(defaultData, outputData)
|
112
|
+
|
113
|
+
outputYaml = outputData.to_yaml
|
114
|
+
canOverwrite = true
|
115
|
+
if File.exist?(@config.output_path)
|
116
|
+
if @config.prompt_overwrite == true
|
117
|
+
confirmation = TTY::Prompt.new
|
118
|
+
canOverwrite = confirmation.yes?("Overwrite your existing configuration?")
|
119
|
+
else
|
120
|
+
canOverwrite = true
|
121
|
+
end
|
122
|
+
end
|
123
|
+
if canOverwrite == true
|
124
|
+
File.open(@config.output_path, "w") do |file|
|
125
|
+
file.write outputYaml
|
126
|
+
end
|
127
|
+
end
|
128
|
+
0
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'vagrant'
|
2
|
+
|
3
|
+
module VagrantWizard
|
4
|
+
class Config < Vagrant.plugin('2', :config)
|
5
|
+
attr_accessor :config_path
|
6
|
+
attr_accessor :defaults_path
|
7
|
+
attr_accessor :output_path
|
8
|
+
attr_accessor :prompt_presets
|
9
|
+
attr_accessor :presets_dir_path
|
10
|
+
attr_accessor :prompt_overwrite
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@config_path = UNSET_VALUE
|
14
|
+
@defaults_path = UNSET_VALUE
|
15
|
+
@output_path = UNSET_VALUE
|
16
|
+
@prompt_presets = UNSET_VALUE
|
17
|
+
@presets_dir_path = UNSET_VALUE
|
18
|
+
@propmt_overwrite = UNSET_VALUE
|
19
|
+
end
|
20
|
+
|
21
|
+
def finalize!
|
22
|
+
@config_path = './vagrant-wizard.yml' if @config_path == UNSET_VALUE
|
23
|
+
@defaults_path = './vagrant-wizard.default.yml' if @defaults_path == UNSET_VALUE
|
24
|
+
@output_path = './vagrant-config.yml' if @output_path == UNSET_VALUE
|
25
|
+
@prompt_presets = true if @prompt_presets == UNSET_VALUE
|
26
|
+
@presets_dir_path = './wizard-presets' if @presets_dir_path == UNSET_VALUE
|
27
|
+
@prompt_overwrite = true if @prompt_overwrite == UNSET_VALUE
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "tty-prompt"
|
2
|
+
|
3
|
+
class VagrantWizard::Confirm < VagrantWizard::Input
|
4
|
+
|
5
|
+
def processInput
|
6
|
+
prompt = TTY::Prompt.new
|
7
|
+
|
8
|
+
if @data.key?('default')
|
9
|
+
puts "Warning: `default` key specified for `confirm` prompt type, but `default` is not accepted for `confirm`."
|
10
|
+
end
|
11
|
+
@output = prompt.yes?(@prompt)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class VagrantWizard::Input
|
2
|
+
attr_reader :prompt
|
3
|
+
attr_reader :data
|
4
|
+
attr_reader :output
|
5
|
+
attr_accessor :silent
|
6
|
+
|
7
|
+
def initialize(prompt, data)
|
8
|
+
@prompt = prompt
|
9
|
+
@data = data
|
10
|
+
@output = nil
|
11
|
+
@silent = false
|
12
|
+
end
|
13
|
+
|
14
|
+
def prompt
|
15
|
+
if !@silent
|
16
|
+
self.processInput
|
17
|
+
return @output
|
18
|
+
elsif @data.key?('default')
|
19
|
+
@output = @data['default']
|
20
|
+
return @output
|
21
|
+
end
|
22
|
+
puts "Warning: input for prompt '#{@data['key']}' has been silenced, but no default value has been provided"
|
23
|
+
return @output
|
24
|
+
end
|
25
|
+
|
26
|
+
def processInput
|
27
|
+
puts "Warning: processInput not implemented for this input type"
|
28
|
+
@output = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "tty-prompt"
|
2
|
+
|
3
|
+
class VagrantWizard::Password < VagrantWizard::Input
|
4
|
+
|
5
|
+
def processInput
|
6
|
+
prompt = TTY::Prompt.new
|
7
|
+
|
8
|
+
if @data.key?('default')
|
9
|
+
puts "Warning: `default` key specified for `password` prompt type, but `default` is not accepted for `password`."
|
10
|
+
end
|
11
|
+
@output = prompt.mask(@prompt)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "tty-prompt"
|
2
|
+
|
3
|
+
class VagrantWizard::Prompt < VagrantWizard::Input
|
4
|
+
|
5
|
+
def processInput
|
6
|
+
prompt = TTY::Prompt.new
|
7
|
+
|
8
|
+
if @data.key?('default')
|
9
|
+
@output = prompt.ask(@prompt, default: @data['default'])
|
10
|
+
return
|
11
|
+
end
|
12
|
+
@output = prompt.ask(@prompt)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "tty-prompt"
|
2
|
+
|
3
|
+
class VagrantWizard::Select < VagrantWizard::Input
|
4
|
+
|
5
|
+
def processInput
|
6
|
+
|
7
|
+
prompt = TTY::Prompt.new
|
8
|
+
choices = Hash.new
|
9
|
+
|
10
|
+
@data['choices'].each do |choice|
|
11
|
+
choices[choice['name']] = choice['value']
|
12
|
+
end
|
13
|
+
|
14
|
+
if @data.key?('default')
|
15
|
+
default_index = choices.find_index do |key,value|
|
16
|
+
value == @data['default']
|
17
|
+
end
|
18
|
+
default_index += 1
|
19
|
+
|
20
|
+
@output = prompt.select(@prompt) do |menu|
|
21
|
+
menu.default default_index
|
22
|
+
choices.each do |key,value|
|
23
|
+
menu.choice key,value
|
24
|
+
end
|
25
|
+
end
|
26
|
+
return
|
27
|
+
end
|
28
|
+
|
29
|
+
@output = prompt.select(@prompt, choices)
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'vagrant'
|
2
|
+
require 'vagrant-wizard'
|
3
|
+
require 'vagrant-wizard/version'
|
4
|
+
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
class VagrantWizard::Plugin < Vagrant.plugin("2")
|
8
|
+
name "Wizard"
|
9
|
+
|
10
|
+
description <<-DESC
|
11
|
+
This plugin allows users to interactively configure
|
12
|
+
their Vagrant environments.
|
13
|
+
DESC
|
14
|
+
|
15
|
+
command "wizard" do
|
16
|
+
require_relative "commands/wizard"
|
17
|
+
VagrantWizard::Commands::WizardCommand
|
18
|
+
end
|
19
|
+
|
20
|
+
config "wizard" do
|
21
|
+
require_relative "config"
|
22
|
+
VagrantWizard::Config
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class VagrantWizard::PromptParser
|
2
|
+
attr_reader :output
|
3
|
+
attr_reader :key
|
4
|
+
attr_accessor :advanced
|
5
|
+
|
6
|
+
def initialize(prompt)
|
7
|
+
@prompt = prompt
|
8
|
+
@advanced = false
|
9
|
+
@key = @prompt['key']
|
10
|
+
@output = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def prompt
|
14
|
+
promptType = @prompt['type']
|
15
|
+
promptQuestion = @prompt['prompt']
|
16
|
+
|
17
|
+
begin
|
18
|
+
require_relative "inputs/#{promptType}"
|
19
|
+
rescue LoadError
|
20
|
+
puts "Unable to process input type '#{promptType}'"
|
21
|
+
if @prompt.key?('default')
|
22
|
+
@output = @prompt['default']
|
23
|
+
end
|
24
|
+
exit
|
25
|
+
end
|
26
|
+
|
27
|
+
className = Object.const_get("VagrantWizard::#{promptType.capitalize}")
|
28
|
+
prompt = className.new(promptQuestion, @prompt)
|
29
|
+
|
30
|
+
if @prompt.key?('advanced') && @advanced == false
|
31
|
+
if @prompt['advanced'] == true
|
32
|
+
prompt.silent = true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
@output = prompt.prompt()
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
require "vagrant-wizard/version"
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "vagrant-wizard"
|
9
|
+
spec.version = VagrantWizard::VERSION
|
10
|
+
spec.authors = ["Joe D'Amore"]
|
11
|
+
spec.email = ["joe@joedamore.me"]
|
12
|
+
|
13
|
+
spec.summary = "Interactive environment configuration"
|
14
|
+
spec.description = "Interactive configuration for Vagrant development environments"
|
15
|
+
spec.homepage = "https://github.com/joe-damore/vagrant-wizard"
|
16
|
+
spec.license = "MIT"
|
17
|
+
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
|
21
|
+
spec.files = %x{git ls-files -z}.split("\0")
|
22
|
+
spec.require_path = "lib"
|
23
|
+
|
24
|
+
spec.add_runtime_dependency "tty-prompt", "~> 0.19.0"
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.17"
|
27
|
+
spec.add_development_dependency "rake", "~> 10"
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vagrant-wizard
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Joe D'Amore
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-09-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: tty-prompt
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.19.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.19.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.17'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.17'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10'
|
55
|
+
description: Interactive configuration for Vagrant development environments
|
56
|
+
email:
|
57
|
+
- joe@joedamore.me
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- ".vagrant/rgloader/loader.rb"
|
64
|
+
- Gemfile
|
65
|
+
- Gemfile.lock
|
66
|
+
- LICENSE
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- bin/console
|
70
|
+
- bin/setup
|
71
|
+
- lib/vagrant-wizard.rb
|
72
|
+
- lib/vagrant-wizard/commands/wizard.rb
|
73
|
+
- lib/vagrant-wizard/config.rb
|
74
|
+
- lib/vagrant-wizard/inputs/confirm.rb
|
75
|
+
- lib/vagrant-wizard/inputs/input.rb
|
76
|
+
- lib/vagrant-wizard/inputs/password.rb
|
77
|
+
- lib/vagrant-wizard/inputs/prompt.rb
|
78
|
+
- lib/vagrant-wizard/inputs/select.rb
|
79
|
+
- lib/vagrant-wizard/loader.rb
|
80
|
+
- lib/vagrant-wizard/plugin.rb
|
81
|
+
- lib/vagrant-wizard/prompt-parser.rb
|
82
|
+
- lib/vagrant-wizard/version.rb
|
83
|
+
- vagrant-wizard.gemspec
|
84
|
+
- vagrant-wizard.sublime-project
|
85
|
+
homepage: https://github.com/joe-damore/vagrant-wizard
|
86
|
+
licenses:
|
87
|
+
- MIT
|
88
|
+
metadata: {}
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options: []
|
91
|
+
require_paths:
|
92
|
+
- lib
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
requirements: []
|
104
|
+
rubygems_version: 3.0.4
|
105
|
+
signing_key:
|
106
|
+
specification_version: 4
|
107
|
+
summary: Interactive environment configuration
|
108
|
+
test_files: []
|