init-boilerplate 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'init-boilerplate'
3
+ InitBoilerplate.main
@@ -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: []