🎨 CLI is more user-friendly.
This commit is contained in:
8
bin/README.md
vendored
8
bin/README.md
vendored
@@ -107,14 +107,6 @@ Determine whether the application launches in full screen. Default is `false`. U
|
||||
--fullscreen
|
||||
```
|
||||
|
||||
#### [resize]
|
||||
|
||||
Determine whether the window is resizable. Default is `true`. Use the following command to disable window resizing.
|
||||
|
||||
```shell
|
||||
--resizable
|
||||
```
|
||||
|
||||
#### [multi-arch]
|
||||
|
||||
Package the application to support both Intel and M1 chips, exclusively for macOS. Default is `false`.
|
||||
|
||||
8
bin/README_CN.md
vendored
8
bin/README_CN.md
vendored
@@ -101,14 +101,6 @@ pake [url] [options]
|
||||
--transparent
|
||||
```
|
||||
|
||||
#### [resize]
|
||||
|
||||
设置应用窗口是否可以调整大小,默认为 `true`(可调整)。使用以下命令可以禁止调整窗口大小。
|
||||
|
||||
```shell
|
||||
--resizable
|
||||
```
|
||||
|
||||
#### [fullscreen]
|
||||
|
||||
设置应用程序是否在启动时自动全屏,默认为 `false`。使用以下命令可以设置应用程序启动时自动全屏。
|
||||
|
||||
64
bin/builders/BaseBuilder.ts
vendored
64
bin/builders/BaseBuilder.ts
vendored
@@ -2,20 +2,25 @@ import path from 'path';
|
||||
import fsExtra from "fs-extra";
|
||||
import prompts from 'prompts';
|
||||
|
||||
import logger from '@/options/logger';
|
||||
import { PakeAppOptions } from '@/types';
|
||||
import { checkRustInstalled, installRust } from '@/helpers/rust';
|
||||
import { mergeConfig } from "@/helpers/merge";
|
||||
import tauriConfig from '@/helpers/tauriConfig';
|
||||
import { npmDirectory } from '@/utils/dir';
|
||||
import { getSpinner } from "@/utils/info";
|
||||
import { shellExec } from '@/utils/shell';
|
||||
import { isChinaDomain } from '@/utils/ip';
|
||||
import { getSpinner } from "@/utils/info";
|
||||
import { npmDirectory } from '@/utils/dir';
|
||||
import { IS_MAC } from "@/utils/platform";
|
||||
import { checkRustInstalled, installRust } from '@/helpers/rust';
|
||||
import { PakeAppOptions } from '@/types';
|
||||
import logger from '@/options/logger';
|
||||
|
||||
export default abstract class BaseBuilder {
|
||||
abstract build(url: string, options: PakeAppOptions): Promise<void>;
|
||||
protected options: PakeAppOptions;
|
||||
|
||||
protected constructor(options: PakeAppOptions) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
async prepare() {
|
||||
// Windows and Linux need to install necessary build tools.
|
||||
if (!IS_MAC) {
|
||||
logger.info('The first use requires installing system dependencies.');
|
||||
logger.info('See more in https://tauri.app/v1/guides/getting-started/prerequisites#installing.');
|
||||
@@ -52,9 +57,50 @@ export default abstract class BaseBuilder {
|
||||
spinner.succeed('Package installed.');
|
||||
}
|
||||
|
||||
protected async runBuildCommand(command: string = "npm run build") {
|
||||
async buildAndCopy(url: string) {
|
||||
const { name } = this.options;
|
||||
await mergeConfig(url, this.options, tauriConfig);
|
||||
await this.runBuildCommand();
|
||||
|
||||
const fileName = this.getFileName();
|
||||
const appPath = this.getBuildAppPath(npmDirectory, fileName);
|
||||
const distPath = path.resolve(`${name}.${this.getExtension()}`);
|
||||
await fsExtra.copy(appPath, distPath);
|
||||
await fsExtra.remove(appPath);
|
||||
logger.success('✔ Build success!');
|
||||
logger.success('✔ App installer located in', distPath);
|
||||
}
|
||||
|
||||
abstract build(url: string): Promise<void>;
|
||||
|
||||
abstract getFileName(): string;
|
||||
|
||||
abstract getExtension(): string;
|
||||
|
||||
protected getArch() {
|
||||
return process.arch === "x64" ? "amd64" : process.arch;
|
||||
}
|
||||
|
||||
protected getBuildCommand(): string {
|
||||
return "npm run build";
|
||||
}
|
||||
|
||||
protected runBuildCommand() {
|
||||
const spinner = getSpinner('Building app...');
|
||||
setTimeout(() => spinner.stop(), 3000);
|
||||
await shellExec(`cd "${npmDirectory}" && ${command}`);
|
||||
return shellExec(`cd ${npmDirectory} && ${this.getBuildCommand()}`);
|
||||
}
|
||||
|
||||
protected getBasePath(): string {
|
||||
return 'src-tauri/target/release/bundle/';
|
||||
}
|
||||
|
||||
protected getBuildAppPath(npmDirectory: string, fileName: string): string {
|
||||
return path.join(
|
||||
npmDirectory,
|
||||
this.getBasePath(),
|
||||
this.getExtension().toLowerCase(),
|
||||
`${fileName}.${this.getExtension()}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
7
bin/builders/BuilderProvider.ts
vendored
7
bin/builders/BuilderProvider.ts
vendored
@@ -2,21 +2,22 @@ import BaseBuilder from './BaseBuilder';
|
||||
import MacBuilder from './MacBuilder';
|
||||
import WinBuilder from './WinBuilder';
|
||||
import LinuxBuilder from './LinuxBuilder';
|
||||
import { PakeAppOptions } from '@/types';
|
||||
|
||||
const { platform } = process;
|
||||
|
||||
const buildersMap: Record<string, new () => BaseBuilder> = {
|
||||
const buildersMap: Record<string, new (options: PakeAppOptions) => BaseBuilder> = {
|
||||
darwin: MacBuilder,
|
||||
win32: WinBuilder,
|
||||
linux: LinuxBuilder,
|
||||
};
|
||||
|
||||
export default class BuilderProvider {
|
||||
static create(): BaseBuilder {
|
||||
static create(options: PakeAppOptions): BaseBuilder {
|
||||
const Builder = buildersMap[platform];
|
||||
if (!Builder) {
|
||||
throw new Error('The current system is not supported!');
|
||||
}
|
||||
return new Builder();
|
||||
return new Builder(options);
|
||||
}
|
||||
}
|
||||
|
||||
59
bin/builders/LinuxBuilder.ts
vendored
59
bin/builders/LinuxBuilder.ts
vendored
@@ -1,48 +1,31 @@
|
||||
import path from 'path';
|
||||
import fsExtra from "fs-extra";
|
||||
|
||||
import BaseBuilder from './BaseBuilder';
|
||||
import logger from '@/options/logger';
|
||||
import tauriConfig from '@/helpers/tauriConfig';
|
||||
import { npmDirectory } from '@/utils/dir';
|
||||
import { mergeConfig } from "@/helpers/merge";
|
||||
import { PakeAppOptions } from '@/types';
|
||||
import tauriConfig from '@/helpers/tauriConfig';
|
||||
|
||||
export default class LinuxBuilder extends BaseBuilder {
|
||||
async build(url: string, options: PakeAppOptions) {
|
||||
const { name } = options;
|
||||
await mergeConfig(url, options, tauriConfig);
|
||||
await this.runBuildCommand();
|
||||
constructor(options: PakeAppOptions) {
|
||||
super(options);
|
||||
}
|
||||
|
||||
const arch = process.arch === "x64" ? "amd64" : process.arch;
|
||||
|
||||
if (options.targets === "deb" || options.targets === "all") {
|
||||
const debName = `${name}_${tauriConfig.package.version}_${arch}.deb`;
|
||||
const appPath = this.getBuildAppPath(npmDirectory, "deb", debName);
|
||||
const distPath = path.resolve(`${name}.deb`);
|
||||
await fsExtra.copy(appPath, distPath);
|
||||
await fsExtra.remove(appPath);
|
||||
logger.success('✔ Build Deb success!');
|
||||
logger.success('✔ Deb app installer located in', distPath);
|
||||
}
|
||||
|
||||
if (options.targets === "appimage" || options.targets === "all") {
|
||||
const appImageName = `${name}_${tauriConfig.package.version}_${arch}.AppImage`;
|
||||
const appImagePath = this.getBuildAppPath(npmDirectory, "appimage", appImageName);
|
||||
const distAppPath = path.resolve(`${name}.AppImage`);
|
||||
await fsExtra.copy(appImagePath, distAppPath);
|
||||
await fsExtra.remove(appImagePath);
|
||||
logger.success('✔ Build AppImage success!');
|
||||
logger.success('✔ AppImage installer located in', distAppPath);
|
||||
async build(url: string) {
|
||||
const targetTypes = ['deb', 'appimage'];
|
||||
for (const type of targetTypes) {
|
||||
if (this.options.targets === type || this.options.targets === "all") {
|
||||
await this.buildAndCopy(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getBuildAppPath(npmDirectory: string, packageType: string, packageName: string) {
|
||||
return path.join(
|
||||
npmDirectory,
|
||||
'src-tauri/target/release/bundle/',
|
||||
packageType,
|
||||
packageName
|
||||
);
|
||||
getFileName(): string {
|
||||
const { name } = this.options;
|
||||
const arch = this.getArch();
|
||||
return `${name}_${tauriConfig.package.version}_${arch}`;
|
||||
}
|
||||
|
||||
getExtension(): string {
|
||||
if (this.options.targets === 'appimage') {
|
||||
return 'AppImage';
|
||||
}
|
||||
return this.options.targets;
|
||||
}
|
||||
}
|
||||
|
||||
58
bin/builders/MacBuilder.ts
vendored
58
bin/builders/MacBuilder.ts
vendored
@@ -1,36 +1,38 @@
|
||||
import path from 'path';
|
||||
import fsExtra from "fs-extra";
|
||||
|
||||
import BaseBuilder from './BaseBuilder';
|
||||
import logger from '@/options/logger';
|
||||
import tauriConfig from '@/helpers/tauriConfig';
|
||||
import { npmDirectory } from '@/utils/dir';
|
||||
import { mergeConfig } from "@/helpers/merge";
|
||||
import { PakeAppOptions } from '@/types';
|
||||
import BaseBuilder from './BaseBuilder';
|
||||
|
||||
export default class MacBuilder extends BaseBuilder {
|
||||
async build(url: string, options: PakeAppOptions) {
|
||||
const { name } = options;
|
||||
await mergeConfig(url, options, tauriConfig);
|
||||
let dmgName: string;
|
||||
if (options.multiArch) {
|
||||
await this.runBuildCommand('npm run build:mac');
|
||||
dmgName = `${name}_${tauriConfig.package.version}_universal.dmg`;
|
||||
} else {
|
||||
await this.runBuildCommand();
|
||||
let arch = process.arch === "arm64" ? "aarch64" : process.arch;
|
||||
dmgName = `${name}_${tauriConfig.package.version}_${arch}.dmg`;
|
||||
}
|
||||
const appPath = this.getBuildAppPath(npmDirectory, dmgName, options.multiArch);
|
||||
const distPath = path.resolve(`${name}.dmg`);
|
||||
await fsExtra.copy(appPath, distPath);
|
||||
await fsExtra.remove(appPath);
|
||||
logger.success('✔ Build success!');
|
||||
logger.success('✔ App installer located in', distPath);
|
||||
constructor(options: PakeAppOptions) {
|
||||
super(options);
|
||||
}
|
||||
|
||||
getBuildAppPath(npmDirectory: string, dmgName: string, multiArch: boolean) {
|
||||
const dmgPath = multiArch ? 'src-tauri/target/universal-apple-darwin/release/bundle/dmg' : 'src-tauri/target/release/bundle/dmg';
|
||||
return path.join(npmDirectory, dmgPath, dmgName);
|
||||
async build(url: string) {
|
||||
await this.buildAndCopy(url);
|
||||
}
|
||||
|
||||
getFileName(): string {
|
||||
const { name } = this.options;
|
||||
let arch: string;
|
||||
if (this.options.multiArch) {
|
||||
arch = 'universal';
|
||||
} else {
|
||||
arch = process.arch === "arm64" ? "aarch64" : process.arch;
|
||||
}
|
||||
return `${name}_${tauriConfig.package.version}_${arch}`;
|
||||
}
|
||||
|
||||
getExtension(): string {
|
||||
return "dmg";
|
||||
}
|
||||
|
||||
protected getBuildCommand(): string {
|
||||
return this.options.multiArch ? 'npm run build:mac' : super.getBuildCommand();
|
||||
}
|
||||
|
||||
protected getBasePath(): string {
|
||||
return this.options.multiArch
|
||||
? 'src-tauri/target/universal-apple-darwin/release/bundle'
|
||||
: super.getBasePath();
|
||||
}
|
||||
}
|
||||
|
||||
43
bin/builders/WinBuilder.ts
vendored
43
bin/builders/WinBuilder.ts
vendored
@@ -1,35 +1,24 @@
|
||||
import path from 'path';
|
||||
import fsExtra from 'fs-extra';
|
||||
|
||||
import BaseBuilder from './BaseBuilder';
|
||||
import logger from '@/options/logger';
|
||||
import tauriConfig from '@/helpers/tauriConfig';
|
||||
import { npmDirectory } from '@/utils/dir';
|
||||
import { mergeConfig } from '@/helpers/merge';
|
||||
import { PakeAppOptions } from '@/types';
|
||||
import tauriConfig from '@/helpers/tauriConfig';
|
||||
|
||||
export default class WinBuilder extends BaseBuilder {
|
||||
async build(url: string, options: PakeAppOptions) {
|
||||
const { name } = options;
|
||||
await mergeConfig(url, options, tauriConfig);
|
||||
await this.runBuildCommand();
|
||||
|
||||
const language = tauriConfig.tauri.bundle.windows.wix.language[0];
|
||||
const arch = process.arch;
|
||||
const msiName = `${name}_${tauriConfig.package.version}_${arch}_${language}.msi`;
|
||||
const appPath = this.getBuildAppPath(npmDirectory, msiName);
|
||||
const distPath = path.resolve(`${name}.msi`);
|
||||
await fsExtra.copy(appPath, distPath);
|
||||
await fsExtra.remove(appPath);
|
||||
logger.success('✔ Build success!');
|
||||
logger.success('✔ App installer located in', distPath);
|
||||
constructor(options: PakeAppOptions) {
|
||||
super(options);
|
||||
}
|
||||
|
||||
getBuildAppPath(npmDirectory: string, msiName: string) {
|
||||
return path.join(
|
||||
npmDirectory,
|
||||
'src-tauri/target/release/bundle/msi',
|
||||
msiName
|
||||
);
|
||||
async build(url: string) {
|
||||
await this.buildAndCopy(url);
|
||||
}
|
||||
|
||||
getFileName(): string {
|
||||
const { name } = this.options;
|
||||
const arch = this.getArch();
|
||||
const language = tauriConfig.tauri.bundle.windows.wix.language[0];
|
||||
return `${name}_${tauriConfig.package.version}_${arch}_${language}`;
|
||||
}
|
||||
|
||||
getExtension(): string {
|
||||
return "msi";
|
||||
}
|
||||
}
|
||||
|
||||
5
bin/cli.ts
vendored
5
bin/cli.ts
vendored
@@ -21,7 +21,6 @@ program
|
||||
.option('--icon <string>', 'Application icon', DEFAULT.icon)
|
||||
.option('--height <number>', 'Window height', validateNumberInput, DEFAULT.height)
|
||||
.option('--width <number>', 'Window width', validateNumberInput, DEFAULT.width)
|
||||
.option('--resizable', 'Whether the window can be resizable', DEFAULT.resizable)
|
||||
.option('--fullscreen', 'Start the packaged app in full screen', DEFAULT.fullscreen)
|
||||
.option('--transparent', 'Transparent title bar', DEFAULT.transparent)
|
||||
.option('--user-agent <string>', 'Custom user agent', DEFAULT.userAgent)
|
||||
@@ -55,9 +54,9 @@ program
|
||||
const appOptions = await handleInputOptions(options, url);
|
||||
log.debug('PakeAppOptions', appOptions);
|
||||
|
||||
const builder = BuilderProvider.create();
|
||||
const builder = BuilderProvider.create(appOptions);
|
||||
await builder.prepare();
|
||||
await builder.build(url, appOptions);
|
||||
await builder.build(url);
|
||||
});
|
||||
|
||||
program.parse();
|
||||
|
||||
2
bin/utils/info.ts
vendored
2
bin/utils/info.ts
vendored
@@ -27,7 +27,7 @@ export function capitalizeFirstLetter(string: string) {
|
||||
|
||||
export function getSpinner(text: string) {
|
||||
const loadingType = {
|
||||
"interval": 100,
|
||||
"interval": 80,
|
||||
"frames": [
|
||||
"✶",
|
||||
"✵",
|
||||
|
||||
Reference in New Issue
Block a user