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 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: []