Skip to content

Commit 4ec20a4

Browse files
authored
feat: shift tauri create [not wired up] (#1330)
* Partial revert "refactor(tauri.js): remove create command (#1265)" This reverts commit b29c068. * shift templates/recipes over * shift remaining files that weren't removed * add change file * rename to create-tauri-app * adjust covector config
1 parent b0c1009 commit 4ec20a4

37 files changed

Lines changed: 428 additions & 320 deletions

.changes/config.json

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

cli/create-tauri-app/package.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "create-tauri-app",
3+
"version": "0.0.0",
4+
"description": "Create Tauri App in seconds",
5+
"bin": {
6+
"create-tauri-app": "./bin/create-tauri-app.js"
7+
},
8+
"repository": {
9+
"type": "git",
10+
"url": "git+https://github.com/tauri-apps/tauri.git"
11+
},
12+
"license": "MIT",
13+
"bugs": {
14+
"url": "https://github.com/tauri-apps/tauri/issues"
15+
},
16+
"homepage": "https://github.com/tauri-apps/tauri#readme",
17+
"dependencies": {
18+
"minimist": "^1.2.5",
19+
"scaffe": "^0.1.5",
20+
"tauri": "^0.14.0"
21+
}
22+
}

cli/tauri.js/src/api/dependency-manager/npm-packages.ts renamed to cli/create-tauri-app/src/dependency-manager/npm-packages.ts

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,99 @@
1-
import { ManagementType, Result } from './types'
1+
import { ManagementType, Result } from "./types";
22
import {
33
getNpmLatestVersion,
44
getNpmPackageVersion,
55
installNpmPackage,
66
installNpmDevPackage,
77
updateNpmPackage,
8-
semverLt
9-
} from './util'
10-
import logger from '../../helpers/logger'
11-
import { resolve } from '../../helpers/app-paths'
12-
import inquirer from 'inquirer'
13-
import { existsSync } from 'fs'
14-
import { sync as crossSpawnSync } from 'cross-spawn'
8+
semverLt,
9+
} from "./util";
10+
import logger from "../../../tauri.js/src/helpers/logger";
11+
import { resolve } from "../../../tauri.js/src/helpers/app-paths";
12+
import inquirer from "inquirer";
13+
import { existsSync } from "fs";
14+
import { sync as crossSpawnSync } from "cross-spawn";
1515

16-
const log = logger('dependency:npm-packages')
16+
const log = logger("dependency:npm-packages");
1717

1818
async function manageDependencies(
1919
managementType: ManagementType,
2020
dependencies: string[]
2121
): Promise<Result> {
22-
const installedDeps = []
23-
const updatedDeps = []
22+
const installedDeps = [];
23+
const updatedDeps = [];
2424

25-
const npmChild = crossSpawnSync('npm', ['--version'])
26-
const yarnChild = crossSpawnSync('yarn', ['--version'])
25+
const npmChild = crossSpawnSync("npm", ["--version"]);
26+
const yarnChild = crossSpawnSync("yarn", ["--version"]);
2727
if (
2828
(npmChild.status ?? npmChild.error) &&
2929
(yarnChild.status ?? yarnChild.error)
3030
) {
3131
throw new Error(
32-
'must have `npm` or `yarn` installed to manage dependenices'
33-
)
32+
"must have `npm` or `yarn` installed to manage dependenices"
33+
);
3434
}
3535

36-
if (existsSync(resolve.app('package.json'))) {
36+
if (existsSync(resolve.app("package.json"))) {
3737
for (const dependency of dependencies) {
38-
const currentVersion = await getNpmPackageVersion(dependency)
38+
const currentVersion = await getNpmPackageVersion(dependency);
3939
if (currentVersion === null) {
40-
log(`Installing ${dependency}...`)
40+
log(`Installing ${dependency}...`);
4141
if (managementType === ManagementType.Install) {
42-
await installNpmPackage(dependency)
42+
await installNpmPackage(dependency);
4343
} else if (managementType === ManagementType.InstallDev) {
44-
await installNpmDevPackage(dependency)
44+
await installNpmDevPackage(dependency);
4545
}
46-
installedDeps.push(dependency)
46+
installedDeps.push(dependency);
4747
} else if (managementType === ManagementType.Update) {
48-
const latestVersion = await getNpmLatestVersion(dependency)
48+
const latestVersion = await getNpmLatestVersion(dependency);
4949
if (semverLt(currentVersion, latestVersion)) {
5050
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access
5151
const inquired = await inquirer.prompt([
5252
{
53-
type: 'confirm',
54-
name: 'answer',
53+
type: "confirm",
54+
name: "answer",
5555
message: `[NPM]: "${dependency}" latest version is ${latestVersion}. Do you want to update?`,
56-
default: false
57-
}
58-
])
56+
default: false,
57+
},
58+
]);
5959
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access
6060
if (inquired.answer) {
61-
log(`Updating ${dependency}...`)
62-
updateNpmPackage(dependency)
63-
updatedDeps.push(dependency)
61+
log(`Updating ${dependency}...`);
62+
updateNpmPackage(dependency);
63+
updatedDeps.push(dependency);
6464
}
6565
} else {
66-
log(`"${dependency}" is up to date`)
66+
log(`"${dependency}" is up to date`);
6767
}
6868
} else {
69-
log(`"${dependency}" is already installed`)
69+
log(`"${dependency}" is already installed`);
7070
}
7171
}
7272
}
7373

74-
const result: Result = new Map<ManagementType, string[]>()
75-
result.set(ManagementType.Install, installedDeps)
76-
result.set(ManagementType.Update, updatedDeps)
74+
const result: Result = new Map<ManagementType, string[]>();
75+
result.set(ManagementType.Install, installedDeps);
76+
result.set(ManagementType.Update, updatedDeps);
7777

78-
return result
78+
return result;
7979
}
8080

81-
const dependencies = ['tauri']
81+
const dependencies = ["tauri"];
8282

8383
async function install(): Promise<Result> {
84-
return await manageDependencies(ManagementType.Install, dependencies)
84+
return await manageDependencies(ManagementType.Install, dependencies);
8585
}
8686

8787
async function installThese(dependencies: string[]): Promise<Result> {
88-
return await manageDependencies(ManagementType.Install, dependencies)
88+
return await manageDependencies(ManagementType.Install, dependencies);
8989
}
9090

9191
async function installTheseDev(dependencies: string[]): Promise<Result> {
92-
return await manageDependencies(ManagementType.InstallDev, dependencies)
92+
return await manageDependencies(ManagementType.InstallDev, dependencies);
9393
}
9494

9595
async function update(): Promise<Result> {
96-
return await manageDependencies(ManagementType.Update, dependencies)
96+
return await manageDependencies(ManagementType.Update, dependencies);
9797
}
9898

99-
export { install, installThese, installTheseDev, update }
99+
export { install, installThese, installTheseDev, update };
File renamed without changes.

0 commit comments

Comments
 (0)