tauri-create.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. const parseArgs = require('minimist')
  2. const inquirer = require('inquirer')
  3. const { resolve } = require('path')
  4. const { merge } = require('lodash')
  5. const {
  6. recipeShortNames,
  7. recipeDescriptiveNames,
  8. recipeByDescriptiveName,
  9. recipeByShortName
  10. } = require('../dist/api/recipes')
  11. /**
  12. * @type {object}
  13. * @property {boolean} h
  14. * @property {boolean} help
  15. * @property {string|boolean} f
  16. * @property {string|boolean} force
  17. * @property {boolean} l
  18. * @property {boolean} log
  19. * @property {boolean} d
  20. * @property {boolean} directory
  21. * @property {string} r
  22. * @property {string} recipe
  23. */
  24. function main(cliArgs) {
  25. const argv = parseArgs(cliArgs, {
  26. alias: {
  27. h: 'help',
  28. f: 'force',
  29. l: 'log',
  30. d: 'directory',
  31. t: 'tauri-path',
  32. A: 'app-name',
  33. W: 'window-title',
  34. D: 'dist-dir',
  35. P: 'dev-path',
  36. r: 'recipe'
  37. },
  38. boolean: ['h', 'l', 'ci']
  39. })
  40. if (argv.help) {
  41. printUsage()
  42. return 0
  43. }
  44. if (argv.ci) {
  45. runInit(argv)
  46. } else {
  47. getOptionsInteractive(argv).then((responses) => runInit(argv, responses))
  48. }
  49. }
  50. function printUsage() {
  51. console.log(`
  52. Description
  53. Inits the Tauri template. If Tauri cannot find the tauri.conf.json
  54. it will create one.
  55. Usage
  56. $ tauri create
  57. Options
  58. --help, -h Displays this message
  59. --ci Skip prompts
  60. --force, -f Force init to overwrite [conf|template|all]
  61. --log, -l Logging [boolean]
  62. --directory, -d Set target directory for init
  63. --tauri-path, -t Path of the Tauri project to use (relative to the cwd)
  64. --app-name, -A Name of your Tauri application
  65. --window-title, -W Window title of your Tauri application
  66. --dist-dir, -D Web assets location, relative to <project-dir>/src-tauri
  67. --dev-path, -P Url of your dev server
  68. --recipe, -r Add UI framework recipe. None by default.
  69. Supported recipes: [${recipeShortNames.join('|')}]
  70. `)
  71. }
  72. const getOptionsInteractive = (argv) => {
  73. let defaultAppName = argv.A
  74. if (!defaultAppName) {
  75. try {
  76. const packageJson = JSON.parse(
  77. readFileSync(resolve(process.cwd(), 'package.json')).toString()
  78. )
  79. defaultAppName = packageJson.displayName || packageJson.name
  80. } catch {}
  81. }
  82. return inquirer
  83. .prompt([
  84. {
  85. type: 'input',
  86. name: 'appName',
  87. message: 'What is your app name?',
  88. default: defaultAppName,
  89. when: !argv.A
  90. },
  91. {
  92. type: 'input',
  93. name: 'tauri.window.title',
  94. message: 'What should the window title be?',
  95. default: 'Tauri App',
  96. when: () => !argv.W
  97. },
  98. {
  99. type: 'list',
  100. name: 'recipeName',
  101. message: 'Would you like to add a UI recipe?',
  102. choices: recipeDescriptiveNames,
  103. default: 'No recipe',
  104. when: () => !argv.r
  105. }
  106. ])
  107. .then((answers) =>
  108. inquirer
  109. .prompt([
  110. {
  111. type: 'input',
  112. name: 'build.devPath',
  113. message: 'What is the url of your dev server?',
  114. default: 'http://localhost:4000',
  115. when: () =>
  116. (!argv.P && !argv.p && answers.recipeName === 'No recipe') ||
  117. argv.r === 'none'
  118. },
  119. {
  120. type: 'input',
  121. name: 'build.distDir',
  122. message:
  123. 'Where are your web assets (HTML/CSS/JS) located, relative to the "<current dir>/src-tauri" folder that will be created?',
  124. default: '../dist',
  125. when: () =>
  126. (!argv.D && answers.recipeName === 'No recipe') ||
  127. argv.r === 'none'
  128. }
  129. ])
  130. .then((answers2) => ({ ...answers, ...answers2 }))
  131. )
  132. .catch((error) => {
  133. if (error.isTtyError) {
  134. // Prompt couldn't be rendered in the current environment
  135. console.log(
  136. 'It appears your terminal does not support interactive prompts. Using default values.'
  137. )
  138. runInit()
  139. } else {
  140. // Something else when wrong
  141. console.error('An unknown error occurred:', error)
  142. }
  143. })
  144. }
  145. async function runInit(argv, config = {}) {
  146. const { appName, recipeName, ...configOptions } = config
  147. const init = require('../dist/api/init')
  148. let recipe
  149. let recipeSelection = 'none'
  150. if (recipeName !== undefined) {
  151. recipe = recipeByDescriptiveName(recipeName)
  152. } else if (argv.r) {
  153. recipe = recipeByShortName(argv.r)
  154. }
  155. let buildConfig = {
  156. distDir: argv.D,
  157. devPath: argv.P
  158. }
  159. if (recipe !== undefined) {
  160. recipeSelection = recipe.shortName
  161. buildConfig = recipe.configUpdate(buildConfig)
  162. }
  163. const directory = argv.d || process.cwd()
  164. init({
  165. directory,
  166. force: argv.f || null,
  167. logging: argv.l || null,
  168. tauriPath: argv.t || null,
  169. appName: appName || argv.A || null,
  170. customConfig: merge(configOptions, {
  171. build: buildConfig,
  172. tauri: {
  173. window: {
  174. title: argv.W
  175. }
  176. }
  177. })
  178. })
  179. const { installDependencies } = require('../dist/api/dependency-manager')
  180. await installDependencies()
  181. if (recipe !== undefined) {
  182. const {
  183. installRecipeDependencies,
  184. runRecipePostConfig
  185. } = require('../dist/api/recipes/install')
  186. await installRecipeDependencies(recipe, directory)
  187. await runRecipePostConfig(recipe, directory)
  188. }
  189. }
  190. module.exports = main