pep 0.0.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/bin/pep +11 -0
- data/lib/pep.rb +444 -0
- metadata +45 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: cb620804258e340e261d0df726df127f78663a014c8cfe64c448129be06f9f64
|
4
|
+
data.tar.gz: c04defde77e88500b647bac8f4efc2b14188e339192b391f01593b599c2bdabe
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d58eb26fe8c45db760085bedb618717f9bf5f607cef1634f148e409e45a7ff28e7b1d3f1eb590c1ab439711596905f5600ece2c00a4cbbbc2be70e0d90fe7c6d
|
7
|
+
data.tar.gz: ad446d955b066874fdc4b508e9e083671dfd858fa6ee941a4a1cdc2705607f0331705498c127147d52448419cd7f31244f257cb0585160d48ae0bb48a0e587f4
|
data/bin/pep
ADDED
data/lib/pep.rb
ADDED
@@ -0,0 +1,444 @@
|
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
module NeaHelpers
|
4
|
+
def self.add_development_dependency(dependency_name)
|
5
|
+
system("yarn add -D #{dependency_name}")
|
6
|
+
system("yarn install")
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.add_dependency(dependency_name)
|
10
|
+
system("npx expo install #{dependency_name}")
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.git_commit(with_message:)
|
14
|
+
system("git add .")
|
15
|
+
system("git commit -am '#{with_message}'")
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.add_package_json_script(name:, script:)
|
19
|
+
package_json = JSON.parse(File.read("package.json"))
|
20
|
+
package_json["scripts"][name] = script
|
21
|
+
File.open("package.json", "w+") do |file|
|
22
|
+
file.write(JSON.pretty_generate(package_json))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class CreateTypescriptExpoApp
|
28
|
+
def self.create_typescript_expo_app(with_name:)
|
29
|
+
new(with_name).create_typescript_expo_app
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_reader :app_name
|
33
|
+
|
34
|
+
def initialize(app_name)
|
35
|
+
@app_name = app_name
|
36
|
+
end
|
37
|
+
|
38
|
+
def create_typescript_expo_app
|
39
|
+
system("yarn create expo-app #{app_name} --template blank-typescript")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class AddPrettier
|
44
|
+
def self.add_prettier(to_app_with_name:)
|
45
|
+
new(to_app_with_name).add_prettier
|
46
|
+
end
|
47
|
+
|
48
|
+
attr_reader :app_name
|
49
|
+
|
50
|
+
def initialize(app_name)
|
51
|
+
@app_name = app_name
|
52
|
+
end
|
53
|
+
|
54
|
+
def add_prettier
|
55
|
+
Dir.chdir(app_name) do
|
56
|
+
write_prettier_rc
|
57
|
+
NeaHelpers.add_development_dependency("prettier")
|
58
|
+
NeaHelpers.add_package_json_script(
|
59
|
+
name: "prettier-check",
|
60
|
+
script: "prettier --check './**/*.{ts,tsx}'",
|
61
|
+
)
|
62
|
+
NeaHelpers.add_package_json_script(
|
63
|
+
name: "prettier-fix",
|
64
|
+
script: "prettier --write './**/*.{ts,tsx}'",
|
65
|
+
)
|
66
|
+
system("yarn prettier-fix")
|
67
|
+
NeaHelpers.git_commit(with_message: "Add prettier")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def write_prettier_rc
|
74
|
+
File.open(".prettierrc", "w") do |prettier_rc|
|
75
|
+
prettier_rc.write(prettier_rc_content)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def prettier_rc_content
|
80
|
+
<<~EOS
|
81
|
+
{
|
82
|
+
"printWidth": 80,
|
83
|
+
"tabWidth": 2,
|
84
|
+
"useTabs": false,
|
85
|
+
"semi": false,
|
86
|
+
"singleQuote": false,
|
87
|
+
"quoteProps": "consistent",
|
88
|
+
"jsxSingleQuote": false,
|
89
|
+
"trailingComma": "all",
|
90
|
+
"bracketSpacing": true,
|
91
|
+
"bracketSameLine": false,
|
92
|
+
"arrowParens": "avoid",
|
93
|
+
"requirePragma": false,
|
94
|
+
"insertPragma": false,
|
95
|
+
"proseWrap": "preserve",
|
96
|
+
"endOfLine": "lf",
|
97
|
+
"embeddedLanguageFormatting": "auto",
|
98
|
+
"singleAttributePerLine": false
|
99
|
+
}
|
100
|
+
EOS
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class ConfigureTypescript
|
105
|
+
def self.configure_typescript(in_app_with_name:)
|
106
|
+
new(in_app_with_name).configure_typescript
|
107
|
+
end
|
108
|
+
|
109
|
+
attr_reader :app_name
|
110
|
+
|
111
|
+
def initialize(app_name)
|
112
|
+
@app_name = app_name
|
113
|
+
end
|
114
|
+
|
115
|
+
def configure_typescript
|
116
|
+
Dir.chdir(app_name) do
|
117
|
+
update_tsconfig_json
|
118
|
+
NeaHelpers.add_package_json_script(name: "tsc", script: "tsc")
|
119
|
+
NeaHelpers.git_commit(with_message: "Configure typescript")
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
def update_tsconfig_json
|
126
|
+
tsconfig_json = JSON.parse(File.read("tsconfig.json"))
|
127
|
+
tsconfig_json_compiler_options.each do |name, value|
|
128
|
+
tsconfig_json["compilerOptions"][name] = value
|
129
|
+
end
|
130
|
+
File.open("tsconfig.json", "w+") do |file|
|
131
|
+
file.write(JSON.pretty_generate(tsconfig_json))
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def tsconfig_json_compiler_options
|
136
|
+
{
|
137
|
+
"allowJs" => true,
|
138
|
+
"esModuleInterop" => true,
|
139
|
+
"jsx" => "react-native",
|
140
|
+
"lib" => ["DOM", "ESNext"],
|
141
|
+
"moduleResolution" => "node",
|
142
|
+
"noEmit" => true,
|
143
|
+
"resolveJsonModule" => true,
|
144
|
+
"skipLibCheck" => true,
|
145
|
+
"target" => "ESNext",
|
146
|
+
}
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
class AddEslint
|
151
|
+
def self.add_eslint(to_app_with_name:)
|
152
|
+
new(to_app_with_name).add_eslint
|
153
|
+
end
|
154
|
+
|
155
|
+
attr_reader :app_name
|
156
|
+
|
157
|
+
def initialize(app_name)
|
158
|
+
@app_name = app_name
|
159
|
+
end
|
160
|
+
|
161
|
+
def add_eslint
|
162
|
+
Dir.chdir(app_name) do
|
163
|
+
eslint_development_dependencies.each do |eslint_dev_dep|
|
164
|
+
NeaHelpers.add_development_dependency(eslint_dev_dep)
|
165
|
+
end
|
166
|
+
File.open(".eslintrc.js", "w+") do |file|
|
167
|
+
file.write(eslintrc_js_content)
|
168
|
+
end
|
169
|
+
NeaHelpers.add_package_json_script(
|
170
|
+
name: "lint",
|
171
|
+
script: "eslint '**/*.{ts,tsx}'",
|
172
|
+
)
|
173
|
+
NeaHelpers.git_commit(with_message: "Add eslint")
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
private
|
178
|
+
|
179
|
+
def eslint_development_dependencies
|
180
|
+
[
|
181
|
+
"@typescript-eslint/eslint-plugin",
|
182
|
+
"@typescript-eslint/parser",
|
183
|
+
"eslint",
|
184
|
+
"eslint-plugin-react",
|
185
|
+
"eslint-plugin-react-hooks",
|
186
|
+
"eslint-plugin-react-native",
|
187
|
+
]
|
188
|
+
end
|
189
|
+
|
190
|
+
def eslintrc_js_content
|
191
|
+
<<~EOS
|
192
|
+
module.exports = {
|
193
|
+
root: true,
|
194
|
+
parser: "@typescript-eslint/parser",
|
195
|
+
plugins: ["react", "react-native", "@typescript-eslint", "react-hooks"],
|
196
|
+
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
|
197
|
+
parserOptions: {
|
198
|
+
ecmaFeatures: {
|
199
|
+
jsx: true,
|
200
|
+
},
|
201
|
+
project: "tsconfig.json",
|
202
|
+
},
|
203
|
+
env: {
|
204
|
+
"react-native/react-native": true,
|
205
|
+
},
|
206
|
+
rules: {
|
207
|
+
"react-native/no-unused-styles": 2,
|
208
|
+
"react-native/split-platform-components": 2,
|
209
|
+
"react-native/no-single-element-style-arrays": 2,
|
210
|
+
"react-hooks/rules-of-hooks": "error",
|
211
|
+
"react-hooks/exhaustive-deps": "error",
|
212
|
+
"@typescript-eslint/switch-exhaustiveness-check": "error",
|
213
|
+
"@typescript-eslint/ban-ts-comment": 0,
|
214
|
+
"@typescript-eslint/no-empty-function": 0,
|
215
|
+
},
|
216
|
+
}
|
217
|
+
EOS
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
class SetSrcAsRootDirectory
|
222
|
+
def self.set_src_as_root_directory(in_app_with_name:)
|
223
|
+
new(in_app_with_name).set_src_as_root_directory
|
224
|
+
end
|
225
|
+
|
226
|
+
attr_reader :app_name
|
227
|
+
|
228
|
+
def initialize(app_name)
|
229
|
+
@app_name = app_name
|
230
|
+
end
|
231
|
+
|
232
|
+
def set_src_as_root_directory
|
233
|
+
Dir.chdir(app_name) do
|
234
|
+
update_eslintrc
|
235
|
+
update_babel_config_js
|
236
|
+
move_app_tsx
|
237
|
+
update_tsconfig_json
|
238
|
+
NeaHelpers.git_commit(
|
239
|
+
with_message: "Set /src as the root directory for app code",
|
240
|
+
)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
private
|
245
|
+
|
246
|
+
def update_tsconfig_json
|
247
|
+
package_json = JSON.parse(File.read("tsconfig.json"))
|
248
|
+
package_json["compilerOptions"]["baseUrl"] = "src"
|
249
|
+
File.open("tsconfig.json", "w+") do |file|
|
250
|
+
file.write(JSON.pretty_generate(package_json))
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
def move_app_tsx
|
255
|
+
system("mkdir src")
|
256
|
+
system("mv App.tsx src/")
|
257
|
+
File.open("./App.tsx", "w+") do |file|
|
258
|
+
file.write(
|
259
|
+
<<~EOS
|
260
|
+
import App from "./src/App"
|
261
|
+
|
262
|
+
export default App
|
263
|
+
EOS
|
264
|
+
)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def update_babel_config_js
|
269
|
+
new_content = new_babel_config_js_content
|
270
|
+
File.open("babel.config.js", "w+") do |file|
|
271
|
+
file.write(new_content)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
def new_babel_config_js_content
|
276
|
+
current_lines = File.read("babel.config.js").split("\n")
|
277
|
+
current_lines.inject([]) do |lines, current_line|
|
278
|
+
if current_line == " return {"
|
279
|
+
lines + [current_line] + new_babel_config_js_lines
|
280
|
+
else
|
281
|
+
lines + [current_line]
|
282
|
+
end
|
283
|
+
end.join("\n")
|
284
|
+
end
|
285
|
+
|
286
|
+
def new_babel_config_js_lines
|
287
|
+
[
|
288
|
+
" plugins: [",
|
289
|
+
" [",
|
290
|
+
" \"module-resolver\",",
|
291
|
+
" {",
|
292
|
+
" root: [\"./src\"],",
|
293
|
+
" extensions: [\".ts\", \".tsx\"],",
|
294
|
+
" },",
|
295
|
+
" ],",
|
296
|
+
" ],",
|
297
|
+
]
|
298
|
+
end
|
299
|
+
|
300
|
+
def update_eslintrc
|
301
|
+
new_content = new_eslintrc_content
|
302
|
+
File.open(".eslintrc.js", "w+") do |file|
|
303
|
+
file.write(new_content)
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
def new_eslintrc_content
|
308
|
+
current_lines = File.read(".eslintrc.js").split("\n")
|
309
|
+
new_lines = (
|
310
|
+
current_lines[0..-2] + new_eslintrc_lines + [current_lines[-1]]
|
311
|
+
).join("\n")
|
312
|
+
end
|
313
|
+
|
314
|
+
def new_eslintrc_lines
|
315
|
+
[
|
316
|
+
" settings: {",
|
317
|
+
" \"import/resolver\": {",
|
318
|
+
" node: {",
|
319
|
+
" paths: [\"src\"],",
|
320
|
+
" },",
|
321
|
+
" },",
|
322
|
+
" },",
|
323
|
+
]
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
class InstallReactNavigation
|
328
|
+
def self.install_react_navigation(in_app_with_name:)
|
329
|
+
new(in_app_with_name).install_react_navigation
|
330
|
+
end
|
331
|
+
|
332
|
+
attr_reader :app_name
|
333
|
+
|
334
|
+
def initialize(app_name)
|
335
|
+
@app_name = app_name
|
336
|
+
end
|
337
|
+
|
338
|
+
def install_react_navigation
|
339
|
+
Dir.chdir(app_name) do
|
340
|
+
install_dependencies
|
341
|
+
write_app_tsx
|
342
|
+
NeaHelpers.git_commit(with_message: "Add react navigation")
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
private
|
347
|
+
|
348
|
+
def write_app_tsx
|
349
|
+
File.open("./src/App.tsx", "w+") do |app_tsx|
|
350
|
+
app_tsx.write(app_tsx_content)
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
def install_dependencies
|
355
|
+
[
|
356
|
+
"@react-navigation/native",
|
357
|
+
"react-native-screens",
|
358
|
+
"react-native-safe-area-context",
|
359
|
+
"@react-navigation/native-stack",
|
360
|
+
].each do |dep|
|
361
|
+
NeaHelpers.add_dependency(dep)
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
def app_tsx_content
|
366
|
+
<<~EOS
|
367
|
+
import { Button, Text, TextInput, View } from "react-native"
|
368
|
+
import { DefaultTheme, NavigationContainer } from "@react-navigation/native"
|
369
|
+
import { createNativeStackNavigator } from "@react-navigation/native-stack"
|
370
|
+
import type { NativeStackScreenProps } from "@react-navigation/native-stack"
|
371
|
+
import { useState } from "react"
|
372
|
+
|
373
|
+
type StackNavigatorParams = {
|
374
|
+
Home: undefined
|
375
|
+
Details: { homeScreensTextInputValue: string }
|
376
|
+
}
|
377
|
+
|
378
|
+
type HomeProps = NativeStackScreenProps<StackNavigatorParams, "Home">
|
379
|
+
type DetailsProps = NativeStackScreenProps<StackNavigatorParams, "Details">
|
380
|
+
|
381
|
+
const HomeScreen = ({ navigation }: HomeProps) => {
|
382
|
+
const [homeScreensTextInputValue, setHomescreensTextInputValue] =
|
383
|
+
useState<string>("")
|
384
|
+
return (
|
385
|
+
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
|
386
|
+
<Text>Home Screen</Text>
|
387
|
+
<TextInput
|
388
|
+
value={homeScreensTextInputValue}
|
389
|
+
onChangeText={setHomescreensTextInputValue}
|
390
|
+
placeholder="Type somethin here dawg"
|
391
|
+
style={{ width: "50%", height: 50 }}
|
392
|
+
/>
|
393
|
+
<Button
|
394
|
+
title="Go to Details"
|
395
|
+
onPress={() =>
|
396
|
+
navigation.navigate("Details", { homeScreensTextInputValue })
|
397
|
+
}
|
398
|
+
/>
|
399
|
+
</View>
|
400
|
+
)
|
401
|
+
}
|
402
|
+
|
403
|
+
const DetailsScreen = ({ route }: DetailsProps) => {
|
404
|
+
const { homeScreensTextInputValue } = route.params
|
405
|
+
return (
|
406
|
+
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
|
407
|
+
<Text>Details Screen says: {homeScreensTextInputValue}</Text>
|
408
|
+
</View>
|
409
|
+
)
|
410
|
+
}
|
411
|
+
|
412
|
+
const Stack = createNativeStackNavigator<StackNavigatorParams>()
|
413
|
+
|
414
|
+
const MyTheme = {
|
415
|
+
...DefaultTheme,
|
416
|
+
colors: {
|
417
|
+
...DefaultTheme.colors,
|
418
|
+
background: "#fff",
|
419
|
+
},
|
420
|
+
}
|
421
|
+
|
422
|
+
const App = () => (
|
423
|
+
<NavigationContainer theme={MyTheme}>
|
424
|
+
<Stack.Navigator>
|
425
|
+
<Stack.Screen name="Home" component={HomeScreen} />
|
426
|
+
<Stack.Screen name="Details" component={DetailsScreen} />
|
427
|
+
</Stack.Navigator>
|
428
|
+
</NavigationContainer>
|
429
|
+
)
|
430
|
+
|
431
|
+
export default App
|
432
|
+
EOS
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
def run_pep(with_app_name:)
|
437
|
+
app_name = with_app_name
|
438
|
+
CreateTypescriptExpoApp.create_typescript_expo_app(with_name: app_name)
|
439
|
+
AddPrettier.add_prettier(to_app_with_name: app_name)
|
440
|
+
ConfigureTypescript.configure_typescript(in_app_with_name: app_name)
|
441
|
+
AddEslint.add_eslint(to_app_with_name: app_name)
|
442
|
+
SetSrcAsRootDirectory.set_src_as_root_directory(in_app_with_name: app_name)
|
443
|
+
InstallReactNavigation.install_react_navigation(in_app_with_name: app_name)
|
444
|
+
end
|
metadata
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pep
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nick Pachulski
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-03-14 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Start your expo app with prettier, typescript, eslint, and react navigation.
|
14
|
+
email: nick@pachulski.me
|
15
|
+
executables:
|
16
|
+
- pep
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- bin/pep
|
21
|
+
- lib/pep.rb
|
22
|
+
homepage: https://rubygems.org/gems/pep
|
23
|
+
licenses:
|
24
|
+
- MIT
|
25
|
+
metadata: {}
|
26
|
+
post_install_message:
|
27
|
+
rdoc_options: []
|
28
|
+
require_paths:
|
29
|
+
- lib
|
30
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
requirements: []
|
41
|
+
rubygems_version: 3.4.8
|
42
|
+
signing_key:
|
43
|
+
specification_version: 4
|
44
|
+
summary: Expo app scaffolding
|
45
|
+
test_files: []
|