🎨 CLI is more user-friendly.
This commit is contained in:
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";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user