mirror of
https://github.com/zen-browser/surfer.git
synced 2025-07-08 17:30:02 +02:00
♻️ Refactor commands some more to make them simpler
This commit is contained in:
parent
f4982fc699
commit
7572f8527a
6 changed files with 79 additions and 219 deletions
|
@ -7,7 +7,6 @@ import {
|
||||||
execute,
|
execute,
|
||||||
exportFile,
|
exportFile,
|
||||||
fixLineEndings,
|
fixLineEndings,
|
||||||
importPatches,
|
|
||||||
init,
|
init,
|
||||||
licenseCheck,
|
licenseCheck,
|
||||||
melonPackage,
|
melonPackage,
|
||||||
|
|
|
@ -6,7 +6,6 @@ export * from './download-artifacts'
|
||||||
export * from './execute'
|
export * from './execute'
|
||||||
export * from './export-file'
|
export * from './export-file'
|
||||||
export * from './fix-le'
|
export * from './fix-le'
|
||||||
export * from './import-patches'
|
|
||||||
export * from './init'
|
export * from './init'
|
||||||
export * from './license-check'
|
export * from './license-check'
|
||||||
export * from './package'
|
export * from './package'
|
||||||
|
|
|
@ -37,29 +37,18 @@ function importMelonPatches(): ListrTaskGroup {
|
||||||
for (const brandingStyle of readdirSync(BRANDING_DIR).filter((file) =>
|
for (const brandingStyle of readdirSync(BRANDING_DIR).filter((file) =>
|
||||||
lstatSync(join(BRANDING_DIR, file)).isDirectory()
|
lstatSync(join(BRANDING_DIR, file)).isDirectory()
|
||||||
)) {
|
)) {
|
||||||
patches.push(new BrandingPatch(brandingStyle, false))
|
patches.push(new BrandingPatch(brandingStyle))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return patchMethod(
|
return patchMethod('melon', patches, async (patch) => await patch.apply())
|
||||||
'melon',
|
|
||||||
patches,
|
|
||||||
async (patch, i) => await patch.applyWithStatus([i, patches.length])
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function importFolders(): ListrTaskGroup {
|
function importFolders(): ListrTaskGroup {
|
||||||
return patchMethod(
|
return patchMethod(
|
||||||
'folder',
|
'folder',
|
||||||
manualPatches.map(
|
manualPatches.map(
|
||||||
(patch, i) =>
|
(patch) => new ManualPatch(patch.name, patch.action, patch.src)
|
||||||
new ManualPatch(
|
|
||||||
patch.name,
|
|
||||||
[i, manualPatches.length],
|
|
||||||
{},
|
|
||||||
patch.action,
|
|
||||||
patch.src
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
async (patch) => await patch.apply()
|
async (patch) => await patch.apply()
|
||||||
)
|
)
|
||||||
|
@ -68,9 +57,8 @@ function importFolders(): ListrTaskGroup {
|
||||||
function importGitPatch(): ListrTaskGroup {
|
function importGitPatch(): ListrTaskGroup {
|
||||||
return patchMethod(
|
return patchMethod(
|
||||||
'git',
|
'git',
|
||||||
sync('**/*.patch').map(
|
sync('**/*.patch', { nodir: true, cwd: SRC_DIR }).map(
|
||||||
(file, i, array) =>
|
(file) => new PatchFile(file, resolve(SRC_DIR, file))
|
||||||
new PatchFile(file, [i, array.length], {}, resolve(SRC_DIR, file))
|
|
||||||
),
|
),
|
||||||
async (patch) => await patch.apply()
|
async (patch) => await patch.apply()
|
||||||
)
|
)
|
||||||
|
|
|
@ -36,8 +36,8 @@ export class BrandingPatch extends PatchBase {
|
||||||
outputPath: string
|
outputPath: string
|
||||||
configPath: string
|
configPath: string
|
||||||
|
|
||||||
constructor(name: string, minimal?: boolean) {
|
constructor(name: string) {
|
||||||
super(`Browser branding: ${name}`, [0, 0], { minimal })
|
super(`Browser branding: ${name}`)
|
||||||
this.name = name
|
this.name = name
|
||||||
|
|
||||||
this.outputPath = join(BRANDING_STORE, name)
|
this.outputPath = join(BRANDING_STORE, name)
|
||||||
|
@ -64,44 +64,25 @@ export class BrandingPatch extends PatchBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
async apply(): Promise<void> {
|
async apply(): Promise<void> {
|
||||||
this.start()
|
this.checkForFaults()
|
||||||
|
|
||||||
try {
|
const brandingConfig = {
|
||||||
log.debug('Checking branding files')
|
brandingGenericName: config.name,
|
||||||
|
brandingVendor: config.vendor,
|
||||||
|
|
||||||
this.checkForFaults()
|
...defaultBrandsConfig,
|
||||||
|
...(config.brands[this.name] || {}),
|
||||||
const brandingConfig = {
|
|
||||||
brandingGenericName: config.name,
|
|
||||||
brandingVendor: config.vendor,
|
|
||||||
|
|
||||||
...defaultBrandsConfig,
|
|
||||||
...(config.brands[this.name] || {}),
|
|
||||||
}
|
|
||||||
|
|
||||||
log.debug(`Creating folder ${this.outputPath}`)
|
|
||||||
|
|
||||||
if (existsSync(this.outputPath))
|
|
||||||
rmdirSync(this.outputPath, { recursive: true })
|
|
||||||
mkdirSync(this.outputPath, { recursive: true })
|
|
||||||
|
|
||||||
log.debug('Setup images')
|
|
||||||
|
|
||||||
await this.setupImages()
|
|
||||||
|
|
||||||
log.debug(`Setup locales`)
|
|
||||||
|
|
||||||
this.setupLocales(brandingConfig)
|
|
||||||
|
|
||||||
log.debug(`Copying files from ${BRANDING_FF}`)
|
|
||||||
|
|
||||||
await this.copyMozillaFiles(brandingConfig)
|
|
||||||
|
|
||||||
this.done = true
|
|
||||||
} catch (e) {
|
|
||||||
this.error = e
|
|
||||||
this.done = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (existsSync(this.outputPath))
|
||||||
|
rmdirSync(this.outputPath, { recursive: true })
|
||||||
|
mkdirSync(this.outputPath, { recursive: true })
|
||||||
|
|
||||||
|
await this.setupImages()
|
||||||
|
|
||||||
|
this.setupLocales(brandingConfig)
|
||||||
|
|
||||||
|
await this.copyMozillaFiles(brandingConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
private async copyMozillaFiles(brandingConfig: {
|
private async copyMozillaFiles(brandingConfig: {
|
||||||
|
@ -159,16 +140,12 @@ export class BrandingPatch extends PatchBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async setupImages() {
|
private async setupImages() {
|
||||||
log.debug('Creating default*.png files')
|
|
||||||
|
|
||||||
for (const size of [16, 22, 24, 32, 48, 64, 128, 256]) {
|
for (const size of [16, 22, 24, 32, 48, 64, 128, 256]) {
|
||||||
await sharp(join(this.configPath, 'logo.png'))
|
await sharp(join(this.configPath, 'logo.png'))
|
||||||
.resize(size, size)
|
.resize(size, size)
|
||||||
.toFile(join(this.outputPath, `default${size}.png`))
|
.toFile(join(this.outputPath, `default${size}.png`))
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug('Creating firefox*.ico')
|
|
||||||
|
|
||||||
await sharp(join(this.configPath, 'logo.png'))
|
await sharp(join(this.configPath, 'logo.png'))
|
||||||
.resize(512, 512)
|
.resize(512, 512)
|
||||||
.toFile(join(this.outputPath, 'firefox.ico'))
|
.toFile(join(this.outputPath, 'firefox.ico'))
|
||||||
|
@ -176,8 +153,6 @@ export class BrandingPatch extends PatchBase {
|
||||||
.resize(64, 64)
|
.resize(64, 64)
|
||||||
.toFile(join(this.outputPath, 'firefox64.ico'))
|
.toFile(join(this.outputPath, 'firefox64.ico'))
|
||||||
|
|
||||||
log.debug('Creating content/about-logo*.png')
|
|
||||||
|
|
||||||
mkdirSync(join(this.outputPath, 'content'), { recursive: true })
|
mkdirSync(join(this.outputPath, 'content'), { recursive: true })
|
||||||
|
|
||||||
await sharp(join(this.configPath, 'logo.png'))
|
await sharp(join(this.configPath, 'logo.png'))
|
||||||
|
|
|
@ -1,80 +1,16 @@
|
||||||
import chalk from 'chalk'
|
|
||||||
import execa from 'execa'
|
import execa from 'execa'
|
||||||
import { existsSync, rmdirSync, rmSync, statSync } from 'fs'
|
import { existsSync, rmdirSync, rmSync, statSync } from 'fs'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import readline from 'readline'
|
|
||||||
import { log } from '..'
|
import { log } from '..'
|
||||||
|
import { discard } from '../commands'
|
||||||
import { ENGINE_DIR, PATCH_ARGS } from '../constants'
|
import { ENGINE_DIR, PATCH_ARGS } from '../constants'
|
||||||
import { copyManual } from '../utils'
|
import { copyManual } from '../utils'
|
||||||
|
|
||||||
export abstract class PatchBase {
|
export abstract class PatchBase {
|
||||||
public name: string
|
public name: string
|
||||||
|
|
||||||
protected status: number[]
|
constructor(name: string) {
|
||||||
|
|
||||||
protected options: {
|
|
||||||
minimal?: boolean
|
|
||||||
noIgnore?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
private _done = false
|
|
||||||
|
|
||||||
protected error: Error | unknown
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
name: string,
|
|
||||||
status: number[],
|
|
||||||
options: {
|
|
||||||
minimal?: boolean
|
|
||||||
noIgnore?: boolean
|
|
||||||
} = {}
|
|
||||||
) {
|
|
||||||
this.name = name
|
this.name = name
|
||||||
this.status = status
|
|
||||||
this.options = options
|
|
||||||
}
|
|
||||||
|
|
||||||
protected get done(): boolean {
|
|
||||||
return this._done
|
|
||||||
}
|
|
||||||
|
|
||||||
protected set done(_: boolean) {
|
|
||||||
this._done = _
|
|
||||||
|
|
||||||
if (this.options.minimal) return
|
|
||||||
|
|
||||||
// Move to the start of the last line
|
|
||||||
readline.moveCursor(process.stdout, 0, -1)
|
|
||||||
readline.clearLine(process.stdout, 1)
|
|
||||||
|
|
||||||
// Print the status
|
|
||||||
log.info(
|
|
||||||
`${chalk.gray(`(${this.status[0]}/${this.status[1]})`)} Applying ${
|
|
||||||
this.name
|
|
||||||
}... ${chalk[this._done ? 'green' : 'red'].bold(
|
|
||||||
this._done ? 'Done ✔' : 'Error ❗'
|
|
||||||
)}`
|
|
||||||
)
|
|
||||||
|
|
||||||
// If there is an error present, it should be thrown
|
|
||||||
if (this.error) {
|
|
||||||
throw this.error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected start(): void {
|
|
||||||
if (this.options.minimal) return
|
|
||||||
|
|
||||||
log.info(
|
|
||||||
`${chalk.gray(`(${this.status[0]}/${this.status[1]})`)} Applying ${
|
|
||||||
this.name
|
|
||||||
}...`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public applyWithStatus(status: [number, number]): Promise<void> {
|
|
||||||
this.status = status
|
|
||||||
return this.apply()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected filesExist(files: string[]): boolean {
|
protected filesExist(files: string[]): boolean {
|
||||||
|
@ -89,17 +25,8 @@ export class ManualPatch extends PatchBase {
|
||||||
|
|
||||||
private src: string | string[]
|
private src: string | string[]
|
||||||
|
|
||||||
constructor(
|
constructor(name: string, action: 'copy' | 'delete', src: string | string[]) {
|
||||||
name: string,
|
super(name)
|
||||||
status: number[],
|
|
||||||
options: {
|
|
||||||
minimal?: boolean
|
|
||||||
noIgnore?: boolean
|
|
||||||
} = {},
|
|
||||||
action: 'copy' | 'delete',
|
|
||||||
src: string | string[]
|
|
||||||
) {
|
|
||||||
super(name, status, options)
|
|
||||||
|
|
||||||
this.action = action
|
this.action = action
|
||||||
this.src = src
|
this.src = src
|
||||||
|
@ -126,48 +53,39 @@ export class ManualPatch extends PatchBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
async apply(): Promise<void> {
|
async apply(): Promise<void> {
|
||||||
this.start()
|
switch (this.action) {
|
||||||
|
case 'copy':
|
||||||
try {
|
if (typeof this.src === 'string') {
|
||||||
switch (this.action) {
|
await copyManual(this.src)
|
||||||
case 'copy':
|
} else if (Array.isArray(this.src)) {
|
||||||
if (typeof this.src === 'string') {
|
for (const item of this.src) {
|
||||||
await copyManual(this.src, this.options.noIgnore)
|
await copyManual(item)
|
||||||
} else if (Array.isArray(this.src)) {
|
|
||||||
for (const item of this.src) {
|
|
||||||
await copyManual(item, this.options.noIgnore)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new Error(
|
|
||||||
`'${this.src}' is not a valid source. Please provide a string or an array`
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
`'${this.src}' is not a valid source. Please provide a string or an array`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
case 'delete':
|
case 'delete':
|
||||||
if (typeof this.src === 'string') {
|
if (typeof this.src === 'string') {
|
||||||
this.delete(ENGINE_DIR, this.src)
|
this.delete(ENGINE_DIR, this.src)
|
||||||
} else if (Array.isArray(this.src)) {
|
} else if (Array.isArray(this.src)) {
|
||||||
for (const item of this.src) {
|
for (const item of this.src) {
|
||||||
this.delete(ENGINE_DIR, item)
|
this.delete(ENGINE_DIR, item)
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new Error(
|
|
||||||
`'${this.src}' is not a valid source. Please provide a string or an array`
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
`'${this.src}' is not a valid source. Please provide a string or an array`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unknown manual patch action: ${this.action}`)
|
throw new Error(`Unknown manual patch action: ${this.action}`)
|
||||||
}
|
|
||||||
|
|
||||||
this.done = true
|
|
||||||
} catch (e) {
|
|
||||||
this.error = e
|
|
||||||
this.done = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,43 +93,29 @@ export class ManualPatch extends PatchBase {
|
||||||
export class PatchFile extends PatchBase {
|
export class PatchFile extends PatchBase {
|
||||||
private src: string
|
private src: string
|
||||||
|
|
||||||
constructor(
|
constructor(name: string, src: string) {
|
||||||
name: string,
|
super(name)
|
||||||
status: number[],
|
|
||||||
options: {
|
|
||||||
minimal?: boolean
|
|
||||||
noIgnore?: boolean
|
|
||||||
} = {},
|
|
||||||
src: string
|
|
||||||
) {
|
|
||||||
super(name, status, options)
|
|
||||||
this.src = src
|
this.src = src
|
||||||
}
|
}
|
||||||
|
|
||||||
async apply(): Promise<void> {
|
async apply(): Promise<void> {
|
||||||
this.start()
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
try {
|
await execa('git', ['apply', '-R', ...PATCH_ARGS, this.src], {
|
||||||
await execa('git', ['apply', '-R', ...PATCH_ARGS, this.src], {
|
cwd: ENGINE_DIR,
|
||||||
cwd: ENGINE_DIR,
|
})
|
||||||
})
|
} catch (_e) {
|
||||||
} catch (e) {
|
// If the patch has already been applied, we want to revert it. Because
|
||||||
null
|
// there is no good way to check this we are just going to catch and
|
||||||
}
|
// discard the error
|
||||||
|
null
|
||||||
const { stdout, exitCode } = await execa(
|
|
||||||
'git',
|
|
||||||
['apply', ...PATCH_ARGS, this.src],
|
|
||||||
{ cwd: ENGINE_DIR }
|
|
||||||
)
|
|
||||||
|
|
||||||
if (exitCode != 0) throw stdout
|
|
||||||
|
|
||||||
this.done = true
|
|
||||||
} catch (e) {
|
|
||||||
this.error = e
|
|
||||||
this.done = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { stdout, exitCode } = await execa(
|
||||||
|
'git',
|
||||||
|
['apply', ...PATCH_ARGS, this.src],
|
||||||
|
{ cwd: ENGINE_DIR }
|
||||||
|
)
|
||||||
|
|
||||||
|
if (exitCode != 0) throw stdout
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,7 @@ import { ENGINE_DIR, SRC_DIR } from '../constants'
|
||||||
|
|
||||||
const getChunked = (location: string) => location.replace(/\\/g, '/').split('/')
|
const getChunked = (location: string) => location.replace(/\\/g, '/').split('/')
|
||||||
|
|
||||||
export const copyManual = async (
|
export const copyManual = async (name: string): Promise<void> => {
|
||||||
name: string,
|
|
||||||
noIgnore?: boolean
|
|
||||||
): Promise<void> => {
|
|
||||||
// If the file exists and is not a symlink, we want to replace it with a
|
// If the file exists and is not a symlink, we want to replace it with a
|
||||||
// symlink to our file, so remove it
|
// symlink to our file, so remove it
|
||||||
if (
|
if (
|
||||||
|
@ -41,13 +38,11 @@ export const copyManual = async (
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!noIgnore) {
|
const gitignore = readFileSync(resolve(ENGINE_DIR, '.gitignore'), 'utf-8')
|
||||||
const gitignore = readFileSync(resolve(ENGINE_DIR, '.gitignore'), 'utf-8')
|
|
||||||
|
|
||||||
if (!gitignore.includes(getChunked(name).join('/')))
|
if (!gitignore.includes(getChunked(name).join('/')))
|
||||||
appendToFileSync(
|
appendToFileSync(
|
||||||
resolve(ENGINE_DIR, '.gitignore'),
|
resolve(ENGINE_DIR, '.gitignore'),
|
||||||
`\n${getChunked(name).join('/')}`
|
`\n${getChunked(name).join('/')}`
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue