prepare code to support multiple react interfaces
This commit is contained in:
parent
b9079b4c4b
commit
2d6f5aa8c8
146
re-natal.coffee
146
re-natal.coffee
|
@ -5,10 +5,10 @@
|
||||||
# MIT License
|
# MIT License
|
||||||
|
|
||||||
fs = require 'fs-extra'
|
fs = require 'fs-extra'
|
||||||
|
fpath = require 'path'
|
||||||
net = require 'net'
|
net = require 'net'
|
||||||
http = require 'http'
|
http = require 'http'
|
||||||
os = require 'os'
|
os = require 'os'
|
||||||
crypto = require 'crypto'
|
|
||||||
child = require 'child_process'
|
child = require 'child_process'
|
||||||
cli = require 'commander'
|
cli = require 'commander'
|
||||||
chalk = require 'chalk'
|
chalk = require 'chalk'
|
||||||
|
@ -17,19 +17,31 @@ ckDeps = require 'check-dependencies'
|
||||||
pkgJson = require __dirname + '/package.json'
|
pkgJson = require __dirname + '/package.json'
|
||||||
|
|
||||||
nodeVersion = pkgJson.engines.node
|
nodeVersion = pkgJson.engines.node
|
||||||
resources = __dirname + '/resources/'
|
resources = __dirname + '/resources'
|
||||||
validNameRx = /^[A-Z][0-9A-Z]*$/i
|
validNameRx = /^[A-Z][0-9A-Z]*$/i
|
||||||
camelRx = /([a-z])([A-Z])/g
|
camelRx = /([a-z])([A-Z])/g
|
||||||
projNameRx = /\$PROJECT_NAME\$/g
|
projNameRx = /\$PROJECT_NAME\$/g
|
||||||
projNameHyphRx = /\$PROJECT_NAME_HYPHENATED\$/g
|
projNameHyphRx = /\$PROJECT_NAME_HYPHENATED\$/g
|
||||||
projNameUsRx = /\$PROJECT_NAME_UNDERSCORED\$/g
|
projNameUsRx = /\$PROJECT_NAME_UNDERSCORED\$/g
|
||||||
|
interfaceDepsRx = /\$INTERFACE_DEPS\$/g
|
||||||
platformRx = /\$PLATFORM\$/g
|
platformRx = /\$PLATFORM\$/g
|
||||||
devHostRx = /\$DEV_HOST\$/g
|
devHostRx = /\$DEV_HOST\$/g
|
||||||
figwheelUrlRx = /ws:\/\/[0-9a-zA-Z\.]*:/g
|
figwheelUrlRx = /ws:\/\/[0-9a-zA-Z\.]*:/g
|
||||||
rnVersion = '0.19.0'
|
rnVersion = '0.19.0'
|
||||||
rnPackagerPort = 8081
|
rnPackagerPort = 8081
|
||||||
process.title = 're-natal'
|
process.title = 're-natal'
|
||||||
sampleCommand = '(dispatch [:set-greeting "Hello Native World!"])'
|
interfaceConf =
|
||||||
|
'reagent':
|
||||||
|
cljsDir: "cljs-reagent"
|
||||||
|
sources:
|
||||||
|
ios: ["core.cljs"]
|
||||||
|
android: ["core.cljs"]
|
||||||
|
common: ["handlers.cljs", "subs.cljs", "db.cljs"]
|
||||||
|
deps: ['[reagent "0.5.1" :exclusions [cljsjs/react]]'
|
||||||
|
'[re-frame "0.6.0"]'
|
||||||
|
'[prismatic/schema "1.0.4"]']
|
||||||
|
shims: ["cljsjs.react"]
|
||||||
|
sampleCommand: '(dispatch [:set-greeting "Hello Native World!"])'
|
||||||
|
|
||||||
log = (s, color = 'green') ->
|
log = (s, color = 'green') ->
|
||||||
console.log chalk[color] s
|
console.log chalk[color] s
|
||||||
|
@ -70,13 +82,6 @@ edit = (path, pairs) ->
|
||||||
contents.replace rx, replacement
|
contents.replace rx, replacement
|
||||||
, readFile path
|
, readFile path
|
||||||
|
|
||||||
mkdirSync = (path) ->
|
|
||||||
try
|
|
||||||
fs.mkdirSync(path)
|
|
||||||
catch {message}
|
|
||||||
if not message.match /EEXIST/i
|
|
||||||
throw new Error "Could not create dir #{path}: #{message}" ;
|
|
||||||
|
|
||||||
toUnderscored = (s) ->
|
toUnderscored = (s) ->
|
||||||
s.replace(camelRx, '$1_$2').toLowerCase()
|
s.replace(camelRx, '$1_$2').toLowerCase()
|
||||||
|
|
||||||
|
@ -113,10 +118,11 @@ ensureXcode = (cb) ->
|
||||||
if message.match /type.+xcodebuild/i
|
if message.match /type.+xcodebuild/i
|
||||||
logErr 'Xcode Command Line Tools are required'
|
logErr 'Xcode Command Line Tools are required'
|
||||||
|
|
||||||
generateConfig = (name) ->
|
generateConfig = (interfaceName, projName) ->
|
||||||
log 'Creating Re-Natal config'
|
log 'Creating Re-Natal config'
|
||||||
config =
|
config =
|
||||||
name: name
|
name: projName
|
||||||
|
interface: interfaceName
|
||||||
androidHost: "localhost"
|
androidHost: "localhost"
|
||||||
modules: []
|
modules: []
|
||||||
imageDirs: ["images"]
|
imageDirs: ["images"]
|
||||||
|
@ -190,39 +196,37 @@ configureDevHostForAndroidDevice = (deviceType) ->
|
||||||
catch {message}
|
catch {message}
|
||||||
logErr message
|
logErr message
|
||||||
|
|
||||||
copyDevEnvironmentFiles = (projNameHyph, projName, devHost) ->
|
copyDevEnvironmentFiles = (interfaceName, projNameHyph, projName, devHost) ->
|
||||||
mkdirSync "env/dev"
|
fs.mkdirpSync "env/dev/env/ios"
|
||||||
mkdirSync "env/dev/env"
|
fs.mkdirpSync "env/dev/env/android"
|
||||||
mkdirSync "env/dev/env/ios"
|
|
||||||
mkdirSync "env/dev/env/android"
|
|
||||||
|
|
||||||
userNsPath = "env/dev/user.clj"
|
userNsPath = "env/dev/user.clj"
|
||||||
fs.copySync("#{resources}user.clj", userNsPath)
|
fs.copySync("#{resources}/user.clj", userNsPath)
|
||||||
|
|
||||||
mainIosDevPath = "env/dev/env/ios/main.cljs"
|
mainIosDevPath = "env/dev/env/ios/main.cljs"
|
||||||
mainAndroidDevPath = "env/dev/env/android/main.cljs"
|
mainAndroidDevPath = "env/dev/env/android/main.cljs"
|
||||||
|
|
||||||
fs.copySync("#{resources}cljs/main_dev.cljs", mainIosDevPath)
|
cljsDir = interfaceConf[interfaceName].cljsDir
|
||||||
|
fs.copySync("#{resources}/#{cljsDir}/main_dev.cljs", mainIosDevPath)
|
||||||
edit mainIosDevPath, [[projNameHyphRx, projNameHyph], [projNameRx, projName], [platformRx, "ios"], [devHostRx, devHost] ]
|
edit mainIosDevPath, [[projNameHyphRx, projNameHyph], [projNameRx, projName], [platformRx, "ios"], [devHostRx, devHost] ]
|
||||||
fs.copySync("#{resources}cljs/main_dev.cljs", mainAndroidDevPath)
|
fs.copySync("#{resources}/#{cljsDir}/main_dev.cljs", mainAndroidDevPath)
|
||||||
edit mainAndroidDevPath, [[projNameHyphRx, projNameHyph], [projNameRx, projName], [platformRx, "android"], [devHostRx, devHost]]
|
edit mainAndroidDevPath, [[projNameHyphRx, projNameHyph], [projNameRx, projName], [platformRx, "android"], [devHostRx, devHost]]
|
||||||
|
|
||||||
copyProdEnvironmentFiles = (projNameHyph, projName) ->
|
copyProdEnvironmentFiles = (interfaceName, projNameHyph, projName) ->
|
||||||
mkdirSync "env/prod"
|
fs.mkdirpSync "env/prod/env/ios"
|
||||||
mkdirSync "env/prod/env"
|
fs.mkdirpSync "env/prod/env/android"
|
||||||
mkdirSync "env/prod/env/ios"
|
|
||||||
mkdirSync "env/prod/env/android"
|
|
||||||
|
|
||||||
mainIosProdPath = "env/prod/env/ios/main.cljs"
|
mainIosProdPath = "env/prod/env/ios/main.cljs"
|
||||||
mainAndroidProdPath = "env/prod/env/android/main.cljs"
|
mainAndroidProdPath = "env/prod/env/android/main.cljs"
|
||||||
|
|
||||||
fs.copySync("#{resources}cljs/main_prod.cljs", mainIosProdPath)
|
cljsDir = interfaceConf[interfaceName].cljsDir
|
||||||
|
fs.copySync("#{resources}/#{cljsDir}/main_prod.cljs", mainIosProdPath)
|
||||||
edit mainIosProdPath, [[projNameHyphRx, projNameHyph], [projNameRx, projName], [platformRx, "ios"]]
|
edit mainIosProdPath, [[projNameHyphRx, projNameHyph], [projNameRx, projName], [platformRx, "ios"]]
|
||||||
fs.copySync("#{resources}cljs/main_prod.cljs", mainAndroidProdPath)
|
fs.copySync("#{resources}/#{cljsDir}/main_prod.cljs", mainAndroidProdPath)
|
||||||
edit mainAndroidProdPath, [[projNameHyphRx, projNameHyph], [projNameRx, projName], [platformRx, "android"]]
|
edit mainAndroidProdPath, [[projNameHyphRx, projNameHyph], [projNameRx, projName], [platformRx, "android"]]
|
||||||
|
|
||||||
copyFigwheelBridge = (projNameUs) ->
|
copyFigwheelBridge = (projNameUs) ->
|
||||||
fs.copySync("#{resources}figwheel-bridge.js", "./figwheel-bridge.js")
|
fs.copySync("#{resources}/figwheel-bridge.js", "./figwheel-bridge.js")
|
||||||
edit "figwheel-bridge.js", [[projNameUsRx, projNameUs]]
|
edit "figwheel-bridge.js", [[projNameUsRx, projNameUs]]
|
||||||
|
|
||||||
updateGitIgnore = () ->
|
updateGitIgnore = () ->
|
||||||
|
@ -235,7 +239,38 @@ patchReactNativePackager = () ->
|
||||||
edit "node_modules/react-native/packager/react-packager/src/Server/index.js",
|
edit "node_modules/react-native/packager/react-packager/src/Server/index.js",
|
||||||
[[/match.*\.map\$\/\)/m, "match(/index\\..*\\.map$/)"]]
|
[[/match.*\.map\$\/\)/m, "match(/index\\..*\\.map$/)"]]
|
||||||
|
|
||||||
init = (projName) ->
|
shimCljsNamespace = (ns) ->
|
||||||
|
filePath = "src/" + ns.replace(/\./g, "/") + ".cljs"
|
||||||
|
fs.mkdirpSync fpath.dirname(filePath)
|
||||||
|
fs.writeFileSync(filePath, "(ns #{ns})")
|
||||||
|
|
||||||
|
copySrcFiles = (interfaceName, projName, projNameUs, projNameHyph) ->
|
||||||
|
cljsDir = interfaceConf[interfaceName].cljsDir
|
||||||
|
fileNames = interfaceConf[interfaceName].sources.common;
|
||||||
|
for fileName in fileNames
|
||||||
|
path = "src/#{projNameUs}/#{fileName}"
|
||||||
|
fs.copySync("#{resources}/#{cljsDir}/#{fileName}", path)
|
||||||
|
edit path, [[projNameHyphRx, projNameHyph], [projNameRx, projName]]
|
||||||
|
|
||||||
|
platforms = ["ios", "android"]
|
||||||
|
for platform in platforms
|
||||||
|
fs.mkdirSync "src/#{projNameUs}/#{platform}"
|
||||||
|
fileNames = interfaceConf[interfaceName].sources[platform]
|
||||||
|
for fileName in fileNames
|
||||||
|
path = "src/#{projNameUs}/#{platform}/#{fileName}"
|
||||||
|
fs.copySync("#{resources}/#{cljsDir}/#{fileName}", path)
|
||||||
|
edit path, [[projNameHyphRx, projNameHyph], [projNameRx, projName], [platformRx, platform]]
|
||||||
|
|
||||||
|
shims = fileNames = interfaceConf[interfaceName].shims;
|
||||||
|
for namespace in shims
|
||||||
|
shimCljsNamespace(namespace)
|
||||||
|
|
||||||
|
copyProjectClj = (interfaceName, projNameHyph) ->
|
||||||
|
fs.copySync("#{resources}/project.clj", "project.clj")
|
||||||
|
deps = interfaceConf[interfaceName].deps.join("\n")
|
||||||
|
edit 'project.clj', [[projNameHyphRx, projNameHyph], [interfaceDepsRx, deps]]
|
||||||
|
|
||||||
|
init = (interfaceName, projName) ->
|
||||||
if projName.toLowerCase() is 'react' or !projName.match validNameRx
|
if projName.toLowerCase() is 'react' or !projName.match validNameRx
|
||||||
logErr 'Invalid project name. Use an alphanumeric CamelCase name.'
|
logErr 'Invalid project name. Use an alphanumeric CamelCase name.'
|
||||||
|
|
||||||
|
@ -256,50 +291,20 @@ init = (projName) ->
|
||||||
|
|
||||||
log 'Updating Leiningen project'
|
log 'Updating Leiningen project'
|
||||||
process.chdir projNameHyph
|
process.chdir projNameHyph
|
||||||
fs.copySync("#{resources}project.clj", "project.clj")
|
|
||||||
edit \
|
|
||||||
'project.clj',
|
|
||||||
[
|
|
||||||
[projNameHyphRx, projNameHyph]
|
|
||||||
]
|
|
||||||
|
|
||||||
fs.removeSync "resources"
|
fs.removeSync "resources"
|
||||||
|
|
||||||
corePath = "src/#{projNameUs}/core.clj"
|
corePath = "src/#{projNameUs}/core.clj"
|
||||||
fs.unlinkSync corePath
|
fs.unlinkSync corePath
|
||||||
|
|
||||||
handlersPath = "src/#{projNameUs}/handlers.cljs"
|
copyProjectClj(interfaceName, projNameHyph)
|
||||||
subsPath = "src/#{projNameUs}/subs.cljs"
|
|
||||||
dbPath = "src/#{projNameUs}/db.cljs"
|
|
||||||
fs.copySync("#{resources}cljs/handlers.cljs", handlersPath)
|
|
||||||
fs.copySync("#{resources}cljs/subs.cljs", subsPath)
|
|
||||||
fs.copySync("#{resources}cljs/db.cljs", dbPath)
|
|
||||||
|
|
||||||
edit handlersPath, [[projNameHyphRx, projNameHyph], [projNameRx, projName]]
|
copySrcFiles(interfaceName, projName, projNameUs, projNameHyph)
|
||||||
edit subsPath, [[projNameHyphRx, projNameHyph], [projNameRx, projName]]
|
|
||||||
edit dbPath, [[projNameHyphRx, projNameHyph], [projNameRx, projName]]
|
|
||||||
|
|
||||||
fs.mkdirSync 'src/cljsjs'
|
|
||||||
fs.writeFileSync("src/cljsjs/react.cljs", "(ns cljsjs.react)")
|
|
||||||
|
|
||||||
fs.mkdirSync "src/#{projNameUs}/android"
|
|
||||||
fs.mkdirSync "src/#{projNameUs}/ios"
|
|
||||||
|
|
||||||
coreAndroidPath = "src/#{projNameUs}/android/core.cljs"
|
|
||||||
coreIosPath = "src/#{projNameUs}/ios/core.cljs"
|
|
||||||
|
|
||||||
fs.copySync("#{resources}cljs/core.cljs", coreAndroidPath)
|
|
||||||
edit coreAndroidPath, [[projNameHyphRx, projNameHyph], [projNameRx, projName], [platformRx, "android"]]
|
|
||||||
|
|
||||||
fs.copySync("#{resources}cljs/core.cljs", coreIosPath)
|
|
||||||
edit coreIosPath, [[projNameHyphRx, projNameHyph], [projNameRx, projName], [platformRx, "ios"]]
|
|
||||||
|
|
||||||
fs.mkdirSync "env"
|
fs.mkdirSync "env"
|
||||||
|
|
||||||
copyDevEnvironmentFiles(projNameHyph, projName, "localhost")
|
copyDevEnvironmentFiles(interfaceName, projNameHyph, projName, "localhost")
|
||||||
copyProdEnvironmentFiles(projNameHyph, projName)
|
copyProdEnvironmentFiles(interfaceName, projNameHyph, projName)
|
||||||
|
|
||||||
fs.copySync("#{resources}images", "./images")
|
fs.copySync("#{resources}/images", "./images")
|
||||||
|
|
||||||
log 'Creating React Native skeleton. Relax, this takes a while...'
|
log 'Creating React Native skeleton. Relax, this takes a while...'
|
||||||
|
|
||||||
|
@ -320,11 +325,9 @@ init = (projName) ->
|
||||||
\"require('react-native/local-cli/cli').init('.', '#{projName}')\"
|
\"require('react-native/local-cli/cli').init('.', '#{projName}')\"
|
||||||
"
|
"
|
||||||
|
|
||||||
patchReactNativePackager();
|
|
||||||
|
|
||||||
updateGitIgnore()
|
updateGitIgnore()
|
||||||
|
|
||||||
generateConfig projName
|
generateConfig(interfaceName, projName)
|
||||||
|
|
||||||
copyFigwheelBridge(projNameUs)
|
copyFigwheelBridge(projNameUs)
|
||||||
|
|
||||||
|
@ -350,7 +353,7 @@ init = (projName) ->
|
||||||
log 'Changes you make via the REPL or by changing your .cljs files should appear live.', 'yellow'
|
log 'Changes you make via the REPL or by changing your .cljs files should appear live.', 'yellow'
|
||||||
log ''
|
log ''
|
||||||
log 'Try this command as an example:', 'yellow'
|
log 'Try this command as an example:', 'yellow'
|
||||||
log sampleCommand, 'inverse'
|
log interfaceConf[interfaceName].sampleCommand, 'inverse'
|
||||||
log ''
|
log ''
|
||||||
log '✔ Done', 'bgMagenta'
|
log '✔ Done', 'bgMagenta'
|
||||||
log ''
|
log ''
|
||||||
|
@ -425,12 +428,13 @@ generateDevScripts = () ->
|
||||||
message
|
message
|
||||||
|
|
||||||
doUpgrade = (config) ->
|
doUpgrade = (config) ->
|
||||||
|
interfaceName = config.interface;
|
||||||
projName = config.name;
|
projName = config.name;
|
||||||
projNameHyph = projName.replace(camelRx, '$1-$2').toLowerCase()
|
projNameHyph = projName.replace(camelRx, '$1-$2').toLowerCase()
|
||||||
projNameUs = toUnderscored projName
|
projNameUs = toUnderscored projName
|
||||||
|
|
||||||
copyDevEnvironmentFiles(projNameHyph, projName, "localhost")
|
copyDevEnvironmentFiles(interfaceName, projNameHyph, projName, "localhost")
|
||||||
copyProdEnvironmentFiles(projNameHyph, projName)
|
copyProdEnvironmentFiles(interfaceName, projNameHyph, projName)
|
||||||
log 'upgraded files in env/'
|
log 'upgraded files in env/'
|
||||||
|
|
||||||
copyFigwheelBridge(projNameUs)
|
copyFigwheelBridge(projNameUs)
|
||||||
|
@ -480,7 +484,7 @@ cli.command 'init <name>'
|
||||||
re-natal init HelloWorld
|
re-natal init HelloWorld
|
||||||
'''
|
'''
|
||||||
|
|
||||||
ensureFreePort -> init name
|
ensureFreePort -> init('reagent', name)
|
||||||
|
|
||||||
cli.command 'upgrade'
|
cli.command 'upgrade'
|
||||||
.description 'upgrades project files to current installed version of re-natal (the upgrade of re-natal itself is done via npm)'
|
.description 'upgrades project files to current installed version of re-natal (the upgrade of re-natal itself is done via npm)'
|
||||||
|
|
|
@ -5,9 +5,7 @@
|
||||||
:url "http://www.eclipse.org/legal/epl-v10.html"}
|
:url "http://www.eclipse.org/legal/epl-v10.html"}
|
||||||
:dependencies [[org.clojure/clojure "1.7.0"]
|
:dependencies [[org.clojure/clojure "1.7.0"]
|
||||||
[org.clojure/clojurescript "1.7.170"]
|
[org.clojure/clojurescript "1.7.170"]
|
||||||
[reagent "0.5.1" :exclusions [cljsjs/react]]
|
$INTERFACE_DEPS$]
|
||||||
[re-frame "0.6.0"]
|
|
||||||
[prismatic/schema "1.0.4"]]
|
|
||||||
:plugins [[lein-cljsbuild "1.1.1"]
|
:plugins [[lein-cljsbuild "1.1.1"]
|
||||||
[lein-figwheel "0.5.0-2"]]
|
[lein-figwheel "0.5.0-2"]]
|
||||||
:clean-targets ["target/" "index.ios.js" "index.android.js"]
|
:clean-targets ["target/" "index.ios.js" "index.android.js"]
|
||||||
|
|
Loading…
Reference in New Issue