setup_script_generator 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 +2 -0
- data/.ruby-version +1 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +20 -0
- data/LICENSE.txt +21 -0
- data/README.md +81 -0
- data/Rakefile +6 -0
- data/bin/setup +232 -0
- data/exe/generate-setup +5 -0
- data/lib/setup_script_generator/cli.rb +199 -0
- data/lib/setup_script_generator/templates/customizable-section.sh +10 -0
- data/lib/setup_script_generator/templates/non-customizable-section.sh.erb +190 -0
- data/lib/setup_script_generator/templates/provisions/bash.sh +6 -0
- data/lib/setup_script_generator/templates/provisions/elm.sh +22 -0
- data/lib/setup_script_generator/templates/provisions/heroku.sh +6 -0
- data/lib/setup_script_generator/templates/provisions/node.sh +61 -0
- data/lib/setup_script_generator/templates/provisions/postgresql.sh +19 -0
- data/lib/setup_script_generator/templates/provisions/ruby.sh +63 -0
- data/lib/setup_script_generator/templates/provisions/sqlite3.sh +11 -0
- data/lib/setup_script_generator/templates/skeleton.sh.erb +7 -0
- data/lib/setup_script_generator/version.rb +3 -0
- data/setup_script_generator.gemspec +37 -0
- metadata +98 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7b641747f34456dd34dc4b20a778afaac326a434768343287cab7feef3c89bee
|
4
|
+
data.tar.gz: '0893528542d93ea1d8dd8b8905e16ef0bc5e9de41097ed9e42a6c93232c8f33c'
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e926f73fa6112f27a9670df108b60475bad4cc95494d81684ea80819d9296fb18d6d033dd1c878b3a0a4f59032fe2ea8c4705c8a01a39119a2f0d2395d8543c4
|
7
|
+
data.tar.gz: 0e554f39ce7ffa60271700978a7ccd69065e66194aec4766d991f2acfa8d6696ea202490913fdb02d9e10bcf4588390963683dcfeda037e36bb87c5b5a608526
|
data/.gitignore
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.6.3
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
setup_script_generator (0.2.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
rake (10.5.0)
|
10
|
+
|
11
|
+
PLATFORMS
|
12
|
+
ruby
|
13
|
+
|
14
|
+
DEPENDENCIES
|
15
|
+
bundler (~> 1.17)
|
16
|
+
rake (~> 10.0)
|
17
|
+
setup_script_generator!
|
18
|
+
|
19
|
+
BUNDLED WITH
|
20
|
+
1.17.3
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2019 Elliot Winkler
|
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
|
13
|
+
all 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
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# Setup Script Generator
|
2
|
+
|
3
|
+
Every project needs a [setup script][setup-script]. This is an executable that a
|
4
|
+
new contributor to the project can run in order to quickly prepare his or her
|
5
|
+
machine for development.
|
6
|
+
|
7
|
+
[setup-script]: https://thoughtbot.com/blog/shell-script-suggestions-for-speedy-setups
|
8
|
+
|
9
|
+
The problem is that a good setup script is time-consuming to write:
|
10
|
+
|
11
|
+
* The script must be portable, which means handling installation of software
|
12
|
+
using package managers on different platforms.
|
13
|
+
* The script must be snappy, which (along with the previous point) dictates the
|
14
|
+
use of Bash.
|
15
|
+
* The script must make sure that the proper version of your project's
|
16
|
+
implementation language is installed, and if said language has version
|
17
|
+
managers (such as for Ruby or Node), the script must take them into account
|
18
|
+
as well.
|
19
|
+
* The script must provide friendly errors if any checks fail.
|
20
|
+
(Bonus points for colors and/or emoji.)
|
21
|
+
* The script must be idempotent, so that if changes to the development are
|
22
|
+
made, the script can be run again, and any requirements that are already
|
23
|
+
satisfied will be skipped, while new requirements will be installed.
|
24
|
+
* The script must be easy to read and maintain in the future.
|
25
|
+
|
26
|
+
Given this, this project provides a way to generate a setup script for your own
|
27
|
+
project, so that you can keep all of your teammates on the same page and offer
|
28
|
+
them a nice experience going forward.
|
29
|
+
|
30
|
+
## Installation
|
31
|
+
|
32
|
+
Currently, the generator is available through a Ruby gem. You can install this
|
33
|
+
gem by first installing Ruby, then running:
|
34
|
+
|
35
|
+
gem install setup_script_generator
|
36
|
+
|
37
|
+
## Usage
|
38
|
+
|
39
|
+
After installing the gem, navigate to your project. Generally, setup scripts are
|
40
|
+
kept in `bin`, so to generate a script, run:
|
41
|
+
|
42
|
+
generate-setup bin/setup
|
43
|
+
|
44
|
+
Now, by default, this won't do a whole lot. That's because a setup script is
|
45
|
+
much more useful with *provisions*, which add checks and steps for a particular
|
46
|
+
language, framework, or service. For instance, if your project requires Ruby,
|
47
|
+
then you'd want to say:
|
48
|
+
|
49
|
+
generate-setup bin/setup --provision ruby
|
50
|
+
|
51
|
+
You can add more than one provision if that's what you need:
|
52
|
+
|
53
|
+
generate-setup bin/setup --provision ruby --provision node
|
54
|
+
|
55
|
+
You can get a list of available provisions by running:
|
56
|
+
|
57
|
+
generate-setup --list-provisions
|
58
|
+
|
59
|
+
And if you want to view the setup script before you generate it, you can tack
|
60
|
+
`--dry-run` to the end of the command. For instance:
|
61
|
+
|
62
|
+
generate-setup bin/setup --provision ruby --dry-run
|
63
|
+
|
64
|
+
Finally, to see the full list of options, run:
|
65
|
+
|
66
|
+
generate-setup --help
|
67
|
+
|
68
|
+
## Development
|
69
|
+
|
70
|
+
Naturally, this gem comes with its own setup script you can use to get started.
|
71
|
+
Just run:
|
72
|
+
|
73
|
+
bin/setup
|
74
|
+
|
75
|
+
To release a new version, update `version.rb`, then run `rake release`.
|
76
|
+
|
77
|
+
## Author/License
|
78
|
+
|
79
|
+
(c) 2019 Elliot Winkler (<elliot.winkler@gmail.com>).
|
80
|
+
|
81
|
+
Available under the [MIT license](LICENSE.txt).
|
data/Rakefile
ADDED
data/bin/setup
ADDED
@@ -0,0 +1,232 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -euo pipefail
|
4
|
+
|
5
|
+
something_already_printed=0
|
6
|
+
|
7
|
+
cd "$(dirname "$(dirname "$0")")"
|
8
|
+
|
9
|
+
determine-platform() {
|
10
|
+
local uname=$(uname)
|
11
|
+
|
12
|
+
if [[ $uname == 'Darwin' ]]; then
|
13
|
+
echo 'mac'
|
14
|
+
else
|
15
|
+
echo 'linux'
|
16
|
+
fi
|
17
|
+
}
|
18
|
+
|
19
|
+
banner() {
|
20
|
+
print-with-color 34 "== $@ =="
|
21
|
+
}
|
22
|
+
|
23
|
+
success() {
|
24
|
+
print-with-color 32 "$@"
|
25
|
+
}
|
26
|
+
|
27
|
+
warning() {
|
28
|
+
print-with-color 33 "$@"
|
29
|
+
}
|
30
|
+
|
31
|
+
error() {
|
32
|
+
print-with-color 31 "$@"
|
33
|
+
}
|
34
|
+
|
35
|
+
print-with-color() {
|
36
|
+
pad-from-existing-output
|
37
|
+
echo -ne "\033[${1}m"
|
38
|
+
echo -n "${@:2}"
|
39
|
+
echo -e "\033[0m"
|
40
|
+
something_already_printed=1
|
41
|
+
}
|
42
|
+
|
43
|
+
print-wrapped() {
|
44
|
+
pad-from-existing-output
|
45
|
+
echo -n "$@" | fmt -w 80 | cat
|
46
|
+
something_already_printed=1
|
47
|
+
}
|
48
|
+
|
49
|
+
pad-from-existing-output() {
|
50
|
+
if [[ $something_already_printed -eq 1 ]]; then
|
51
|
+
echo
|
52
|
+
fi
|
53
|
+
}
|
54
|
+
|
55
|
+
print() {
|
56
|
+
pad-from-existing-output
|
57
|
+
echo "$@"
|
58
|
+
something_already_printed=1
|
59
|
+
}
|
60
|
+
|
61
|
+
has-executable() {
|
62
|
+
type "$1" &>/dev/null
|
63
|
+
}
|
64
|
+
|
65
|
+
is-running() {
|
66
|
+
pgrep "$1" >/dev/null
|
67
|
+
}
|
68
|
+
|
69
|
+
start() {
|
70
|
+
if has-executable brew; then
|
71
|
+
brew services start "$1"
|
72
|
+
else
|
73
|
+
sudo service "${2:-$1}" start
|
74
|
+
fi
|
75
|
+
}
|
76
|
+
|
77
|
+
install() {
|
78
|
+
local apt_package=""
|
79
|
+
local rpm_package=""
|
80
|
+
local brew_package=""
|
81
|
+
local default_package=""
|
82
|
+
local package=""
|
83
|
+
|
84
|
+
for arg in "$@"; do
|
85
|
+
case $arg in
|
86
|
+
apt=*)
|
87
|
+
apt_package="${arg#apt=}"
|
88
|
+
;;
|
89
|
+
rpm=*)
|
90
|
+
rpm_package="${arg#rpm=}"
|
91
|
+
;;
|
92
|
+
brew=*)
|
93
|
+
brew_package="${arg#brew=}"
|
94
|
+
;;
|
95
|
+
*)
|
96
|
+
default_package="$arg"
|
97
|
+
;;
|
98
|
+
esac
|
99
|
+
done
|
100
|
+
|
101
|
+
if has-executable brew; then
|
102
|
+
package="${brew_package:-$default_package}"
|
103
|
+
|
104
|
+
if [[ -n $package ]]; then
|
105
|
+
brew install "$package"
|
106
|
+
fi
|
107
|
+
elif has-executable apt-get; then
|
108
|
+
package="${apt_package:-$default_package}"
|
109
|
+
|
110
|
+
if [[ -n $package ]]; then
|
111
|
+
sudo apt-get install -y "$package"
|
112
|
+
fi
|
113
|
+
elif has-executable yum; then
|
114
|
+
package="${yum_package:-$default_package}"
|
115
|
+
|
116
|
+
if [[ -n $package ]]; then
|
117
|
+
sudo yum install -y "$package"
|
118
|
+
fi
|
119
|
+
else
|
120
|
+
error "Sorry, I'm not sure how to install $default_package."
|
121
|
+
exit 1
|
122
|
+
fi
|
123
|
+
}
|
124
|
+
|
125
|
+
check-for-package-manager() {
|
126
|
+
local platform=$(determine-platform)
|
127
|
+
|
128
|
+
if [[ $platform == "linux" ]]; then
|
129
|
+
if ! has-executable apt-get; then
|
130
|
+
error "You don't seem to have a package manager installed."
|
131
|
+
print-wrapped "\
|
132
|
+
The setup script assumes you're using Debian or a Debian-derived flavor of
|
133
|
+
Linux (i.e. something with Apt). If this is not the case, then we would
|
134
|
+
gladly take a PR fixing this!"
|
135
|
+
exit 1
|
136
|
+
fi
|
137
|
+
else
|
138
|
+
if ! has-executable brew; then
|
139
|
+
error "You don't seem to have Homebrew installed."
|
140
|
+
print-wrapped "\
|
141
|
+
Follow the instructions here to do this:
|
142
|
+
|
143
|
+
http://brew.sh
|
144
|
+
|
145
|
+
Then re-run this script."
|
146
|
+
exit 1
|
147
|
+
fi
|
148
|
+
|
149
|
+
# TODO: Check that OS X Command Line Tools are installed?
|
150
|
+
fi
|
151
|
+
}
|
152
|
+
|
153
|
+
install-development-libraries() {
|
154
|
+
install rpm=zlib-devel
|
155
|
+
}
|
156
|
+
|
157
|
+
provision-ruby() {
|
158
|
+
if [[ -f .ruby-version ]]; then
|
159
|
+
REQUIRED_RUBY_VERSION=$(cat .ruby-version)
|
160
|
+
else
|
161
|
+
error "You don't seem to have a Ruby version set in your project."
|
162
|
+
print-wrapped "\
|
163
|
+
You'll need to create a .ruby-version file in your project before you can run
|
164
|
+
this script.
|
165
|
+
"
|
166
|
+
exit 1
|
167
|
+
fi
|
168
|
+
|
169
|
+
install-ruby-development-library
|
170
|
+
ensure-ruby-installed
|
171
|
+
install-ruby-dependencies
|
172
|
+
}
|
173
|
+
|
174
|
+
install-ruby-development-library() {
|
175
|
+
install apt=ruby-dev rpm=ruby-devel
|
176
|
+
}
|
177
|
+
|
178
|
+
ensure-ruby-installed() {
|
179
|
+
if has-executable rbenv; then
|
180
|
+
if ! (rbenv versions | grep $REQUIRED_RUBY_VERSION'\>' &>/dev/null); then
|
181
|
+
banner "Installing Ruby $REQUIRED_RUBY_VERSION with rbenv"
|
182
|
+
rbenv install --skip-existing "$REQUIRED_RUBY_VERSION"
|
183
|
+
fi
|
184
|
+
elif has-executable chruby-exec; then
|
185
|
+
PREFIX='' source /usr/local/share/chruby/chruby.sh
|
186
|
+
if ! (chruby '' | grep $REQUIRED_RUBY_VERSION'\>' &>/dev/null); then
|
187
|
+
if has-executable install-ruby; then
|
188
|
+
banner "Installing Ruby $REQUIRED_RUBY_VERSION with install-ruby"
|
189
|
+
install-ruby "$REQUIRED_RUBY_VERSION"
|
190
|
+
else
|
191
|
+
error "Please install Ruby $REQUIRED_RUBY_VERSION"
|
192
|
+
fi
|
193
|
+
fi
|
194
|
+
elif has-executable rvm; then
|
195
|
+
if ! (rvm list | grep $required_ruby_version'\>' &>/dev/null); then
|
196
|
+
banner "Installing Ruby $required_ruby_version with rvm"
|
197
|
+
rvm install $required_ruby_version
|
198
|
+
rvm use $required_ruby_version
|
199
|
+
fi
|
200
|
+
else
|
201
|
+
error "You don't seem to have a Ruby manager installed."
|
202
|
+
print-wrapped "\
|
203
|
+
We recommend using rbenv. You can find instructions to install it here:
|
204
|
+
|
205
|
+
https://github.com/rbenv/rbenv#installation
|
206
|
+
|
207
|
+
Make sure to follow the instructions to configure your shell so that rbenv is
|
208
|
+
automatically loaded.
|
209
|
+
|
210
|
+
When you're done, open up a new terminal tab and re-run this script."
|
211
|
+
exit 1
|
212
|
+
fi
|
213
|
+
}
|
214
|
+
|
215
|
+
install-ruby-dependencies() {
|
216
|
+
banner 'Installing Ruby dependencies'
|
217
|
+
gem install bundler -v '~> 1.0' --conservative
|
218
|
+
bundle check || bundle install
|
219
|
+
}
|
220
|
+
|
221
|
+
run-provisions() {
|
222
|
+
provision-ruby
|
223
|
+
}
|
224
|
+
|
225
|
+
setup() {
|
226
|
+
check-for-package-manager
|
227
|
+
install-development-libraries
|
228
|
+
run-provisions
|
229
|
+
success "Done!"
|
230
|
+
}
|
231
|
+
|
232
|
+
setup
|
data/exe/generate-setup
ADDED
@@ -0,0 +1,199 @@
|
|
1
|
+
require "pathname"
|
2
|
+
require "optparse"
|
3
|
+
require "erb"
|
4
|
+
|
5
|
+
require_relative "version"
|
6
|
+
|
7
|
+
module SetupScriptGenerator
|
8
|
+
class Cli
|
9
|
+
TEMPLATES_DIR = Pathname.new("./templates").expand_path(__dir__)
|
10
|
+
PROVISIONS_DIR = TEMPLATES_DIR.join("provisions")
|
11
|
+
SKELETON_TEMPLATE_PATH = TEMPLATES_DIR.join("skeleton.sh.erb")
|
12
|
+
CUSTOMIZABLE_SECTION_PATH = TEMPLATES_DIR.join("customizable-section.sh")
|
13
|
+
NON_CUSTOMIZABLE_SECTION_PATH = TEMPLATES_DIR.join("non-customizable-section.sh.erb")
|
14
|
+
NON_CUSTOMIZABLE_SECTION_MARKER = <<-MARKER.strip
|
15
|
+
### DON'T MODIFY ANYTHING BELOW THIS LINE! #####################################
|
16
|
+
MARKER
|
17
|
+
|
18
|
+
def self.call(args, stdout, stderr)
|
19
|
+
new(args, stdout, stderr).call
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(args, stdout, stderr)
|
23
|
+
@args = args
|
24
|
+
@stdout = stdout
|
25
|
+
@stderr = stderr
|
26
|
+
|
27
|
+
@provision_names = []
|
28
|
+
@dry_run = false
|
29
|
+
end
|
30
|
+
|
31
|
+
def call
|
32
|
+
parse_args!(args)
|
33
|
+
validate_provision_names!
|
34
|
+
|
35
|
+
if dry_run?
|
36
|
+
stdout.puts generated_content
|
37
|
+
else
|
38
|
+
output_file.parent.mkpath
|
39
|
+
output_file.write(generated_content)
|
40
|
+
output_file.chmod(0744)
|
41
|
+
stdout.puts "File written to: #{output_file}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
attr_reader :args, :stdout, :stderr, :provision_names
|
48
|
+
|
49
|
+
def dry_run?
|
50
|
+
@dry_run
|
51
|
+
end
|
52
|
+
|
53
|
+
def parse_args!(args)
|
54
|
+
option_parser.parse!(args)
|
55
|
+
|
56
|
+
if args.empty?
|
57
|
+
error "Must provide an output file!"
|
58
|
+
stderr.puts
|
59
|
+
stderr.puts option_parser
|
60
|
+
exit 1
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def option_parser
|
65
|
+
@_option_parser ||= OptionParser.new do |parser|
|
66
|
+
parser.banner = "#{$0} [OPTIONS] OUTPUT_FILE"
|
67
|
+
|
68
|
+
parser.on(
|
69
|
+
"-p",
|
70
|
+
"--provision [NAME]",
|
71
|
+
String,
|
72
|
+
"Inserts code into the setup script to provision a library or " +
|
73
|
+
"package when the script runs."
|
74
|
+
) do |provision_name|
|
75
|
+
provision_names << provision_name
|
76
|
+
end
|
77
|
+
|
78
|
+
parser.on("-n", "--dry-run", "Outputs the generated script instead of writing to the file.") do
|
79
|
+
@dry_run = true
|
80
|
+
end
|
81
|
+
|
82
|
+
parser.on("-l", "--list-provisions", "Lists the available provisions.") do
|
83
|
+
stdout.puts "Here are the provisions you can specify with --provision NAME:"
|
84
|
+
|
85
|
+
valid_provision_names.sort.each do |provision_name|
|
86
|
+
stdout.puts "* #{provision_name}"
|
87
|
+
end
|
88
|
+
|
89
|
+
exit
|
90
|
+
end
|
91
|
+
|
92
|
+
parser.on("-h", "--help", "You're looking at it!") do
|
93
|
+
puts parser
|
94
|
+
exit
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def output_file
|
100
|
+
Pathname.new(args.first).expand_path(ENV["PWD"])
|
101
|
+
end
|
102
|
+
|
103
|
+
def validate_provision_names!
|
104
|
+
invalid_provision_name = provision_names.find do |provision_name|
|
105
|
+
!valid_provision_names.include?(provision_name)
|
106
|
+
end
|
107
|
+
|
108
|
+
if invalid_provision_name
|
109
|
+
error "Invalid provision: #{invalid_provision_name}"
|
110
|
+
stderr.puts "Valid provisions are: #{valid_provision_names.join(', ')}"
|
111
|
+
exit 2
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def valid_provision_names
|
116
|
+
@_valid_provision_names ||= PROVISIONS_DIR.glob("*").map do |path|
|
117
|
+
path.basename(".sh").to_s
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def generated_content
|
122
|
+
if output_file.exist?
|
123
|
+
content = ""
|
124
|
+
|
125
|
+
output_file.each_line do |line|
|
126
|
+
if line == "#{NON_CUSTOMIZABLE_SECTION_MARKER}\n"
|
127
|
+
content << non_customizable_section
|
128
|
+
break
|
129
|
+
else
|
130
|
+
content << line
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
content
|
135
|
+
else
|
136
|
+
skeleton
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def skeleton
|
141
|
+
@_skeleton ||= RenderFile.call(
|
142
|
+
SKELETON_TEMPLATE_PATH,
|
143
|
+
customizable_section: customizable_section,
|
144
|
+
non_customizable_section: non_customizable_section
|
145
|
+
)
|
146
|
+
end
|
147
|
+
|
148
|
+
def customizable_section
|
149
|
+
@_customizable_section ||= File.read(CUSTOMIZABLE_SECTION_PATH)
|
150
|
+
end
|
151
|
+
|
152
|
+
def non_customizable_section
|
153
|
+
@_non_customizable_section ||= RenderFile.call(
|
154
|
+
NON_CUSTOMIZABLE_SECTION_PATH,
|
155
|
+
provisions: provisions,
|
156
|
+
version: SetupScriptGenerator::VERSION
|
157
|
+
)
|
158
|
+
end
|
159
|
+
|
160
|
+
def provisions
|
161
|
+
@_provisions ||= provision_names.map do |provision_name|
|
162
|
+
Provision.new(provision_name, PROVISIONS_DIR)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def error(message)
|
167
|
+
stderr.puts "\e[31m[Error] #{message}\e[0m"
|
168
|
+
end
|
169
|
+
|
170
|
+
class Provision
|
171
|
+
attr_reader :name
|
172
|
+
|
173
|
+
def initialize(name, provisions_directory)
|
174
|
+
@name = name
|
175
|
+
@provisions_directory = provisions_directory
|
176
|
+
end
|
177
|
+
|
178
|
+
def code
|
179
|
+
@_code ||= file.read
|
180
|
+
end
|
181
|
+
|
182
|
+
def valid?
|
183
|
+
file.exist?
|
184
|
+
end
|
185
|
+
|
186
|
+
private
|
187
|
+
|
188
|
+
attr_reader :provisions_directory
|
189
|
+
|
190
|
+
def file
|
191
|
+
@_file ||= provisions_directory.join("#{name}.sh")
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
RenderFile = lambda do |file, context|
|
196
|
+
ERB.new(file.read, trim_mode: '-').result_with_hash(context)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
### PROJECT SETUP ##############################################################
|
2
|
+
|
3
|
+
# Feel free to add whatever functions or variables you want to add in this
|
4
|
+
# section.
|
5
|
+
|
6
|
+
provision-project() {
|
7
|
+
# This function gets called automatically below.
|
8
|
+
# Feel free to remove these comments.
|
9
|
+
# If your project needs custom setup, then place that here.
|
10
|
+
}
|
@@ -0,0 +1,190 @@
|
|
1
|
+
### DON'T MODIFY ANYTHING BELOW THIS LINE! #####################################
|
2
|
+
|
3
|
+
# This setup script was generated with setup_script_generator <%= version %>,
|
4
|
+
# available on RubyGems.
|
5
|
+
#
|
6
|
+
# To regenerate this section, install the gem and run:
|
7
|
+
#
|
8
|
+
<% if provisions.any? -%>
|
9
|
+
# generate-setup \
|
10
|
+
<%= provisions.map { |p| "# -p #{p}" }.join(" \\\n") -%>
|
11
|
+
<% else -%>
|
12
|
+
# generate-setup
|
13
|
+
<% end -%>
|
14
|
+
|
15
|
+
something_already_printed=0
|
16
|
+
|
17
|
+
determine-platform() {
|
18
|
+
local uname=$(uname)
|
19
|
+
|
20
|
+
if [[ $uname == 'Darwin' ]]; then
|
21
|
+
echo 'mac'
|
22
|
+
else
|
23
|
+
echo 'linux'
|
24
|
+
fi
|
25
|
+
}
|
26
|
+
|
27
|
+
banner() {
|
28
|
+
print-with-color 34 "== $@ =="
|
29
|
+
}
|
30
|
+
|
31
|
+
success() {
|
32
|
+
print-with-color 32 "$@"
|
33
|
+
}
|
34
|
+
|
35
|
+
warning() {
|
36
|
+
print-with-color 33 "$@"
|
37
|
+
}
|
38
|
+
|
39
|
+
error() {
|
40
|
+
print-with-color 31 "$@"
|
41
|
+
}
|
42
|
+
|
43
|
+
print-with-color() {
|
44
|
+
pad-from-existing-output
|
45
|
+
echo -ne "\033[${1}m"
|
46
|
+
echo -n "${@:2}"
|
47
|
+
echo -e "\033[0m"
|
48
|
+
something_already_printed=1
|
49
|
+
}
|
50
|
+
|
51
|
+
print-wrapped() {
|
52
|
+
pad-from-existing-output
|
53
|
+
echo -n "$@" | fmt -w 80 | cat
|
54
|
+
something_already_printed=1
|
55
|
+
}
|
56
|
+
|
57
|
+
pad-from-existing-output() {
|
58
|
+
if [[ $something_already_printed -eq 1 ]]; then
|
59
|
+
echo
|
60
|
+
fi
|
61
|
+
}
|
62
|
+
|
63
|
+
print() {
|
64
|
+
pad-from-existing-output
|
65
|
+
echo "$@"
|
66
|
+
something_already_printed=1
|
67
|
+
}
|
68
|
+
|
69
|
+
has-executable() {
|
70
|
+
type "$1" &>/dev/null
|
71
|
+
}
|
72
|
+
|
73
|
+
is-running() {
|
74
|
+
pgrep "$1" >/dev/null
|
75
|
+
}
|
76
|
+
|
77
|
+
start() {
|
78
|
+
if has-executable brew; then
|
79
|
+
brew services start "$1"
|
80
|
+
else
|
81
|
+
sudo service "${2:-$1}" start
|
82
|
+
fi
|
83
|
+
}
|
84
|
+
|
85
|
+
install() {
|
86
|
+
local apt_package=""
|
87
|
+
local rpm_package=""
|
88
|
+
local brew_package=""
|
89
|
+
local default_package=""
|
90
|
+
local package=""
|
91
|
+
|
92
|
+
for arg in "$@"; do
|
93
|
+
case $arg in
|
94
|
+
apt=*)
|
95
|
+
apt_package="${arg#apt=}"
|
96
|
+
;;
|
97
|
+
rpm=*)
|
98
|
+
rpm_package="${arg#rpm=}"
|
99
|
+
;;
|
100
|
+
brew=*)
|
101
|
+
brew_package="${arg#brew=}"
|
102
|
+
;;
|
103
|
+
*)
|
104
|
+
default_package="$arg"
|
105
|
+
;;
|
106
|
+
esac
|
107
|
+
done
|
108
|
+
|
109
|
+
if has-executable brew; then
|
110
|
+
package="${brew_package:-$default_package}"
|
111
|
+
|
112
|
+
if [[ -n $package ]]; then
|
113
|
+
brew install "$package"
|
114
|
+
fi
|
115
|
+
elif has-executable apt-get; then
|
116
|
+
package="${apt_package:-$default_package}"
|
117
|
+
|
118
|
+
if [[ -n $package ]]; then
|
119
|
+
sudo apt-get install -y "$package"
|
120
|
+
fi
|
121
|
+
elif has-executable yum; then
|
122
|
+
package="${yum_package:-$default_package}"
|
123
|
+
|
124
|
+
if [[ -n $package ]]; then
|
125
|
+
sudo yum install -y "$package"
|
126
|
+
fi
|
127
|
+
else
|
128
|
+
error "Sorry, I'm not sure how to install $default_package."
|
129
|
+
exit 1
|
130
|
+
fi
|
131
|
+
}
|
132
|
+
|
133
|
+
check-for-package-manager() {
|
134
|
+
local platform=$(determine-platform)
|
135
|
+
|
136
|
+
if [[ $platform == "linux" ]]; then
|
137
|
+
if ! has-executable apt-get; then
|
138
|
+
error "You don't seem to have a package manager installed."
|
139
|
+
print-wrapped "\
|
140
|
+
The setup script assumes you're using Debian or a Debian-derived flavor of
|
141
|
+
Linux (i.e. something with Apt). If this is not the case, then we would
|
142
|
+
gladly take a PR fixing this!"
|
143
|
+
exit 1
|
144
|
+
fi
|
145
|
+
else
|
146
|
+
if ! has-executable brew; then
|
147
|
+
error "You don't seem to have Homebrew installed."
|
148
|
+
print-wrapped "\
|
149
|
+
Follow the instructions here to do this:
|
150
|
+
|
151
|
+
http://brew.sh
|
152
|
+
|
153
|
+
Then re-run this script."
|
154
|
+
exit 1
|
155
|
+
fi
|
156
|
+
|
157
|
+
# TODO: Check that OS X Command Line Tools are installed?
|
158
|
+
fi
|
159
|
+
}
|
160
|
+
|
161
|
+
install-development-libraries() {
|
162
|
+
install rpm=zlib-devel
|
163
|
+
}
|
164
|
+
|
165
|
+
<% provisions.each do |provision| -%>
|
166
|
+
<%= provision.code -%>
|
167
|
+
|
168
|
+
<% end -%>
|
169
|
+
<% if provisions.any? -%>
|
170
|
+
run-provisions() {
|
171
|
+
<% provisions.each do |provision| -%>
|
172
|
+
provision-<%= provision.name %>
|
173
|
+
<% end -%>
|
174
|
+
provision-project
|
175
|
+
}
|
176
|
+
|
177
|
+
<% end -%>
|
178
|
+
setup() {
|
179
|
+
cd "$(dirname "$(dirname "$0")")"
|
180
|
+
check-for-package-manager
|
181
|
+
<%# TODO: Check if build-essential is installed on Debian? -%>
|
182
|
+
install-development-libraries
|
183
|
+
<% if provisions.any? -%>
|
184
|
+
run-provisions
|
185
|
+
<% end -%>
|
186
|
+
provision-project
|
187
|
+
success "Done!"
|
188
|
+
}
|
189
|
+
|
190
|
+
setup
|
@@ -0,0 +1,22 @@
|
|
1
|
+
provision-elm() {
|
2
|
+
local platform=$(determine-platform)
|
3
|
+
|
4
|
+
if ! has-executable elm; then
|
5
|
+
banner "Installing Elm"
|
6
|
+
|
7
|
+
if [[ $platform == "mac" ]]; then
|
8
|
+
install brew=elm
|
9
|
+
else
|
10
|
+
print-wrapped "\
|
11
|
+
It doesn't look like you have Elm installed.
|
12
|
+
|
13
|
+
Elm is easy to install on Mac, but requires more manual work on other platforms.
|
14
|
+
The best thing to do is to follow the installation instructions on the official
|
15
|
+
Elm guide:
|
16
|
+
|
17
|
+
https://guide.elm-lang.org/install/elm.html
|
18
|
+
"
|
19
|
+
exit 1
|
20
|
+
fi
|
21
|
+
fi
|
22
|
+
}
|
@@ -0,0 +1,61 @@
|
|
1
|
+
provision-node() {
|
2
|
+
if [[ -f .node-version ]]; then
|
3
|
+
REQUIRED_NODE_VERSION=$(cat .node-version)
|
4
|
+
elif [[ -f .nvmrc ]]; then
|
5
|
+
REQUIRED_NODE_VERSION=$(cat .nvmrc)
|
6
|
+
else
|
7
|
+
error "You don't seem to have a Node version set in your project."
|
8
|
+
print-wrapped "\
|
9
|
+
You'll need to create a .node-version or .nvmrc file in your project before you
|
10
|
+
can run this script.
|
11
|
+
"
|
12
|
+
exit 1
|
13
|
+
fi
|
14
|
+
|
15
|
+
ensure-node-installed
|
16
|
+
install-node-dependencies
|
17
|
+
}
|
18
|
+
|
19
|
+
ensure-node-installed() {
|
20
|
+
if has-executable nodenv; then
|
21
|
+
if ! (nodenv versions | grep $REQUIRED_NODE_VERSION'\>' &>/dev/null); then
|
22
|
+
banner "Installing Node $REQUIRED_NODE_VERSION with nodenv"
|
23
|
+
nodenv install --skip-existing "$REQUIRED_NODE_VERSION"
|
24
|
+
fi
|
25
|
+
elif has-executable nvm; then
|
26
|
+
if ! (nvm list | grep $required_node_version'\>' &>/dev/null); then
|
27
|
+
banner "Installing node $required_node_version with nvm"
|
28
|
+
nvm install $required_node_version
|
29
|
+
nvm use $required_node_version
|
30
|
+
fi
|
31
|
+
else
|
32
|
+
error "You don't seem to have a Node manager installed."
|
33
|
+
print-wrapped "\
|
34
|
+
We recommend using nodenv. You can find instructions to install it here:
|
35
|
+
|
36
|
+
https://github.com/nodenv/nodenv#installation
|
37
|
+
|
38
|
+
Make sure to follow the instructions to configure your shell so that nodenv is
|
39
|
+
automatically loaded.
|
40
|
+
|
41
|
+
When you're done, open up a new terminal tab and re-run this script."
|
42
|
+
exit 1
|
43
|
+
fi
|
44
|
+
}
|
45
|
+
|
46
|
+
install-node-dependencies() {
|
47
|
+
banner 'Installing Node dependencies'
|
48
|
+
|
49
|
+
if [[ -f package-lock.json ]]; then
|
50
|
+
npm install
|
51
|
+
elif [[ -f yarn.lock ]]; then
|
52
|
+
yarn install
|
53
|
+
else
|
54
|
+
error "Sorry, I'm not sure how to install your dependencies."
|
55
|
+
print-wrapped "\
|
56
|
+
You'll need to create a package-lock.json or yarn.lock file in your project
|
57
|
+
before you can run this script.
|
58
|
+
"
|
59
|
+
exit 1
|
60
|
+
fi
|
61
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
provision-postgresql() {
|
2
|
+
ensure-postgresql-installed
|
3
|
+
ensure-postgresql-running
|
4
|
+
}
|
5
|
+
|
6
|
+
ensure-postgresql-installed() {
|
7
|
+
if ! has-executable psql; then
|
8
|
+
banner 'Installing PostgreSQL'
|
9
|
+
install postgresql
|
10
|
+
install apt=libpq-dev rpm=postgresql-devel
|
11
|
+
fi
|
12
|
+
}
|
13
|
+
|
14
|
+
ensure-postgresql-running() {
|
15
|
+
if ! is-running postgres; then
|
16
|
+
banner 'Starting PostgreSQL'
|
17
|
+
start postgresql
|
18
|
+
fi
|
19
|
+
}
|
@@ -0,0 +1,63 @@
|
|
1
|
+
provision-ruby() {
|
2
|
+
if [[ -f .ruby-version ]]; then
|
3
|
+
REQUIRED_RUBY_VERSION=$(cat .ruby-version)
|
4
|
+
else
|
5
|
+
error "You don't seem to have a Ruby version set in your project."
|
6
|
+
print-wrapped "\
|
7
|
+
You'll need to create a .ruby-version file in your project before you can run
|
8
|
+
this script.
|
9
|
+
"
|
10
|
+
exit 1
|
11
|
+
fi
|
12
|
+
|
13
|
+
install-ruby-development-library
|
14
|
+
ensure-ruby-installed
|
15
|
+
install-ruby-dependencies
|
16
|
+
}
|
17
|
+
|
18
|
+
install-ruby-development-library() {
|
19
|
+
install apt=ruby-dev rpm=ruby-devel
|
20
|
+
}
|
21
|
+
|
22
|
+
ensure-ruby-installed() {
|
23
|
+
if has-executable rbenv; then
|
24
|
+
if ! (rbenv versions | grep $REQUIRED_RUBY_VERSION'\>' &>/dev/null); then
|
25
|
+
banner "Installing Ruby $REQUIRED_RUBY_VERSION with rbenv"
|
26
|
+
rbenv install --skip-existing "$REQUIRED_RUBY_VERSION"
|
27
|
+
fi
|
28
|
+
elif has-executable chruby-exec; then
|
29
|
+
PREFIX='' source /usr/local/share/chruby/chruby.sh
|
30
|
+
if ! (chruby '' | grep $REQUIRED_RUBY_VERSION'\>' &>/dev/null); then
|
31
|
+
if has-executable install-ruby; then
|
32
|
+
banner "Installing Ruby $REQUIRED_RUBY_VERSION with install-ruby"
|
33
|
+
install-ruby "$REQUIRED_RUBY_VERSION"
|
34
|
+
else
|
35
|
+
error "Please install Ruby $REQUIRED_RUBY_VERSION"
|
36
|
+
fi
|
37
|
+
fi
|
38
|
+
elif has-executable rvm; then
|
39
|
+
if ! (rvm list | grep $required_ruby_version'\>' &>/dev/null); then
|
40
|
+
banner "Installing Ruby $required_ruby_version with rvm"
|
41
|
+
rvm install $required_ruby_version
|
42
|
+
rvm use $required_ruby_version
|
43
|
+
fi
|
44
|
+
else
|
45
|
+
error "You don't seem to have a Ruby manager installed."
|
46
|
+
print-wrapped "\
|
47
|
+
We recommend using rbenv. You can find instructions to install it here:
|
48
|
+
|
49
|
+
https://github.com/rbenv/rbenv#installation
|
50
|
+
|
51
|
+
Make sure to follow the instructions to configure your shell so that rbenv is
|
52
|
+
automatically loaded.
|
53
|
+
|
54
|
+
When you're done, open up a new terminal tab and re-run this script."
|
55
|
+
exit 1
|
56
|
+
fi
|
57
|
+
}
|
58
|
+
|
59
|
+
install-ruby-dependencies() {
|
60
|
+
banner 'Installing Ruby dependencies'
|
61
|
+
gem install bundler -v '~> 1.0' --conservative
|
62
|
+
bundle check || bundle install
|
63
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "setup_script_generator/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "setup_script_generator"
|
7
|
+
spec.version = SetupScriptGenerator::VERSION
|
8
|
+
spec.authors = ["Elliot Winkler"]
|
9
|
+
spec.email = ["elliot.winkler@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = %q{Generate setup scripts for your projects.}
|
12
|
+
spec.homepage = "https://github.com/mcmire/setup_script_generator"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
if spec.respond_to?(:metadata)
|
16
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
17
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
18
|
+
spec.metadata["source_code_uri"] = "https://github.com/mcmire/setup_script_generator"
|
19
|
+
spec.metadata["changelog_uri"] = "https://github.com/mcmire/setup_script_generator/tree/master/CHANGELOG.md"
|
20
|
+
else
|
21
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
22
|
+
"public gem pushes."
|
23
|
+
end
|
24
|
+
|
25
|
+
# Specify which files should be added to the gem when it is released.
|
26
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
27
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
28
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
29
|
+
end
|
30
|
+
spec.bindir = "exe"
|
31
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
32
|
+
spec.require_paths = ["lib"]
|
33
|
+
|
34
|
+
spec.add_development_dependency "bundler", "~> 1.17"
|
35
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
36
|
+
# spec.add_development_dependency "rspec", "~> 3.0"
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: setup_script_generator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Elliot Winkler
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-02-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.17'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.17'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
description:
|
42
|
+
email:
|
43
|
+
- elliot.winkler@gmail.com
|
44
|
+
executables:
|
45
|
+
- generate-setup
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- ".gitignore"
|
50
|
+
- ".ruby-version"
|
51
|
+
- Gemfile
|
52
|
+
- Gemfile.lock
|
53
|
+
- LICENSE.txt
|
54
|
+
- README.md
|
55
|
+
- Rakefile
|
56
|
+
- bin/setup
|
57
|
+
- exe/generate-setup
|
58
|
+
- lib/setup_script_generator/cli.rb
|
59
|
+
- lib/setup_script_generator/templates/customizable-section.sh
|
60
|
+
- lib/setup_script_generator/templates/non-customizable-section.sh.erb
|
61
|
+
- lib/setup_script_generator/templates/provisions/bash.sh
|
62
|
+
- lib/setup_script_generator/templates/provisions/elm.sh
|
63
|
+
- lib/setup_script_generator/templates/provisions/heroku.sh
|
64
|
+
- lib/setup_script_generator/templates/provisions/node.sh
|
65
|
+
- lib/setup_script_generator/templates/provisions/postgresql.sh
|
66
|
+
- lib/setup_script_generator/templates/provisions/ruby.sh
|
67
|
+
- lib/setup_script_generator/templates/provisions/sqlite3.sh
|
68
|
+
- lib/setup_script_generator/templates/skeleton.sh.erb
|
69
|
+
- lib/setup_script_generator/version.rb
|
70
|
+
- setup_script_generator.gemspec
|
71
|
+
homepage: https://github.com/mcmire/setup_script_generator
|
72
|
+
licenses:
|
73
|
+
- MIT
|
74
|
+
metadata:
|
75
|
+
allowed_push_host: https://rubygems.org
|
76
|
+
homepage_uri: https://github.com/mcmire/setup_script_generator
|
77
|
+
source_code_uri: https://github.com/mcmire/setup_script_generator
|
78
|
+
changelog_uri: https://github.com/mcmire/setup_script_generator/tree/master/CHANGELOG.md
|
79
|
+
post_install_message:
|
80
|
+
rdoc_options: []
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
requirements: []
|
94
|
+
rubygems_version: 3.0.6
|
95
|
+
signing_key:
|
96
|
+
specification_version: 4
|
97
|
+
summary: Generate setup scripts for your projects.
|
98
|
+
test_files: []
|