setup_script_generator 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|