Skip to content

Commit

Permalink
feat: shift tauri create [not wired up] (#1330)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
jbolda authored Mar 7, 2021
1 parent b0c1009 commit 4ec20a4
Show file tree
Hide file tree
Showing 37 changed files with 428 additions and 320 deletions.
5 changes: 5 additions & 0 deletions .changes/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,11 @@
}
]
},
"create-tauri-app": {
"path": "./cli/create-tauri-app",
"manager": "javascript",
"dependencies": ["tauri.js"]
},
"tauri-utils": {
"path": "./tauri-utils",
"manager": "rust"
Expand Down
6 changes: 6 additions & 0 deletions .changes/revert-and-shift-tauri-create.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"create-tauri-app": minor
"tauri.js": patch
---

Revert `tauri create` deletion and shift remaining pieces that weren't deleted to `create-tauri-app`.
209 changes: 209 additions & 0 deletions cli/create-tauri-app/bin/create-tauri-app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
const parseArgs = require("minimist");
const inquirer = require("inquirer");
const { resolve } = require("path");
const { merge } = require("lodash");
const {
recipeShortNames,
recipeDescriptiveNames,
recipeByDescriptiveName,
recipeByShortName,
} = require("../../tauri.js/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("../../tauri.js/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("../../tauri.js/dist/api/dependency-manager");
await installDependencies();

if (recipe !== undefined) {
const {
installRecipeDependencies,
runRecipePostConfig,
} = require("../../tauri.js/dist/api/recipes/install");

await installRecipeDependencies(recipe, directory);
await runRecipePostConfig(recipe, directory);
}
}

module.exports = main;
22 changes: 22 additions & 0 deletions cli/create-tauri-app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "create-tauri-app",
"version": "0.0.0",
"description": "Create Tauri App in seconds",
"bin": {
"create-tauri-app": "./bin/create-tauri-app.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/tauri-apps/tauri.git"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/tauri-apps/tauri/issues"
},
"homepage": "https://github.com/tauri-apps/tauri#readme",
"dependencies": {
"minimist": "^1.2.5",
"scaffe": "^0.1.5",
"tauri": "^0.14.0"
}
}
Original file line number Diff line number Diff line change
@@ -1,99 +1,99 @@
import { ManagementType, Result } from './types'
import { ManagementType, Result } from "./types";
import {
getNpmLatestVersion,
getNpmPackageVersion,
installNpmPackage,
installNpmDevPackage,
updateNpmPackage,
semverLt
} from './util'
import logger from '../../helpers/logger'
import { resolve } from '../../helpers/app-paths'
import inquirer from 'inquirer'
import { existsSync } from 'fs'
import { sync as crossSpawnSync } from 'cross-spawn'
semverLt,
} from "./util";
import logger from "../../../tauri.js/src/helpers/logger";
import { resolve } from "../../../tauri.js/src/helpers/app-paths";
import inquirer from "inquirer";
import { existsSync } from "fs";
import { sync as crossSpawnSync } from "cross-spawn";

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

async function manageDependencies(
managementType: ManagementType,
dependencies: string[]
): Promise<Result> {
const installedDeps = []
const updatedDeps = []
const installedDeps = [];
const updatedDeps = [];

const npmChild = crossSpawnSync('npm', ['--version'])
const yarnChild = crossSpawnSync('yarn', ['--version'])
const npmChild = crossSpawnSync("npm", ["--version"]);
const yarnChild = crossSpawnSync("yarn", ["--version"]);
if (
(npmChild.status ?? npmChild.error) &&
(yarnChild.status ?? yarnChild.error)
) {
throw new Error(
'must have `npm` or `yarn` installed to manage dependenices'
)
"must have `npm` or `yarn` installed to manage dependenices"
);
}

if (existsSync(resolve.app('package.json'))) {
if (existsSync(resolve.app("package.json"))) {
for (const dependency of dependencies) {
const currentVersion = await getNpmPackageVersion(dependency)
const currentVersion = await getNpmPackageVersion(dependency);
if (currentVersion === null) {
log(`Installing ${dependency}...`)
log(`Installing ${dependency}...`);
if (managementType === ManagementType.Install) {
await installNpmPackage(dependency)
await installNpmPackage(dependency);
} else if (managementType === ManagementType.InstallDev) {
await installNpmDevPackage(dependency)
await installNpmDevPackage(dependency);
}
installedDeps.push(dependency)
installedDeps.push(dependency);
} else if (managementType === ManagementType.Update) {
const latestVersion = await getNpmLatestVersion(dependency)
const latestVersion = await getNpmLatestVersion(dependency);
if (semverLt(currentVersion, latestVersion)) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access
const inquired = await inquirer.prompt([
{
type: 'confirm',
name: 'answer',
type: "confirm",
name: "answer",
message: `[NPM]: "${dependency}" latest version is ${latestVersion}. Do you want to update?`,
default: false
}
])
default: false,
},
]);
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access
if (inquired.answer) {
log(`Updating ${dependency}...`)
updateNpmPackage(dependency)
updatedDeps.push(dependency)
log(`Updating ${dependency}...`);
updateNpmPackage(dependency);
updatedDeps.push(dependency);
}
} else {
log(`"${dependency}" is up to date`)
log(`"${dependency}" is up to date`);
}
} else {
log(`"${dependency}" is already installed`)
log(`"${dependency}" is already installed`);
}
}
}

const result: Result = new Map<ManagementType, string[]>()
result.set(ManagementType.Install, installedDeps)
result.set(ManagementType.Update, updatedDeps)
const result: Result = new Map<ManagementType, string[]>();
result.set(ManagementType.Install, installedDeps);
result.set(ManagementType.Update, updatedDeps);

return result
return result;
}

const dependencies = ['tauri']
const dependencies = ["tauri"];

async function install(): Promise<Result> {
return await manageDependencies(ManagementType.Install, dependencies)
return await manageDependencies(ManagementType.Install, dependencies);
}

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

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

async function update(): Promise<Result> {
return await manageDependencies(ManagementType.Update, dependencies)
return await manageDependencies(ManagementType.Update, dependencies);
}

export { install, installThese, installTheseDev, update }
export { install, installThese, installTheseDev, update };
Loading

0 comments on commit 4ec20a4

Please sign in to comment.