init-boilerplate 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/init-boilerplate +3 -0
- data/lib/init-boilerplate.rb +329 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d5d1d339f1bbf2586c033f212bea954a2239eb82751edd4eb015261d5693db97
|
4
|
+
data.tar.gz: 64fabb83bae542f391d7e99b26a64ad4ccf917400a497f7c225c9a2522c435db
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 24ec3174b3f86b490a6d07c3fa01b6c57cceab2bb9b3aed2ede2e7f94b8e49f582e699f52f51f0e725b03c73828dd33f7e9642108872f7879bee25ce6e0b550b
|
7
|
+
data.tar.gz: 168bf2dc07a56904f60175091934bf3df5e1133f5d1a87f0fcaeaab46247f52f160c07f4b70434e34f75267ef719386cf6f67e29ee78832970c829f7b0901080
|
@@ -0,0 +1,329 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'json'
|
3
|
+
require 'colorize'
|
4
|
+
require 'down'
|
5
|
+
|
6
|
+
module InitBoilerplate
|
7
|
+
CONFIGS = [
|
8
|
+
PACKAGE = 'package.json'.freeze,
|
9
|
+
PRETTIER = '.prettierrc'.freeze,
|
10
|
+
NODEMON = 'nodemon.json'.freeze,
|
11
|
+
TS_CONFIG = 'tsconfig.json'.freeze,
|
12
|
+
LINT_STAGED = '.lintstagedrc'.freeze,
|
13
|
+
HUSKY = '.huskyrc'.freeze,
|
14
|
+
ES_LINT = '.eslintrc.json'.freeze,
|
15
|
+
STYLE_LINT = '.stylelintrc.json'.freeze,
|
16
|
+
COMMIT_LINT = '.commitlintrc.json'.freeze
|
17
|
+
].freeze
|
18
|
+
|
19
|
+
def self.display_header
|
20
|
+
puts "\n========================================".colorize(:blue)
|
21
|
+
puts "\tInitialize Boilerplate".colorize(:blue)
|
22
|
+
puts "========================================\n".colorize(:blue)
|
23
|
+
display_pwd
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.display_pwd
|
27
|
+
puts "\nThe current working directory is:".colorize(:green)
|
28
|
+
puts Dir.pwd.to_s.colorize(:green)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.display_menu
|
32
|
+
puts "\n1. Create node.js project".colorize(:blue)
|
33
|
+
puts '2. Create react.js project'.colorize(:blue)
|
34
|
+
puts '3. Add GitHub templates'.colorize(:blue)
|
35
|
+
puts "4. Exit\n".colorize(:blue)
|
36
|
+
puts 'Select an option:'.colorize(:yellow)
|
37
|
+
input = STDIN.gets.chomp.strip
|
38
|
+
process_option(input.to_i)
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.check_already_init
|
42
|
+
if File.file?(PACKAGE)
|
43
|
+
puts "#{PACKAGE} exists and will be used".colorize(:green)
|
44
|
+
else
|
45
|
+
puts "#{PACKAGE} does not exist".colorize(:green)
|
46
|
+
system('npm init -y')
|
47
|
+
package_json = File.read(PACKAGE)
|
48
|
+
package_hash = JSON.parse(package_json)
|
49
|
+
package_hash['description'] = 'TODO'
|
50
|
+
package_hash['repository'] = 'TODO' unless package_hash.key?('repository')
|
51
|
+
File.open(PACKAGE, 'w+') do |file|
|
52
|
+
file.write(JSON.pretty_generate(package_hash))
|
53
|
+
file.close
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.check_npm
|
59
|
+
puts 'Checking npm...'.colorize(:yellow)
|
60
|
+
return unless system('npm --version').nil?
|
61
|
+
|
62
|
+
puts 'Error: npm is not installed'.colorize(:red)
|
63
|
+
exit(1)
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.create_node_directory(typescript)
|
67
|
+
puts 'Creating src directory...'.colorize(:green)
|
68
|
+
path = if typescript
|
69
|
+
'./src/index.ts'
|
70
|
+
else
|
71
|
+
'./src/index.js'
|
72
|
+
end
|
73
|
+
dir = File.dirname(path)
|
74
|
+
FileUtils.mkdir_p(dir) unless File.directory?(dir)
|
75
|
+
File.new(path, 'w+')
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.configure_nodemon
|
79
|
+
puts 'Configuring nodemon...'.colorize(:green)
|
80
|
+
system('npm install --save-dev nodemon')
|
81
|
+
return "#{NODEMON} already exists and will not be configured" if File.exist?(NODEMON)
|
82
|
+
|
83
|
+
hash = {
|
84
|
+
watch: ['src'],
|
85
|
+
ext: '.ts,.js',
|
86
|
+
ignore: [],
|
87
|
+
exec: 'ts-node ./src/index.ts'
|
88
|
+
}
|
89
|
+
File.open(NODEMON, 'w+') do |file|
|
90
|
+
file.truncate(0)
|
91
|
+
file.write(JSON.pretty_generate(hash))
|
92
|
+
file.close
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.update_node_package_json
|
97
|
+
puts "Updating #{PACKAGE} scripts...".colorize(:green)
|
98
|
+
package_json = File.read(PACKAGE)
|
99
|
+
package_hash = JSON.parse(package_json)
|
100
|
+
package_hash['scripts']['start:dev'] = 'nodemon'
|
101
|
+
package_hash['scripts']['build'] = 'rimraf ./build && tsc'
|
102
|
+
package_hash['scripts']['start'] = 'npm run build && node build/index.js'
|
103
|
+
File.open(PACKAGE, 'w+') do |file|
|
104
|
+
file.write(JSON.pretty_generate(package_hash))
|
105
|
+
file.close
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.configure_prettier
|
110
|
+
puts 'Installing and configuring prettier...'.colorize(:green)
|
111
|
+
system('npm install --save-dev prettier')
|
112
|
+
return "#{PRETTIER} already exists and will not be configured" if File.exist?(PRETTIER)
|
113
|
+
|
114
|
+
hash = {
|
115
|
+
trailingComma: 'es5',
|
116
|
+
arrowParens: 'always',
|
117
|
+
singleQuote: true,
|
118
|
+
printWidth: 120
|
119
|
+
}
|
120
|
+
File.open(PRETTIER, 'w+') do |file|
|
121
|
+
file.write(JSON.pretty_generate(hash))
|
122
|
+
file.close
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def self.configure_typescript(react)
|
127
|
+
puts 'Installing and configuring typescript...'.colorize(:green)
|
128
|
+
system('npm install --save-dev typescript @types/node ts-node rimraf')
|
129
|
+
if react
|
130
|
+
system('npm install --save-dev @types/react @types/react-dom @types/jest')
|
131
|
+
else
|
132
|
+
system('npm install --save-dev @types/express')
|
133
|
+
system('npm install express')
|
134
|
+
end
|
135
|
+
system('npx tsc --init --rootDir src --outDir build --moduleResolution "node" --esModuleInterop --resolveJsonModule --sourceMap --module commonjs --allowJs true --noImplicitAny true --target "es6"')
|
136
|
+
end
|
137
|
+
|
138
|
+
def self.configure_eslint(react)
|
139
|
+
puts 'Installing and configuring ESLint...'.colorize(:green)
|
140
|
+
system('npm install --save-dev eslint eslint-plugin-prettier eslint-config-prettier')
|
141
|
+
system('npx eslint --init')
|
142
|
+
es_lint = File.read(ES_LINT)
|
143
|
+
es_lint_hash = JSON.parse(es_lint)
|
144
|
+
es_lint_hash['plugins'] << 'prettier'
|
145
|
+
es_lint_hash['rules']['prettier/prettier'] = 'error'
|
146
|
+
es_lint_hash['rules']['no-console'] = 1
|
147
|
+
es_lint_hash['extends'] << 'prettier'
|
148
|
+
es_lint_hash['extends'] << 'plugin:prettier/recommended'
|
149
|
+
if react
|
150
|
+
es_lint_hash['plugins'] << 'react'
|
151
|
+
es_lint_hash['extends'] << 'plugin:react/recommended'
|
152
|
+
es_lint_hash['extends'] << 'prettier/react'
|
153
|
+
end
|
154
|
+
File.open(ES_LINT, 'w+') do |file|
|
155
|
+
file.write(JSON.pretty_generate(es_lint_hash))
|
156
|
+
file.close
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def self.configure_stylelint
|
161
|
+
puts 'Installing and configuring stylelint...'.colorize(:green)
|
162
|
+
system('npm install --save-dev stylelint stylelint-config-standard stylelint-config-sass-guidelines stylelint-prettier stylelint-config-prettier')
|
163
|
+
hash = {
|
164
|
+
extends: %w[stylelint-config-standard stylelint-config-sass-guidelines stylelint-prettier/recommended],
|
165
|
+
plugins: ['stylelint-prettier'],
|
166
|
+
rules: {
|
167
|
+
'prettier/prettier': true
|
168
|
+
}
|
169
|
+
}
|
170
|
+
File.open(STYLE_LINT, 'w+') do |file|
|
171
|
+
file.write(JSON.pretty_generate(hash))
|
172
|
+
file.close
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def self.configure_commitlint
|
177
|
+
puts 'Installing and configuring commitlint...'
|
178
|
+
system('npm install --save-dev @commitlint/{config-conventional,cli} stylefmt')
|
179
|
+
hash = {
|
180
|
+
extends: ['@commitlint/config-conventional']
|
181
|
+
}
|
182
|
+
File.open(COMMIT_LINT, 'w+') do |file|
|
183
|
+
file.write(JSON.pretty_generate(hash))
|
184
|
+
file.close
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def self.configure_husky
|
189
|
+
puts 'Installing and configuring husky with lint-staged...'
|
190
|
+
system('npx mrm lint-staged')
|
191
|
+
package_json = File.read(PACKAGE)
|
192
|
+
package_hash = JSON.parse(package_json)
|
193
|
+
package_hash['husky']['hooks']['commit-msg'] = 'commitlint -E HUSKY_GIT_PARAMS'
|
194
|
+
git_add = 'git add'
|
195
|
+
package_hash['lint-staged'] = {
|
196
|
+
'*.+(js|jsx|ts|tsx)': [
|
197
|
+
'eslint --cache --fix',
|
198
|
+
git_add
|
199
|
+
],
|
200
|
+
'*.+(json|css|md|html|ts|tsx|jsx)': [
|
201
|
+
'prettier --write',
|
202
|
+
git_add
|
203
|
+
],
|
204
|
+
'*.+(css|less|sass)': [
|
205
|
+
'stylefmt',
|
206
|
+
'stylelint --fix',
|
207
|
+
git_add
|
208
|
+
],
|
209
|
+
'*.+(scss)': [
|
210
|
+
'stylefmt',
|
211
|
+
'stylelint --fix --syntax=scss',
|
212
|
+
git_add
|
213
|
+
]
|
214
|
+
}
|
215
|
+
File.open(PACKAGE, 'w+') do |file|
|
216
|
+
file.write(JSON.pretty_generate(package_hash))
|
217
|
+
file.close
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def self.create_node_project
|
222
|
+
puts 'Does your project use TypeScript? (y/n)'.colorize(:yellow)
|
223
|
+
input = STDIN.gets.strip.chomp
|
224
|
+
typescript = input == 'y'
|
225
|
+
puts 'Make sure this is where you want to create your project (y/n)'.colorize(:magenta)
|
226
|
+
display_pwd
|
227
|
+
confirm = STDIN.gets.strip.chomp
|
228
|
+
exit(0) if confirm != 'y'
|
229
|
+
puts 'Creating node.js project'.colorize(:green)
|
230
|
+
puts 'With TypeScript' if typescript
|
231
|
+
check_npm
|
232
|
+
check_already_init
|
233
|
+
configure_typescript(false) if typescript
|
234
|
+
create_node_directory(typescript)
|
235
|
+
configure_nodemon
|
236
|
+
update_node_package_json
|
237
|
+
configure_prettier
|
238
|
+
configure_eslint(false)
|
239
|
+
configure_commitlint
|
240
|
+
configure_husky
|
241
|
+
end
|
242
|
+
|
243
|
+
def self.create_react_project
|
244
|
+
puts 'Does your project use TypeScript? (y/n)'.colorize(:yellow)
|
245
|
+
input = STDIN.gets.strip.chomp
|
246
|
+
typescript = input == 'y'
|
247
|
+
puts 'Make sure this is where you want to create your project (y/n)'.colorize(:magenta)
|
248
|
+
display_pwd
|
249
|
+
confirm = STDIN.gets.strip.chomp
|
250
|
+
exit(0) if confirm != 'y'
|
251
|
+
puts 'Creating react.js project'.colorize(:green)
|
252
|
+
puts 'With TypeScript' if typescript
|
253
|
+
check_npm
|
254
|
+
check_already_init
|
255
|
+
if typescript
|
256
|
+
configure_typescript(true)
|
257
|
+
system('npx create-react-app . --template typescript')
|
258
|
+
else
|
259
|
+
system('npx create-react-app .')
|
260
|
+
end
|
261
|
+
configure_prettier
|
262
|
+
configure_eslint(true)
|
263
|
+
configure_commitlint
|
264
|
+
configure_husky
|
265
|
+
end
|
266
|
+
|
267
|
+
def self.add_templates
|
268
|
+
puts 'Creating GitHub template files'.colorize(:green)
|
269
|
+
issue_template_dir = '.github/ISSUE_TEMPLATE'
|
270
|
+
pull_request_template_dir = '.github/PULL_REQUEST_TEMPLATE'
|
271
|
+
FileUtils.mkdir_p issue_template_dir
|
272
|
+
FileUtils.mkdir_p pull_request_template_dir
|
273
|
+
|
274
|
+
issue_templates = [
|
275
|
+
'https://github.com/gpnn/git-conventions-guide/raw/master/docs/ISSUE_TEMPLATE/bug.md'.freeze,
|
276
|
+
'https://github.com/gpnn/git-conventions-guide/raw/master/docs/ISSUE_TEMPLATE/epic.md'.freeze,
|
277
|
+
'https://github.com/gpnn/git-conventions-guide/raw/master/docs/ISSUE_TEMPLATE/story.md'.freeze,
|
278
|
+
'https://github.com/gpnn/git-conventions-guide/raw/master/docs/ISSUE_TEMPLATE/sub-task.md'.freeze,
|
279
|
+
'https://github.com/gpnn/git-conventions-guide/raw/master/docs/ISSUE_TEMPLATE/task.md'.freeze
|
280
|
+
].freeze
|
281
|
+
|
282
|
+
pull_request_template = 'https://github.com/gpnn/git-conventions-guide/raw/master/docs/PULL_REQUEST_TEMPLATE/pull_request_template.md'.freeze
|
283
|
+
readme_template = 'https://github.com/gpnn/git-conventions-guide/raw/master/docs/README_template.md'.freeze
|
284
|
+
|
285
|
+
issue_templates.each do |issue_template|
|
286
|
+
tempfile = Down.download(issue_template)
|
287
|
+
FileUtils.mv tempfile.path, "./#{issue_template_dir}/#{tempfile.original_filename}"
|
288
|
+
end
|
289
|
+
|
290
|
+
tempfile = Down.download(pull_request_template)
|
291
|
+
FileUtils.mv tempfile.path, "./#{pull_request_template_dir}/#{tempfile.original_filename}"
|
292
|
+
|
293
|
+
tempfile = Down.download(readme_template)
|
294
|
+
FileUtils.mv tempfile.path, './README.md'
|
295
|
+
|
296
|
+
end
|
297
|
+
|
298
|
+
def self.process_option(choice)
|
299
|
+
case choice
|
300
|
+
when 4
|
301
|
+
puts "\nExiting...".colorize(:green)
|
302
|
+
exit(0)
|
303
|
+
when 3
|
304
|
+
add_templates
|
305
|
+
when 2
|
306
|
+
create_react_project
|
307
|
+
when 1
|
308
|
+
create_node_project
|
309
|
+
else
|
310
|
+
puts "\nYour input is invalid, returning to menu..."
|
311
|
+
display_menu
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
def self.clean_directory
|
316
|
+
puts "\nCleaning directory...".colorize(:blue)
|
317
|
+
FileUtils.rm_rf 'src' if File.directory?('src')
|
318
|
+
CONFIGS.each do |config|
|
319
|
+
File.delete(config) if File.exist?(config)
|
320
|
+
end
|
321
|
+
File.delete('package-lock.json') if File.exist?('package-lock.json')
|
322
|
+
end
|
323
|
+
|
324
|
+
def self.main
|
325
|
+
display_header
|
326
|
+
clean_directory if ARGV[0] == 'clean'
|
327
|
+
display_menu
|
328
|
+
end
|
329
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: init-boilerplate
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gordon Pham-Nguyen
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-03-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: colorize
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.8.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.8.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: down
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 5.1.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 5.1.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: colorize
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.8.1
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.8.1
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: down
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 5.1.1
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 5.1.1
|
69
|
+
description: Supports react.js and node.js projects, with or without TypeScript. Sets
|
70
|
+
up ESLint, Prettier while taking into account for TypeScript. stylefmt and stylelint.
|
71
|
+
Sets up Husky pre-commit and commit message hooks. Sets up lint-staged. Sets up
|
72
|
+
nodemon for node.js projects
|
73
|
+
email: gordon.pn6@gmail.com
|
74
|
+
executables:
|
75
|
+
- init-boilerplate
|
76
|
+
extensions: []
|
77
|
+
extra_rdoc_files: []
|
78
|
+
files:
|
79
|
+
- bin/init-boilerplate
|
80
|
+
- lib/init-boilerplate.rb
|
81
|
+
homepage: https://github.com/gpnn/create-boilerplate-cli/
|
82
|
+
licenses:
|
83
|
+
- MIT
|
84
|
+
metadata: {}
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '2.6'
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubygems_version: 3.1.2
|
101
|
+
signing_key:
|
102
|
+
specification_version: 4
|
103
|
+
summary: Generate boilerplate code for node.js and react.js projects, with all the
|
104
|
+
necessary tooling
|
105
|
+
test_files: []
|