mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-01 10:01:07 +02:00
refactor(tauri.js): remove create command (#1265)
also fixes window title not setting properly because window config is an array
This commit is contained in:
@@ -1,207 +0,0 @@
|
||||
const parseArgs = require('minimist')
|
||||
const inquirer = require('inquirer')
|
||||
const { resolve } = require('path')
|
||||
const { merge } = require('lodash')
|
||||
const {
|
||||
recipeShortNames,
|
||||
recipeDescriptiveNames,
|
||||
recipeByDescriptiveName,
|
||||
recipeByShortName
|
||||
} = require('../dist/api/recipes')
|
||||
|
||||
/**
|
||||
* @type {object}
|
||||
* @property {boolean} h
|
||||
* @property {boolean} help
|
||||
* @property {string|boolean} f
|
||||
* @property {string|boolean} force
|
||||
* @property {boolean} l
|
||||
* @property {boolean} log
|
||||
* @property {boolean} d
|
||||
* @property {boolean} directory
|
||||
* @property {string} r
|
||||
* @property {string} recipe
|
||||
*/
|
||||
function main(cliArgs) {
|
||||
const argv = parseArgs(cliArgs, {
|
||||
alias: {
|
||||
h: 'help',
|
||||
f: 'force',
|
||||
l: 'log',
|
||||
d: 'directory',
|
||||
t: 'tauri-path',
|
||||
A: 'app-name',
|
||||
W: 'window-title',
|
||||
D: 'dist-dir',
|
||||
P: 'dev-path',
|
||||
r: 'recipe'
|
||||
},
|
||||
boolean: ['h', 'l', 'ci']
|
||||
})
|
||||
|
||||
if (argv.help) {
|
||||
printUsage()
|
||||
return 0
|
||||
}
|
||||
|
||||
if (argv.ci) {
|
||||
runInit(argv)
|
||||
} else {
|
||||
getOptionsInteractive(argv).then((responses) => runInit(argv, responses))
|
||||
}
|
||||
}
|
||||
|
||||
function printUsage() {
|
||||
console.log(`
|
||||
Description
|
||||
Inits the Tauri template. If Tauri cannot find the tauri.conf.json
|
||||
it will create one.
|
||||
Usage
|
||||
$ tauri create
|
||||
Options
|
||||
--help, -h Displays this message
|
||||
--ci Skip prompts
|
||||
--force, -f Force init to overwrite [conf|template|all]
|
||||
--log, -l Logging [boolean]
|
||||
--directory, -d Set target directory for init
|
||||
--tauri-path, -t Path of the Tauri project to use (relative to the cwd)
|
||||
--app-name, -A Name of your Tauri application
|
||||
--window-title, -W Window title of your Tauri application
|
||||
--dist-dir, -D Web assets location, relative to <project-dir>/src-tauri
|
||||
--dev-path, -P Url of your dev server
|
||||
--recipe, -r Add UI framework recipe. None by default.
|
||||
Supported recipes: [${recipeShortNames.join('|')}]
|
||||
`)
|
||||
}
|
||||
|
||||
const getOptionsInteractive = (argv) => {
|
||||
let defaultAppName = argv.A
|
||||
if (!defaultAppName) {
|
||||
try {
|
||||
const packageJson = JSON.parse(
|
||||
readFileSync(resolve(process.cwd(), 'package.json')).toString()
|
||||
)
|
||||
defaultAppName = packageJson.displayName || packageJson.name
|
||||
} catch {}
|
||||
}
|
||||
|
||||
return inquirer
|
||||
.prompt([
|
||||
{
|
||||
type: 'input',
|
||||
name: 'appName',
|
||||
message: 'What is your app name?',
|
||||
default: defaultAppName,
|
||||
when: !argv.A
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
name: 'tauri.window.title',
|
||||
message: 'What should the window title be?',
|
||||
default: 'Tauri App',
|
||||
when: () => !argv.W
|
||||
},
|
||||
{
|
||||
type: 'list',
|
||||
name: 'recipeName',
|
||||
message: 'Would you like to add a UI recipe?',
|
||||
choices: recipeDescriptiveNames,
|
||||
default: 'No recipe',
|
||||
when: () => !argv.r
|
||||
}
|
||||
])
|
||||
.then((answers) =>
|
||||
inquirer
|
||||
.prompt([
|
||||
{
|
||||
type: 'input',
|
||||
name: 'build.devPath',
|
||||
message: 'What is the url of your dev server?',
|
||||
default: 'http://localhost:4000',
|
||||
when: () =>
|
||||
(!argv.P && !argv.p && answers.recipeName === 'No recipe') ||
|
||||
argv.r === 'none'
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
name: 'build.distDir',
|
||||
message:
|
||||
'Where are your web assets (HTML/CSS/JS) located, relative to the "<current dir>/src-tauri" folder that will be created?',
|
||||
default: '../dist',
|
||||
when: () =>
|
||||
(!argv.D && answers.recipeName === 'No recipe') ||
|
||||
argv.r === 'none'
|
||||
}
|
||||
])
|
||||
.then((answers2) => ({ ...answers, ...answers2 }))
|
||||
)
|
||||
.catch((error) => {
|
||||
if (error.isTtyError) {
|
||||
// Prompt couldn't be rendered in the current environment
|
||||
console.log(
|
||||
'It appears your terminal does not support interactive prompts. Using default values.'
|
||||
)
|
||||
runInit()
|
||||
} else {
|
||||
// Something else when wrong
|
||||
console.error('An unknown error occurred:', error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async function runInit(argv, config = {}) {
|
||||
const { appName, recipeName, ...configOptions } = config
|
||||
const init = require('../dist/api/init')
|
||||
|
||||
let recipe
|
||||
let recipeSelection = 'none'
|
||||
|
||||
if (recipeName !== undefined) {
|
||||
recipe = recipeByDescriptiveName(recipeName)
|
||||
} else if (argv.r) {
|
||||
recipe = recipeByShortName(argv.r)
|
||||
}
|
||||
|
||||
let buildConfig = {
|
||||
distDir: argv.D,
|
||||
devPath: argv.P
|
||||
}
|
||||
|
||||
if (recipe !== undefined) {
|
||||
recipeSelection = recipe.shortName
|
||||
buildConfig = recipe.configUpdate(buildConfig)
|
||||
}
|
||||
|
||||
const directory = argv.d || process.cwd()
|
||||
|
||||
init({
|
||||
directory,
|
||||
force: argv.f || null,
|
||||
logging: argv.l || null,
|
||||
tauriPath: argv.t || null,
|
||||
appName: appName || argv.A || null,
|
||||
customConfig: merge(configOptions, {
|
||||
build: buildConfig,
|
||||
tauri: {
|
||||
window: {
|
||||
title: argv.W
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const { installDependencies } = require('../dist/api/dependency-manager')
|
||||
await installDependencies()
|
||||
|
||||
if (recipe !== undefined) {
|
||||
const {
|
||||
installRecipeDependencies,
|
||||
runRecipePostConfig
|
||||
} = require('../dist/api/recipes/install')
|
||||
|
||||
await installRecipeDependencies(recipe, directory)
|
||||
await runRecipePostConfig(recipe, directory)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = main
|
||||
@@ -1,9 +1,10 @@
|
||||
const parseArgs = require('minimist')
|
||||
const tauriCreate = require('./tauri-create')
|
||||
const inquirer = require('inquirer')
|
||||
const { resolve } = require('path')
|
||||
const { merge } = require('lodash')
|
||||
|
||||
/**
|
||||
* init is an alias for create -r none, same as
|
||||
* creating a fresh tauri project with no UI recipe applied.
|
||||
* init creates the src-tauri folder
|
||||
*
|
||||
* @type {object}
|
||||
* @property {boolean} h
|
||||
@@ -18,9 +19,15 @@ const tauriCreate = require('./tauri-create')
|
||||
function main(cliArgs) {
|
||||
const argv = parseArgs(cliArgs, {
|
||||
alias: {
|
||||
h: 'help'
|
||||
h: 'help',
|
||||
f: 'force',
|
||||
l: 'log',
|
||||
A: 'app-name',
|
||||
W: 'window-title',
|
||||
D: 'dist-dir',
|
||||
P: 'dev-path'
|
||||
},
|
||||
boolean: ['h']
|
||||
boolean: ['h', 'l', 'ci']
|
||||
})
|
||||
|
||||
if (argv.help) {
|
||||
@@ -28,8 +35,11 @@ function main(cliArgs) {
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
// delegate actual work to create command
|
||||
tauriCreate([...cliArgs, '-r', 'none'])
|
||||
if (argv.ci) {
|
||||
runInit(argv)
|
||||
} else {
|
||||
getOptionsInteractive(argv).then((responses) => runInit(argv, responses))
|
||||
}
|
||||
}
|
||||
|
||||
function printUsage() {
|
||||
@@ -41,16 +51,107 @@ function printUsage() {
|
||||
$ tauri init
|
||||
Options
|
||||
--help, -h Displays this message
|
||||
--app-name, -a Name of your Tauri application
|
||||
--window-title, -w Window title of your Tauri application
|
||||
--dist-dir, -d Web assets location, relative to <project-dir>/src-tauri
|
||||
--dev-path, -p Url of your dev server
|
||||
--ci Skip prompts
|
||||
--force, -f Force init to overwrite [conf|template|all]
|
||||
--log, -l Logging [boolean]
|
||||
--directory, -d Set target directory for init
|
||||
--tauri-path, -t Path of the Tauri project to use (relative to the cwd)
|
||||
--app-name, -A Name of your Tauri application
|
||||
--window-title, -W Window title of your Tauri application
|
||||
--dist-dir, -D Web assets location, relative to <project-dir>/src-tauri
|
||||
--dev-path, -P Url of your dev server
|
||||
--directory, -D Set target directory for init
|
||||
`)
|
||||
}
|
||||
|
||||
const getOptionsInteractive = (argv) => {
|
||||
let defaultAppName = argv.a
|
||||
if (!defaultAppName) {
|
||||
try {
|
||||
const packageJson = JSON.parse(
|
||||
readFileSync(resolve(process.cwd(), 'package.json')).toString()
|
||||
)
|
||||
defaultAppName = packageJson.displayName || packageJson.name
|
||||
} catch {}
|
||||
}
|
||||
|
||||
return inquirer
|
||||
.prompt([
|
||||
{
|
||||
type: 'input',
|
||||
name: 'appName',
|
||||
message: 'What is your app name?',
|
||||
default: defaultAppName,
|
||||
when: !argv.a
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
name: 'windowTitle',
|
||||
message: 'What should the window title be?',
|
||||
default: 'Tauri App',
|
||||
when: () => !argv.w
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
name: 'build.devPath',
|
||||
message: 'What is the url of your dev server?',
|
||||
default: 'http://localhost:4000',
|
||||
when: () => !argv.p
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
name: 'build.distDir',
|
||||
message:
|
||||
'Where are your web assets (HTML/CSS/JS) located, relative to the "<current dir>/src-tauri" folder that will be created?',
|
||||
default: '../dist',
|
||||
when: () => !argv.d
|
||||
}
|
||||
])
|
||||
.then((answers) => answers)
|
||||
.catch((error) => {
|
||||
if (error.isTtyError) {
|
||||
// Prompt couldn't be rendered in the current environment
|
||||
console.log(
|
||||
'It appears your terminal does not support interactive prompts. Using default values.'
|
||||
)
|
||||
runInit()
|
||||
} else {
|
||||
// Something else when wrong
|
||||
console.error('An unknown error occurred:', error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async function runInit(argv, config = {}) {
|
||||
const { appName, windowTitle, ...configOptions } = config
|
||||
const init = require('../dist/api/init')
|
||||
|
||||
let buildConfig = {
|
||||
distDir: argv.d,
|
||||
devPath: argv.p
|
||||
}
|
||||
|
||||
const directory = argv.D || process.cwd()
|
||||
|
||||
init({
|
||||
directory,
|
||||
force: argv.f || null,
|
||||
logging: argv.l || null,
|
||||
tauriPath: argv.t || null,
|
||||
appName: appName || argv.a || null,
|
||||
customConfig: merge(configOptions, {
|
||||
build: buildConfig,
|
||||
tauri: {
|
||||
windows: [
|
||||
{
|
||||
title: windowTitle || argv.w
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const { installDependencies } = require('../dist/api/dependency-manager')
|
||||
await installDependencies()
|
||||
}
|
||||
|
||||
module.exports = main
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const cmds = ['create', 'init', 'help', 'icon', 'info', 'deps']
|
||||
const cmds = ['init', 'help', 'icon', 'info', 'deps']
|
||||
const rustCliCmds = ['dev', 'build']
|
||||
|
||||
const cmd = process.argv[2]
|
||||
@@ -57,7 +57,7 @@ const tauri = function (command) {
|
||||
}
|
||||
console.log(`[tauri]: running ${command}`)
|
||||
// eslint-disable-next-line security/detect-non-literal-require
|
||||
if (['create', 'init'].includes(command)) {
|
||||
if (['init'].includes(command)) {
|
||||
require(`./tauri-${command}`)(process.argv.slice(2))
|
||||
} else {
|
||||
require(`./tauri-${command}`)
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
import { map, identity, find } from 'lodash'
|
||||
import { TauriBuildConfig } from '../../types/config'
|
||||
import { reactjs, reactts } from './react'
|
||||
|
||||
export interface Recipe {
|
||||
descriptiveName: string
|
||||
shortName: string
|
||||
configUpdate: (cfg: TauriBuildConfig) => TauriBuildConfig
|
||||
extraNpmDependencies: string[]
|
||||
extraNpmDevDependencies: string[]
|
||||
postConfiguration: (cwd: string) => void
|
||||
}
|
||||
|
||||
const none = {
|
||||
descriptiveName: 'No recipe',
|
||||
shortName: 'none',
|
||||
configUpdate: identity,
|
||||
extraNpmDependencies: [],
|
||||
extraNpmDevDependencies: [],
|
||||
postConfiguration: (cwd: string) => {}
|
||||
}
|
||||
|
||||
export const allRecipes: Recipe[] = [none, reactjs, reactts]
|
||||
|
||||
export const recipeNames: Array<[string, string]> = map(
|
||||
allRecipes,
|
||||
(r: Recipe) => [r.shortName, r.descriptiveName]
|
||||
)
|
||||
|
||||
export const recipeByShortName = (name: string): Recipe | undefined =>
|
||||
find(allRecipes, (r: Recipe) => r.shortName === name)
|
||||
|
||||
export const recipeByDescriptiveName = (name: string): Recipe | undefined =>
|
||||
find(allRecipes, (r: Recipe) => r.descriptiveName === name)
|
||||
|
||||
export const recipeShortNames: string[] = map(
|
||||
allRecipes,
|
||||
(r: Recipe) => r.shortName
|
||||
)
|
||||
|
||||
export const recipeDescriptiveNames: string[] = map(
|
||||
allRecipes,
|
||||
(r: Recipe) => r.descriptiveName
|
||||
)
|
||||
@@ -1,35 +0,0 @@
|
||||
import {
|
||||
installThese,
|
||||
installTheseDev
|
||||
} from '../dependency-manager/npm-packages'
|
||||
import { Recipe } from '.'
|
||||
import { Result } from '../dependency-manager/types'
|
||||
import logger from '../../helpers/logger'
|
||||
|
||||
export async function installRecipeDependencies(
|
||||
recipe: Recipe
|
||||
): Promise<Result> {
|
||||
const log = logger('recipe:install')
|
||||
|
||||
log(`Installing dependencies for ${recipe.descriptiveName}`)
|
||||
return await installThese(recipe.extraNpmDependencies).then(
|
||||
async (results) =>
|
||||
await installTheseDev(recipe.extraNpmDevDependencies).then(
|
||||
(results2) =>
|
||||
new Map([
|
||||
...Array.from(results.entries()),
|
||||
...Array.from(results2.entries())
|
||||
])
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
export async function runRecipePostConfig(
|
||||
recipe: Recipe,
|
||||
cwd: string
|
||||
): Promise<void> {
|
||||
const log = logger('recipe:postconfig')
|
||||
|
||||
log(`Running post configuration for ${recipe.descriptiveName}`)
|
||||
return await new Promise(() => recipe.postConfiguration(cwd))
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
import { Recipe } from '.'
|
||||
import { TauriBuildConfig } from '../../types/config'
|
||||
import { spawnSync } from '../../helpers/spawn'
|
||||
import logger from '../../helpers/logger'
|
||||
import copyTemplates from '../../helpers/copy-templates'
|
||||
import { resolve, join } from 'path'
|
||||
|
||||
const uiAppDir = 'app-ui'
|
||||
|
||||
const log = logger('react-recipe')
|
||||
|
||||
const completeLogMsg = `
|
||||
Your installation completed.
|
||||
To start, run yarn tauri dev
|
||||
`
|
||||
|
||||
const afterCra = (): void => {
|
||||
copyTemplates({
|
||||
source: resolve(__dirname, '../../templates/recipes/react/'),
|
||||
scope: {},
|
||||
target: join(uiAppDir, './src/')
|
||||
})
|
||||
log(completeLogMsg)
|
||||
}
|
||||
|
||||
const reactjs: Recipe = {
|
||||
descriptiveName: 'React.js',
|
||||
shortName: 'reactjs',
|
||||
configUpdate: (cfg: TauriBuildConfig): TauriBuildConfig => ({
|
||||
...cfg,
|
||||
distDir: `../${uiAppDir}/build`,
|
||||
devPath: 'http://localhost:3000',
|
||||
beforeDevCommand: `yarn --cwd ${uiAppDir} start`,
|
||||
beforeBuildCommand: `yarn --cwd ${uiAppDir} build`
|
||||
}),
|
||||
extraNpmDevDependencies: ['create-react-app'],
|
||||
extraNpmDependencies: ['react'],
|
||||
postConfiguration: (cwd: string) => {
|
||||
spawnSync('yarn', ['create-react-app', uiAppDir], cwd)
|
||||
afterCra()
|
||||
}
|
||||
}
|
||||
|
||||
const reactts: Recipe = {
|
||||
...reactjs,
|
||||
descriptiveName: 'React with Typescript',
|
||||
shortName: 'reactts',
|
||||
extraNpmDependencies: [
|
||||
'typescript',
|
||||
'@types/node',
|
||||
'@types/react',
|
||||
'@types/react-dom',
|
||||
'@types/jest'
|
||||
],
|
||||
postConfiguration: (cwd: string) => {
|
||||
spawnSync(
|
||||
'yarn',
|
||||
['create-react-app', '--template', 'typescript', uiAppDir],
|
||||
cwd
|
||||
)
|
||||
afterCra()
|
||||
}
|
||||
}
|
||||
|
||||
export { reactjs, reactts }
|
||||
@@ -44,6 +44,18 @@ const injectConfFile = (
|
||||
}
|
||||
/* eslint-enable security/detect-object-injection */
|
||||
})
|
||||
// Window config should be merged
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
if ((customConfig as UnknownObject).tauri?.windows[0]) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
|
||||
;(customConfig as UnknownObject).tauri.windows[0] = {
|
||||
...defaultConfig.tauri.windows[0],
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
...(customConfig as UnknownObject).tauri.windows[0]
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
delete (defaultConfig as UnknownObject).tauri.windows
|
||||
}
|
||||
const finalConf = merge(
|
||||
defaultConfig as any,
|
||||
customConfig as any
|
||||
|
||||
@@ -5,8 +5,6 @@ module.exports = {
|
||||
entry: {
|
||||
'api/cli': './src/api/cli.ts',
|
||||
'api/init': './src/api/init.ts',
|
||||
'api/recipes': './src/api/recipes/index.ts',
|
||||
'api/recipes/install': './src/api/recipes/install.ts',
|
||||
'api/tauricon': './src/api/tauricon.ts',
|
||||
'api/info': './src/api/info.ts',
|
||||
'api/dependency-manager': './src/api/dependency-manager/index.ts',
|
||||
|
||||
Reference in New Issue
Block a user