mirror of
https://github.com/zen-browser/surfer.git
synced 2025-07-08 01:10:03 +02:00
🎨 New, overkill linter
This commit is contained in:
parent
7650c90c3a
commit
d84e0941b5
49 changed files with 670 additions and 470 deletions
11
.eslintrc.js
11
.eslintrc.js
|
@ -3,12 +3,17 @@ module.exports = {
|
||||||
es2021: true,
|
es2021: true,
|
||||||
node: true,
|
node: true,
|
||||||
},
|
},
|
||||||
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
|
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:unicorn/recommended'],
|
||||||
parser: '@typescript-eslint/parser',
|
parser: '@typescript-eslint/parser',
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
ecmaVersion: 'latest',
|
ecmaVersion: 'latest',
|
||||||
sourceType: 'module',
|
sourceType: 'module',
|
||||||
},
|
},
|
||||||
plugins: ['@typescript-eslint'],
|
plugins: ['@typescript-eslint', 'unicorn'],
|
||||||
rules: {},
|
rules: {
|
||||||
|
'unicorn/no-process-exit': 0,
|
||||||
|
// We are currently using commonjs. If / when it becomes viable for us to
|
||||||
|
// switch to ESModules, we should consider enabling this rule
|
||||||
|
'unicorn/prefer-module': 0,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
"@typescript-eslint/eslint-plugin": "^5.22.0",
|
"@typescript-eslint/eslint-plugin": "^5.22.0",
|
||||||
"@typescript-eslint/parser": "^5.22.0",
|
"@typescript-eslint/parser": "^5.22.0",
|
||||||
"eslint": "^8.15.0",
|
"eslint": "^8.15.0",
|
||||||
|
"eslint-plugin-unicorn": "^44.0.2",
|
||||||
"jest": "^27.4.5",
|
"jest": "^27.4.5",
|
||||||
"prettier": "^2.2.1",
|
"prettier": "^2.2.1",
|
||||||
"ts-jest": "^27.1.2",
|
"ts-jest": "^27.1.2",
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
/* eslint-disable unicorn/no-await-expression-member */
|
||||||
|
|
||||||
import { Cmd } from './types'
|
import { Cmd } from './types'
|
||||||
|
|
||||||
export const commands: Cmd[] = [
|
export const commands: Cmd[] = [
|
||||||
|
@ -132,7 +135,7 @@ export const commands: Cmd[] = [
|
||||||
cmd: 'setup-project',
|
cmd: 'setup-project',
|
||||||
description: 'Sets up a gluon project for the first time',
|
description: 'Sets up a gluon project for the first time',
|
||||||
requestController: async () =>
|
requestController: async () =>
|
||||||
(await import('./commands/setupProject')).setupProject,
|
(await import('./commands/setup-project')).setupProject,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cmd: 'status',
|
cmd: 'status',
|
||||||
|
|
|
@ -10,11 +10,11 @@ import { configDispatch } from '../utils'
|
||||||
export const bootstrap = async () => {
|
export const bootstrap = async () => {
|
||||||
log.info(`Bootstrapping ${config.name}...`)
|
log.info(`Bootstrapping ${config.name}...`)
|
||||||
|
|
||||||
const args = ['--application-choice', 'browser']
|
const arguments_ = ['--application-choice', 'browser']
|
||||||
|
|
||||||
console.debug(`Passing through to |mach bootstrap|`)
|
console.debug(`Passing through to |mach bootstrap|`)
|
||||||
await configDispatch('./mach', {
|
await configDispatch('./mach', {
|
||||||
args: ['bootstrap', ...args],
|
args: ['bootstrap', ...arguments_],
|
||||||
cwd: ENGINE_DIR,
|
cwd: ENGINE_DIR,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
import execa from 'execa'
|
import execa from 'execa'
|
||||||
import { existsSync, readFileSync, writeFileSync } from 'fs'
|
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
||||||
import { join, resolve } from 'path'
|
import { join, resolve } from 'node:path'
|
||||||
import { bin_name, config } from '..'
|
import { bin_name, config } from '..'
|
||||||
import { BUILD_TARGETS, CONFIGS_DIR, ENGINE_DIR } from '../constants'
|
import { BUILD_TARGETS, CONFIGS_DIR, ENGINE_DIR } from '../constants'
|
||||||
import { internalMozconfg } from '../constants/mozconfig'
|
import { internalMozconfg } from '../constants/mozconfig'
|
||||||
|
@ -28,7 +28,7 @@ const applyConfig = async (os: string) => {
|
||||||
// Retrieve changeset
|
// Retrieve changeset
|
||||||
const { stdout } = await execa('git', ['rev-parse', 'HEAD'])
|
const { stdout } = await execa('git', ['rev-parse', 'HEAD'])
|
||||||
changeset = stdout.trim()
|
changeset = stdout.trim()
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
log.warning(
|
log.warning(
|
||||||
'Gluon expects that you are building your browser with git as your version control'
|
'Gluon expects that you are building your browser with git as your version control'
|
||||||
)
|
)
|
||||||
|
@ -38,7 +38,7 @@ const applyConfig = async (os: string) => {
|
||||||
log.warning('Otherwise, you can setup git in this folder by running:')
|
log.warning('Otherwise, you can setup git in this folder by running:')
|
||||||
log.warning(' |git init|')
|
log.warning(' |git init|')
|
||||||
|
|
||||||
throw e
|
throw error
|
||||||
}
|
}
|
||||||
|
|
||||||
const templateOptions = {
|
const templateOptions = {
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
import execa from 'execa'
|
import execa from 'execa'
|
||||||
import { existsSync, statSync } from 'fs'
|
import { existsSync, statSync } from 'node:fs'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'node:path'
|
||||||
import { log } from '../log'
|
import { log } from '../log'
|
||||||
import { ENGINE_DIR } from '../constants'
|
import { ENGINE_DIR } from '../constants'
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ export const discard = async (file: string): Promise<void> => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await execa('git', ['restore', file], { cwd: ENGINE_DIR })
|
await execa('git', ['restore', file], { cwd: ENGINE_DIR })
|
||||||
} catch (e) {
|
} catch {
|
||||||
log.warning(`The file ${file} was not changed`)
|
log.warning(`The file ${file} was not changed`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'fs'
|
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs'
|
||||||
import { join } from 'path'
|
import { join } from 'node:path'
|
||||||
import { isMatch } from 'picomatch'
|
import { isMatch } from 'picomatch'
|
||||||
|
|
||||||
import { config } from '../..'
|
import { config } from '../..'
|
||||||
|
@ -10,7 +10,7 @@ import {
|
||||||
AddonInfo,
|
AddonInfo,
|
||||||
configDispatch,
|
configDispatch,
|
||||||
delay,
|
delay,
|
||||||
ensureDir,
|
ensureDirectory,
|
||||||
walkDirectoryTree,
|
walkDirectoryTree,
|
||||||
windowsPathToUnix,
|
windowsPathToUnix,
|
||||||
} from '../../utils'
|
} from '../../utils'
|
||||||
|
@ -29,34 +29,36 @@ export async function resolveAddonDownloadUrl(
|
||||||
addon: AddonInfo
|
addon: AddonInfo
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
switch (addon.platform) {
|
switch (addon.platform) {
|
||||||
case 'url':
|
case 'url': {
|
||||||
return addon.url
|
return addon.url
|
||||||
|
}
|
||||||
|
|
||||||
case 'amo':
|
case 'amo': {
|
||||||
try {
|
try {
|
||||||
return (
|
const mozillaData = await axios.get(
|
||||||
await axios.get(
|
`https://addons.mozilla.org/api/v4/addons/addon/${addon.amoId}/versions/`
|
||||||
`https://addons.mozilla.org/api/v4/addons/addon/${addon.amoId}/versions/`
|
)
|
||||||
)
|
|
||||||
).data.results[0].files[0].url
|
return mozillaData.data.results[0].files[0].url
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
log.warning(
|
log.warning(
|
||||||
'The following error occured whilst fetching amo addon metadata'
|
'The following error occured whilst fetching amo addon metadata'
|
||||||
)
|
)
|
||||||
log.error(e)
|
log.error(error)
|
||||||
|
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case 'github':
|
case 'github': {
|
||||||
try {
|
try {
|
||||||
|
const githubData = await axios.get(
|
||||||
|
`https://api.github.com/repos/${addon.repo}/releases/tags/${addon.version}`
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
(
|
(
|
||||||
((
|
(githubData.data.assets as {
|
||||||
await axios.get(
|
|
||||||
`https://api.github.com/repos/${addon.repo}/releases/tags/${addon.version}`
|
|
||||||
)
|
|
||||||
).data.assets as {
|
|
||||||
url: string
|
url: string
|
||||||
browser_download_url: string
|
browser_download_url: string
|
||||||
name: string
|
name: string
|
||||||
|
@ -64,14 +66,15 @@ export async function resolveAddonDownloadUrl(
|
||||||
).find((asset) => isMatch(asset.name, addon.fileGlob))
|
).find((asset) => isMatch(asset.name, addon.fileGlob))
|
||||||
?.browser_download_url || 'failed'
|
?.browser_download_url || 'failed'
|
||||||
)
|
)
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
log.warning(
|
log.warning(
|
||||||
'The following error occured whilst fetching github metadata'
|
'The following error occured whilst fetching github metadata'
|
||||||
)
|
)
|
||||||
log.error(e)
|
log.error(error)
|
||||||
|
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +82,7 @@ export async function downloadAddon(
|
||||||
url: string,
|
url: string,
|
||||||
addon: AddonInfo & { name: string }
|
addon: AddonInfo & { name: string }
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const tempFile = join(MELON_TMP_DIR, addon.name + '.xpi')
|
const temporaryFile = join(MELON_TMP_DIR, addon.name + '.xpi')
|
||||||
|
|
||||||
log.info(`Download addon from ${url}`)
|
log.info(`Download addon from ${url}`)
|
||||||
|
|
||||||
|
@ -91,23 +94,23 @@ export async function downloadAddon(
|
||||||
// it
|
// it
|
||||||
} else {
|
} else {
|
||||||
const cache = extensionCache.unwrap()
|
const cache = extensionCache.unwrap()
|
||||||
if (cache.url == url && existsSync(tempFile)) {
|
if (cache.url == url && existsSync(temporaryFile)) {
|
||||||
log.info(`Using cached version of ${addon.name}`)
|
log.info(`Using cached version of ${addon.name}`)
|
||||||
return tempFile
|
return temporaryFile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (existsSync(tempFile)) {
|
if (existsSync(temporaryFile)) {
|
||||||
unlinkSync(tempFile)
|
unlinkSync(temporaryFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
await downloadFileToLocation(url, tempFile)
|
await downloadFileToLocation(url, temporaryFile)
|
||||||
|
|
||||||
// I do not know why, but this delay causes unzip to work reliably
|
// I do not know why, but this delay causes unzip to work reliably
|
||||||
await delay(200)
|
await delay(200)
|
||||||
|
|
||||||
return tempFile
|
return temporaryFile
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function unpackAddon(
|
export async function unpackAddon(
|
||||||
|
@ -128,7 +131,7 @@ export async function unpackAddon(
|
||||||
// I do not know why, but this delay causes unzip to work reliably
|
// I do not know why, but this delay causes unzip to work reliably
|
||||||
await delay(200)
|
await delay(200)
|
||||||
|
|
||||||
ensureDir(outPath)
|
ensureDirectory(outPath)
|
||||||
|
|
||||||
await configDispatch('unzip', {
|
await configDispatch('unzip', {
|
||||||
args: [windowsPathToUnix(path), '-d', windowsPathToUnix(outPath)],
|
args: [windowsPathToUnix(path), '-d', windowsPathToUnix(outPath)],
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import execa from 'execa'
|
import execa from 'execa'
|
||||||
import { existsSync } from 'fs'
|
import { existsSync } from 'node:fs'
|
||||||
import { dirname, resolve } from 'path'
|
import { dirname, resolve } from 'node:path'
|
||||||
import { bin_name } from '../..'
|
import { bin_name } from '../..'
|
||||||
import { BASH_PATH, ENGINE_DIR, MELON_TMP_DIR } from '../../constants'
|
import { BASH_PATH, ENGINE_DIR, MELON_TMP_DIR } from '../../constants'
|
||||||
import { log } from '../../log'
|
import { log } from '../../log'
|
||||||
import { commandExistsSync } from '../../utils/commandExists'
|
import { commandExistsSync } from '../../utils/command-exists'
|
||||||
import { downloadFileToLocation } from '../../utils/download'
|
import { downloadFileToLocation } from '../../utils/download'
|
||||||
import { ensureDir, windowsPathToUnix } from '../../utils/fs'
|
import { ensureDirectory, windowsPathToUnix } from '../../utils/fs'
|
||||||
import { init } from '../init'
|
import { init } from '../init'
|
||||||
|
|
||||||
export function shouldSetupFirefoxSource() {
|
export function shouldSetupFirefoxSource() {
|
||||||
|
@ -30,7 +30,7 @@ export async function setupFirefoxSource(version: string) {
|
||||||
async function unpackFirefoxSource(name: string): Promise<void> {
|
async function unpackFirefoxSource(name: string): Promise<void> {
|
||||||
log.info(`Unpacking Firefox...`)
|
log.info(`Unpacking Firefox...`)
|
||||||
|
|
||||||
ensureDir(ENGINE_DIR)
|
ensureDirectory(ENGINE_DIR)
|
||||||
|
|
||||||
let tarExec = 'tar'
|
let tarExec = 'tar'
|
||||||
|
|
||||||
|
@ -56,12 +56,12 @@ async function unpackFirefoxSource(name: string): Promise<void> {
|
||||||
tarExec,
|
tarExec,
|
||||||
[
|
[
|
||||||
'--strip-components=1',
|
'--strip-components=1',
|
||||||
process.platform == 'win32' ? '--force-local' : null,
|
process.platform == 'win32' ? '--force-local' : undefined,
|
||||||
'-xf',
|
'-xf',
|
||||||
windowsPathToUnix(resolve(MELON_TMP_DIR, name)),
|
windowsPathToUnix(resolve(MELON_TMP_DIR, name)),
|
||||||
'-C',
|
'-C',
|
||||||
windowsPathToUnix(ENGINE_DIR),
|
windowsPathToUnix(ENGINE_DIR),
|
||||||
].filter((x) => x) as string[],
|
].filter(Boolean) as string[],
|
||||||
{
|
{
|
||||||
// HACK: Use bash shell on windows to get a sane version of tar that works
|
// HACK: Use bash shell on windows to get a sane version of tar that works
|
||||||
shell: BASH_PATH || false,
|
shell: BASH_PATH || false,
|
||||||
|
@ -80,7 +80,7 @@ async function downloadFirefoxSource(version: string) {
|
||||||
|
|
||||||
log.info(`Locating Firefox release ${version}...`)
|
log.info(`Locating Firefox release ${version}...`)
|
||||||
|
|
||||||
await ensureDir(dirname(fsSaveLocation))
|
await ensureDirectory(dirname(fsSaveLocation))
|
||||||
|
|
||||||
if (existsSync(fsSaveLocation)) {
|
if (existsSync(fsSaveLocation)) {
|
||||||
log.info('Using cached download')
|
log.info('Using cached download')
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
import { existsSync } from 'fs'
|
import { existsSync } from 'node:fs'
|
||||||
import { log } from '../log'
|
import { log } from '../log'
|
||||||
import { ENGINE_DIR } from '../constants'
|
import { ENGINE_DIR } from '../constants'
|
||||||
import { dispatch } from '../utils'
|
import { dispatch } from '../utils'
|
||||||
|
|
||||||
export const execute = async (cmd: string[]) => {
|
export const execute = async (cmd: string[]) => {
|
||||||
if (existsSync(ENGINE_DIR)) {
|
if (existsSync(ENGINE_DIR)) {
|
||||||
if (!cmd || cmd.length == 0)
|
if (!cmd || cmd.length === 0)
|
||||||
log.error('You need to specify a command to run.')
|
log.error('You need to specify a command to run.')
|
||||||
|
|
||||||
const bin = cmd[0]
|
const bin = cmd[0]
|
||||||
const args = cmd
|
const arguments_ = cmd
|
||||||
args.shift()
|
arguments_.shift()
|
||||||
|
|
||||||
log.info(
|
log.info(
|
||||||
`Executing \`${bin}${args.length !== 0 ? ` ` : ``}${args.join(
|
`Executing \`${bin}${arguments_.length > 0 ? ` ` : ``}${arguments_.join(
|
||||||
' '
|
' '
|
||||||
)}\` in \`src\`...`
|
)}\` in \`src\`...`
|
||||||
)
|
)
|
||||||
dispatch(bin, args, ENGINE_DIR)
|
dispatch(bin, arguments_, ENGINE_DIR)
|
||||||
} else {
|
} else {
|
||||||
log.error(`Unable to locate src directory.`)
|
log.error(`Unable to locate src directory.`)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
import execa from 'execa'
|
import execa from 'execa'
|
||||||
import { existsSync, writeFileSync } from 'fs'
|
import { existsSync, writeFileSync } from 'node:fs'
|
||||||
import { basename, resolve } from 'path'
|
import { basename, resolve } from 'node:path'
|
||||||
import { log } from '../log'
|
import { log } from '../log'
|
||||||
import { ENGINE_DIR, SRC_DIR } from '../constants'
|
import { ENGINE_DIR, SRC_DIR } from '../constants'
|
||||||
import { delay, ensureDir } from '../utils'
|
import { delay, ensureDirectory } from '../utils'
|
||||||
|
|
||||||
export const getPatchName = (file: string): string =>
|
export const getPatchName = (file: string): string =>
|
||||||
`${basename(file).replace(/\./g, '-')}.patch`
|
`${basename(file).replace(/\./g, '-')}.patch`
|
||||||
|
@ -36,7 +36,7 @@ export const exportFile = async (file: string): Promise<void> => {
|
||||||
const name = getPatchName(file)
|
const name = getPatchName(file)
|
||||||
const patchPath = file.replace(/\./g, '-').split('/').slice(0, -1)
|
const patchPath = file.replace(/\./g, '-').split('/').slice(0, -1)
|
||||||
|
|
||||||
await ensureDir(resolve(SRC_DIR, ...patchPath))
|
await ensureDirectory(resolve(SRC_DIR, ...patchPath))
|
||||||
|
|
||||||
if (proc.stdout.length >= 8000) {
|
if (proc.stdout.length >= 8000) {
|
||||||
log.warning('')
|
log.warning('')
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
import { Command } from 'commander'
|
import { Command } from 'commander'
|
||||||
import { existsSync, readFileSync } from 'fs'
|
import { existsSync, readFileSync } from 'node:fs'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'node:path'
|
||||||
import { bin_name } from '..'
|
import { bin_name } from '..'
|
||||||
import { log } from '../log'
|
import { log } from '../log'
|
||||||
import { config, configDispatch } from '../utils'
|
import { config, configDispatch } from '../utils'
|
||||||
|
@ -11,9 +11,9 @@ import { config, configDispatch } from '../utils'
|
||||||
export const init = async (directory: Command | string): Promise<void> => {
|
export const init = async (directory: Command | string): Promise<void> => {
|
||||||
const cwd = process.cwd()
|
const cwd = process.cwd()
|
||||||
|
|
||||||
const dir = resolve(cwd as string, directory.toString())
|
const absoluteInitDirectory = resolve(cwd as string, directory.toString())
|
||||||
|
|
||||||
if (!existsSync(dir)) {
|
if (!existsSync(absoluteInitDirectory)) {
|
||||||
log.error(
|
log.error(
|
||||||
`Directory "${directory}" not found.\nCheck the directory exists and run |${bin_name} init| again.`
|
`Directory "${directory}" not found.\nCheck the directory exists and run |${bin_name} init| again.`
|
||||||
)
|
)
|
||||||
|
@ -36,30 +36,31 @@ export const init = async (directory: Command | string): Promise<void> => {
|
||||||
|
|
||||||
version = version.trim().replace(/\\n/g, '')
|
version = version.trim().replace(/\\n/g, '')
|
||||||
|
|
||||||
// TODO: Use bash on windows, this may significantly improve performance. Still needs testing though
|
// TODO: Use bash on windows, this may significantly improve performance.
|
||||||
|
// Still needs testing though
|
||||||
log.info('Initializing git, this may take some time')
|
log.info('Initializing git, this may take some time')
|
||||||
|
|
||||||
await configDispatch('git', {
|
await configDispatch('git', {
|
||||||
args: ['init'],
|
args: ['init'],
|
||||||
cwd: dir,
|
cwd: absoluteInitDirectory,
|
||||||
shell: 'unix',
|
shell: 'unix',
|
||||||
})
|
})
|
||||||
|
|
||||||
await configDispatch('git', {
|
await configDispatch('git', {
|
||||||
args: ['init'],
|
args: ['init'],
|
||||||
cwd: dir,
|
cwd: absoluteInitDirectory,
|
||||||
shell: 'unix',
|
shell: 'unix',
|
||||||
})
|
})
|
||||||
|
|
||||||
await configDispatch('git', {
|
await configDispatch('git', {
|
||||||
args: ['checkout', '--orphan', version],
|
args: ['checkout', '--orphan', version],
|
||||||
cwd: dir,
|
cwd: absoluteInitDirectory,
|
||||||
shell: 'unix',
|
shell: 'unix',
|
||||||
})
|
})
|
||||||
|
|
||||||
await configDispatch('git', {
|
await configDispatch('git', {
|
||||||
args: ['add', '-f', '.'],
|
args: ['add', '-f', '.'],
|
||||||
cwd: dir,
|
cwd: absoluteInitDirectory,
|
||||||
shell: 'unix',
|
shell: 'unix',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -67,13 +68,13 @@ export const init = async (directory: Command | string): Promise<void> => {
|
||||||
|
|
||||||
await configDispatch('git', {
|
await configDispatch('git', {
|
||||||
args: ['commit', '-aqm', `"Firefox ${version}"`],
|
args: ['commit', '-aqm', `"Firefox ${version}"`],
|
||||||
cwd: dir,
|
cwd: absoluteInitDirectory,
|
||||||
shell: 'unix',
|
shell: 'unix',
|
||||||
})
|
})
|
||||||
|
|
||||||
await configDispatch('git', {
|
await configDispatch('git', {
|
||||||
args: ['checkout', '-b', config.name.toLowerCase().replace(/\s/g, '_')],
|
args: ['checkout', '-b', config.name.toLowerCase().replace(/\s/g, '_')],
|
||||||
cwd: dir,
|
cwd: absoluteInitDirectory,
|
||||||
shell: 'unix',
|
shell: 'unix',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
import { join } from 'path'
|
import { join } from 'node:path'
|
||||||
import { isValidLicense } from './license-check'
|
import { isValidLicense } from './license-check'
|
||||||
|
|
||||||
describe('isValidLicense', () => {
|
describe('isValidLicense', () => {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
import { readFile, writeFile } from 'fs/promises'
|
import { readFile, writeFile } from 'node:fs/promises'
|
||||||
import { join } from 'path'
|
import { join } from 'node:path'
|
||||||
|
|
||||||
import { SRC_DIR } from '../constants'
|
import { SRC_DIR } from '../constants'
|
||||||
import { walkDirectory } from '../utils/fs'
|
import { walkDirectory } from '../utils/fs'
|
||||||
import { Task, TaskList } from '../utils/taskList'
|
import { Task, TaskList } from '../utils/task-list'
|
||||||
|
|
||||||
const ignoredFiles = new RegExp('.*\\.(json|patch|md|jpeg|png|gif|tiff|ico)')
|
const ignoredFiles = new RegExp('.*\\.(json|patch|md|jpeg|png|gif|tiff|ico)')
|
||||||
const licenseIgnore = new RegExp('(//|#) Ignore license in this file', 'g')
|
const licenseIgnore = new RegExp('(//|#) Ignore license in this file', 'g')
|
||||||
|
@ -32,7 +32,7 @@ const fixableFiles = [
|
||||||
]
|
]
|
||||||
|
|
||||||
export async function isValidLicense(path: string): Promise<boolean> {
|
export async function isValidLicense(path: string): Promise<boolean> {
|
||||||
const file = (await readFile(path)).toString()
|
const file = await readFile(path, { encoding: 'utf8' })
|
||||||
const contents = file.split('\n')
|
const contents = file.split('\n')
|
||||||
|
|
||||||
// We need to grab the top 5 lines just in case there are newlines in the
|
// We need to grab the top 5 lines just in case there are newlines in the
|
||||||
|
@ -58,7 +58,8 @@ export function createTask(path: string, noFix: boolean): Task {
|
||||||
skip: () => ignoredFiles.test(path),
|
skip: () => ignoredFiles.test(path),
|
||||||
name: path.replace(SRC_DIR, ''),
|
name: path.replace(SRC_DIR, ''),
|
||||||
task: async () => {
|
task: async () => {
|
||||||
const contents = (await readFile(path)).toString().split('\n')
|
const contents = await readFile(path, { encoding: 'utf8' })
|
||||||
|
const contentsSplitNewline = contents.split('\n')
|
||||||
const hasLicense = await isValidLicense(path)
|
const hasLicense = await isValidLicense(path)
|
||||||
|
|
||||||
if (hasLicense) {
|
if (hasLicense) {
|
||||||
|
@ -73,11 +74,12 @@ export function createTask(path: string, noFix: boolean): Task {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const mpl = (
|
const mplHeader = // eslint-disable-next-line unicorn/prefer-module
|
||||||
await readFile(join(__dirname, 'license-check.txt'))
|
await readFile(join(__dirname, 'license-check.txt'), {
|
||||||
).toString()
|
encoding: 'utf8',
|
||||||
|
})
|
||||||
const { comment, commentOpen, commentClose } = fixable
|
const { comment, commentOpen, commentClose } = fixable
|
||||||
let header = mpl
|
let header = mplHeader
|
||||||
.split('\n')
|
.split('\n')
|
||||||
.map((ln) => (comment || '') + ln)
|
.map((ln) => (comment || '') + ln)
|
||||||
.join('\n')
|
.join('\n')
|
||||||
|
@ -86,7 +88,7 @@ export function createTask(path: string, noFix: boolean): Task {
|
||||||
header = commentOpen + header + commentClose
|
header = commentOpen + header + commentClose
|
||||||
}
|
}
|
||||||
|
|
||||||
await writeFile(path, header + '\n' + contents.join('\n'))
|
await writeFile(path, header + '\n' + contentsSplitNewline.join('\n'))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
import { existsSync } from 'fs'
|
import { existsSync } from 'node:fs'
|
||||||
import { copyFile, mkdir, readdir, unlink } from 'fs/promises'
|
import { copyFile, mkdir, readdir, unlink } from 'node:fs/promises'
|
||||||
import { join, resolve } from 'path'
|
import { join, resolve } from 'node:path'
|
||||||
|
|
||||||
import { bin_name, config } from '..'
|
import { bin_name, config } from '..'
|
||||||
import { DIST_DIR, ENGINE_DIR, OBJ_DIR } from '../constants'
|
import { DIST_DIR, ENGINE_DIR, OBJ_DIR } from '../constants'
|
||||||
|
@ -37,15 +37,15 @@ export const gluonPackage = async () => {
|
||||||
log.error(`Cannot locate the 'mach' binary within ${ENGINE_DIR}`)
|
log.error(`Cannot locate the 'mach' binary within ${ENGINE_DIR}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const args = ['package']
|
const arguments_ = ['package']
|
||||||
|
|
||||||
log.info(
|
log.info(
|
||||||
`Packaging \`${config.binaryName}\` with args ${JSON.stringify(
|
`Packaging \`${config.binaryName}\` with args ${JSON.stringify(
|
||||||
args.slice(1, 0)
|
arguments_.slice(1, 0)
|
||||||
)}...`
|
)}...`
|
||||||
)
|
)
|
||||||
|
|
||||||
await dispatch(machPath, args, ENGINE_DIR, true)
|
await dispatch(machPath, arguments_, ENGINE_DIR, true)
|
||||||
|
|
||||||
log.info('Copying results up')
|
log.info('Copying results up')
|
||||||
|
|
||||||
|
@ -53,31 +53,41 @@ export const gluonPackage = async () => {
|
||||||
if (!existsSync(DIST_DIR)) await mkdir(DIST_DIR, { recursive: true })
|
if (!existsSync(DIST_DIR)) await mkdir(DIST_DIR, { recursive: true })
|
||||||
|
|
||||||
log.debug('Indexing files to copy')
|
log.debug('Indexing files to copy')
|
||||||
const files = (await readdir(join(OBJ_DIR, 'dist'), { withFileTypes: true }))
|
const filesInMozillaDistrobution = await readdir(join(OBJ_DIR, 'dist'), {
|
||||||
|
withFileTypes: true,
|
||||||
|
})
|
||||||
|
const files = filesInMozillaDistrobution
|
||||||
.filter((entry) => entry.isFile())
|
.filter((entry) => entry.isFile())
|
||||||
.map((entry) => entry.name)
|
.map((entry) => entry.name)
|
||||||
|
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const destFile = join(DIST_DIR, file)
|
const destinationFile = join(DIST_DIR, file)
|
||||||
log.debug(`Copying ${file}`)
|
log.debug(`Copying ${file}`)
|
||||||
if (existsSync(destFile)) await unlink(destFile)
|
if (existsSync(destinationFile)) await unlink(destinationFile)
|
||||||
await copyFile(join(OBJ_DIR, 'dist', file), destFile)
|
await copyFile(join(OBJ_DIR, 'dist', file), destinationFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Windows has some special dist files that are available within the dist
|
// Windows has some special dist files that are available within the dist
|
||||||
// directory.
|
// directory.
|
||||||
if (process.platform == 'win32') {
|
if (process.platform == 'win32') {
|
||||||
const installerDistDirectory = join(OBJ_DIR, 'dist', 'install', 'sea')
|
const installerDistributionDirectory = join(
|
||||||
|
OBJ_DIR,
|
||||||
|
'dist',
|
||||||
|
'install',
|
||||||
|
'sea'
|
||||||
|
)
|
||||||
|
|
||||||
if (!existsSync(installerDistDirectory)) {
|
if (!existsSync(installerDistributionDirectory)) {
|
||||||
log.error(
|
log.error(
|
||||||
`Could not find windows installer files located at '${installerDistDirectory}'`
|
`Could not find windows installer files located at '${installerDistributionDirectory}'`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const windowsInstallerFiles = (
|
const installerDistributionDirectoryContents = await readdir(
|
||||||
await readdir(installerDistDirectory, { withFileTypes: true })
|
installerDistributionDirectory,
|
||||||
|
{ withFileTypes: true }
|
||||||
)
|
)
|
||||||
|
const windowsInstallerFiles = installerDistributionDirectoryContents
|
||||||
.filter((entry) => entry.isFile())
|
.filter((entry) => entry.isFile())
|
||||||
.map((entry) => entry.name)
|
.map((entry) => entry.name)
|
||||||
|
|
||||||
|
@ -96,10 +106,13 @@ export const gluonPackage = async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actually copy
|
// Actually copy
|
||||||
const destFile = join(DIST_DIR, newFileName)
|
const destinationFile = join(DIST_DIR, newFileName)
|
||||||
log.debug(`Copying ${file}`)
|
log.debug(`Copying ${file}`)
|
||||||
if (existsSync(destFile)) await unlink(destFile)
|
if (existsSync(destinationFile)) await unlink(destinationFile)
|
||||||
await copyFile(join(installerDistDirectory, file), destFile)
|
await copyFile(
|
||||||
|
join(installerDistributionDirectory, file),
|
||||||
|
destinationFile
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,18 +150,10 @@ async function createMarFile(version: string, channel: string) {
|
||||||
// On macos this should be
|
// On macos this should be
|
||||||
// <obj dir>/dist/${binaryName}/${brandFullName}.app and on everything else,
|
// <obj dir>/dist/${binaryName}/${brandFullName}.app and on everything else,
|
||||||
// the contents of the folder <obj dir>/dist/${binaryName}
|
// the contents of the folder <obj dir>/dist/${binaryName}
|
||||||
let binary: string
|
const binary =
|
||||||
|
process.platform == 'darwin'
|
||||||
if (process.platform == 'darwin') {
|
? join(OBJ_DIR, 'dist', config.binaryName, `${getCurrentBrandName()}.app`)
|
||||||
binary = join(
|
: join(OBJ_DIR, 'dist', config.binaryName)
|
||||||
OBJ_DIR,
|
|
||||||
'dist',
|
|
||||||
config.binaryName,
|
|
||||||
`${getCurrentBrandName()}.app`
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
binary = join(OBJ_DIR, 'dist', config.binaryName)
|
|
||||||
}
|
|
||||||
|
|
||||||
const marPath = windowsPathToUnix(join(DIST_DIR, 'output.mar'))
|
const marPath = windowsPathToUnix(join(DIST_DIR, 'output.mar'))
|
||||||
await configDispatch('./tools/update-packaging/make_full_update.sh', {
|
await configDispatch('./tools/update-packaging/make_full_update.sh', {
|
||||||
|
|
|
@ -10,10 +10,10 @@ import {
|
||||||
readFileSync,
|
readFileSync,
|
||||||
writeFileSync,
|
writeFileSync,
|
||||||
copyFileSync,
|
copyFileSync,
|
||||||
} from 'fs'
|
} from 'node:fs'
|
||||||
import { copyFile, readFile, rm, writeFile } from 'fs/promises'
|
import { copyFile, mkdir, readFile, rm, writeFile } from 'node:fs/promises'
|
||||||
import { every } from 'modern-async'
|
import { every } from 'modern-async'
|
||||||
import { dirname, extname, join } from 'path'
|
import { dirname, extname, join } from 'node:path'
|
||||||
import sharp from 'sharp'
|
import sharp from 'sharp'
|
||||||
import pngToIco from 'png-to-ico'
|
import pngToIco from 'png-to-ico'
|
||||||
import asyncIcns from 'async-icns'
|
import asyncIcns from 'async-icns'
|
||||||
|
@ -31,7 +31,7 @@ import {
|
||||||
walkDirectory,
|
walkDirectory,
|
||||||
windowsPathToUnix,
|
windowsPathToUnix,
|
||||||
} from '../../utils'
|
} from '../../utils'
|
||||||
import { templateDir } from '../setupProject'
|
import { templateDirectory } from '../setup-project'
|
||||||
import { IMelonPatch } from './command'
|
import { IMelonPatch } from './command'
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
@ -74,7 +74,7 @@ function constructConfig(name: string) {
|
||||||
brandingVendor: config.vendor,
|
brandingVendor: config.vendor,
|
||||||
|
|
||||||
...defaultBrandsConfig,
|
...defaultBrandsConfig,
|
||||||
...(config.brands[name] || {}),
|
...config.brands[name],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,15 +111,15 @@ async function setupImages(configPath: string, outputPath: string) {
|
||||||
// TODO: Custom MacOS icon support
|
// TODO: Custom MacOS icon support
|
||||||
if (process.platform == 'darwin') {
|
if (process.platform == 'darwin') {
|
||||||
log.debug('Generating Mac Icons')
|
log.debug('Generating Mac Icons')
|
||||||
const tmp = join(MELON_TMP_DIR, 'macos_icon_info.iconset')
|
const temporary = join(MELON_TMP_DIR, 'macos_icon_info.iconset')
|
||||||
|
|
||||||
if (existsSync(tmp)) await rm(tmp, { recursive: true })
|
if (existsSync(temporary)) await rm(temporary, { recursive: true })
|
||||||
|
|
||||||
asyncIcns.convert({
|
asyncIcns.convert({
|
||||||
input: join(configPath, 'logo.png'),
|
input: join(configPath, 'logo.png'),
|
||||||
output: join(outputPath, 'firefox.icns'),
|
output: join(outputPath, 'firefox.icns'),
|
||||||
sizes: [16, 32, 64, 128, 256, 512],
|
sizes: [16, 32, 64, 128, 256, 512],
|
||||||
tmpDirectory: tmp,
|
tmpDirectory: temporary,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,22 +155,32 @@ async function setupLocale(
|
||||||
brandingVendor: string
|
brandingVendor: string
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-extra-semi
|
for (const file of await walkDirectory(
|
||||||
;(await walkDirectory(join(templateDir, 'branding.optional')))
|
join(templateDirectory, 'branding.optional')
|
||||||
.map((file) =>
|
)) {
|
||||||
windowsPathToUnix(file).replace(
|
const fileContents = await readFile(windowsPathToUnix(file), {
|
||||||
windowsPathToUnix(join(templateDir, 'branding.optional') + '/'),
|
encoding: 'utf8',
|
||||||
''
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.map((file) => [
|
|
||||||
readFileSync(join(templateDir, 'branding.optional', file)).toString(),
|
|
||||||
join(outputPath, file),
|
|
||||||
])
|
|
||||||
.forEach(([contents, path]) => {
|
|
||||||
mkdirSync(dirname(path), { recursive: true })
|
|
||||||
writeFileSync(path, stringTemplate(contents, brandingConfig))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const universalPath =
|
||||||
|
// We want to avoid the pain that windows is going to throw at us with its
|
||||||
|
// weird paths
|
||||||
|
windowsPathToUnix(file)
|
||||||
|
// We want to remove all of the extra folders that surround this from the
|
||||||
|
// template folder
|
||||||
|
.replace(
|
||||||
|
windowsPathToUnix(join(templateDirectory, 'branding.optional') + '/'),
|
||||||
|
''
|
||||||
|
)
|
||||||
|
|
||||||
|
const sourceFolderPath = join(outputPath, universalPath)
|
||||||
|
|
||||||
|
await mkdir(dirname(sourceFolderPath), { recursive: true })
|
||||||
|
await writeFile(
|
||||||
|
sourceFolderPath,
|
||||||
|
stringTemplate(fileContents, brandingConfig)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function copyMozFiles(
|
async function copyMozFiles(
|
||||||
|
@ -184,7 +194,8 @@ async function copyMozFiles(
|
||||||
brandingVendor: string
|
brandingVendor: string
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
const files = (await walkDirectory(BRANDING_FF)).filter(
|
const firefoxBrandingDirectoryContents = await walkDirectory(BRANDING_FF)
|
||||||
|
const files = firefoxBrandingDirectoryContents.filter(
|
||||||
(file) => !existsSync(join(outputPath, file.replace(BRANDING_FF, '')))
|
(file) => !existsSync(join(outputPath, file.replace(BRANDING_FF, '')))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -192,7 +203,7 @@ async function copyMozFiles(
|
||||||
|
|
||||||
const everythingElse = files.filter((file) => !css.includes(file))
|
const everythingElse = files.filter((file) => !css.includes(file))
|
||||||
|
|
||||||
css
|
for (const [contents, path] of css
|
||||||
.map((filePath) => [
|
.map((filePath) => [
|
||||||
readFileSync(filePath).toString(),
|
readFileSync(filePath).toString(),
|
||||||
join(outputPath, filePath.replace(BRANDING_FF, '')),
|
join(outputPath, filePath.replace(BRANDING_FF, '')),
|
||||||
|
@ -201,17 +212,16 @@ async function copyMozFiles(
|
||||||
contents.replace(CSS_REPLACE_REGEX, 'var(--theme-bg)') +
|
contents.replace(CSS_REPLACE_REGEX, 'var(--theme-bg)') +
|
||||||
`:root { --theme-bg: ${brandingConfig.backgroundColor} }`,
|
`:root { --theme-bg: ${brandingConfig.backgroundColor} }`,
|
||||||
path,
|
path,
|
||||||
])
|
])) {
|
||||||
.forEach(([contents, path]) => {
|
mkdirSync(dirname(path), { recursive: true })
|
||||||
mkdirSync(dirname(path), { recursive: true })
|
writeFileSync(path, contents)
|
||||||
writeFileSync(path, contents)
|
}
|
||||||
})
|
|
||||||
|
|
||||||
// Copy everything else from the default firefox branding directory
|
// Copy everything else from the default firefox branding directory
|
||||||
everythingElse.forEach((file) => {
|
for (const file of everythingElse) {
|
||||||
mkdirpSync(dirname(join(outputPath, file.replace(BRANDING_FF, ''))))
|
mkdirpSync(dirname(join(outputPath, file.replace(BRANDING_FF, ''))))
|
||||||
copyFileSync(file, join(outputPath, file.replace(BRANDING_FF, '')))
|
copyFileSync(file, join(outputPath, file.replace(BRANDING_FF, '')))
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
|
@ -1,19 +1,19 @@
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
import { join } from 'path'
|
import { join } from 'node:path'
|
||||||
import { existsSync } from 'fs'
|
import { existsSync } from 'node:fs'
|
||||||
import glob from 'tiny-glob'
|
import glob from 'tiny-glob'
|
||||||
|
|
||||||
import { ENGINE_DIR, SRC_DIR } from '../../constants'
|
import { ENGINE_DIR, SRC_DIR } from '../../constants'
|
||||||
import * as gitPatch from './gitPatch'
|
import * as gitPatch from './git-patch'
|
||||||
import * as copyPatch from './copyPatches'
|
import * as copyPatch from './copy-patches'
|
||||||
import * as brandingPatch from './brandingPatch'
|
import * as brandingPatch from './branding-patch'
|
||||||
import { patchCountFile } from '../../middleware/patch-check'
|
import { patchCountFile } from '../../middleware/patch-check'
|
||||||
import { checkHash } from '../../utils'
|
import { checkHash } from '../../utils'
|
||||||
import { templateDir } from '../setupProject'
|
import { templateDirectory } from '../setup-project'
|
||||||
import { Task, TaskList } from '../../utils/taskList'
|
import { Task, TaskList } from '../../utils/task-list'
|
||||||
import { writeFile } from 'fs/promises'
|
import { writeFile } from 'node:fs/promises'
|
||||||
|
|
||||||
export interface IMelonPatch {
|
export interface IMelonPatch {
|
||||||
name: string
|
name: string
|
||||||
|
@ -23,7 +23,7 @@ export interface IMelonPatch {
|
||||||
function patchMethod<T extends IMelonPatch>(
|
function patchMethod<T extends IMelonPatch>(
|
||||||
name: string,
|
name: string,
|
||||||
patches: T[],
|
patches: T[],
|
||||||
patchFn: (patch: T, index: number) => Promise<void>
|
patchFunction: (patch: T, index: number) => Promise<void>
|
||||||
): Task {
|
): Task {
|
||||||
return {
|
return {
|
||||||
name: `Apply ${patches.length} ${name} patches`,
|
name: `Apply ${patches.length} ${name} patches`,
|
||||||
|
@ -32,7 +32,7 @@ function patchMethod<T extends IMelonPatch>(
|
||||||
new TaskList(
|
new TaskList(
|
||||||
patches.map((patch, index) => ({
|
patches.map((patch, index) => ({
|
||||||
name: `Apply ${patch.name}`,
|
name: `Apply ${patch.name}`,
|
||||||
task: () => patchFn(patch, index),
|
task: () => patchFunction(patch, index),
|
||||||
skip: patch.skip,
|
skip: patch.skip,
|
||||||
}))
|
}))
|
||||||
),
|
),
|
||||||
|
@ -80,12 +80,11 @@ async function importFolders(): Promise<Task> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function importGitPatch(): Promise<Task> {
|
async function importGitPatch(): Promise<Task> {
|
||||||
const patches = (
|
let patches = await glob('**/*.patch', {
|
||||||
await glob('**/*.patch', {
|
filesOnly: true,
|
||||||
filesOnly: true,
|
cwd: SRC_DIR,
|
||||||
cwd: SRC_DIR,
|
})
|
||||||
})
|
patches = patches.map((path) => join(SRC_DIR, path))
|
||||||
).map((path) => join(SRC_DIR, path))
|
|
||||||
|
|
||||||
await writeFile(patchCountFile, patches.length.toString())
|
await writeFile(patchCountFile, patches.length.toString())
|
||||||
|
|
||||||
|
@ -97,19 +96,18 @@ async function importGitPatch(): Promise<Task> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function importInternalPatch(): Promise<Task> {
|
async function importInternalPatch(): Promise<Task> {
|
||||||
const patches = (
|
const patches = await glob('*.patch', {
|
||||||
await glob('*.patch', {
|
filesOnly: true,
|
||||||
filesOnly: true,
|
cwd: join(templateDirectory, 'patches.optional'),
|
||||||
cwd: join(templateDir, 'patches.optional'),
|
})
|
||||||
})
|
const structuredPatches = patches.map((path) => ({
|
||||||
).map((path) => ({
|
|
||||||
name: path,
|
name: path,
|
||||||
path: join(templateDir, 'patches.optional', path),
|
path: join(templateDirectory, 'patches.optional', path),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
return patchMethod<gitPatch.IGitPatch>(
|
return patchMethod<gitPatch.IGitPatch>(
|
||||||
'gluon',
|
'gluon',
|
||||||
patches,
|
structuredPatches,
|
||||||
async (patch) => await gitPatch.apply(patch.path)
|
async (patch) => await gitPatch.apply(patch.path)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
import { existsSync } from 'fs'
|
import { existsSync } from 'node:fs'
|
||||||
import { lstatSync, readFileSync } from 'fs'
|
import { lstatSync, readFileSync } from 'node:fs'
|
||||||
import { ensureSymlink, remove } from 'fs-extra'
|
import { ensureSymlink, remove } from 'fs-extra'
|
||||||
import { copyFile } from 'fs/promises'
|
import { copyFile } from 'node:fs/promises'
|
||||||
import { dirname, resolve } from 'path'
|
import { dirname, resolve } from 'node:path'
|
||||||
import glob from 'tiny-glob'
|
import glob from 'tiny-glob'
|
||||||
|
|
||||||
import { appendToFileSync, mkdirp } from '../../utils'
|
import { appendToFileSync, mkdirp } from '../../utils'
|
||||||
|
@ -70,21 +70,20 @@ export interface ICopyPatch extends IMelonPatch {
|
||||||
// Exports
|
// Exports
|
||||||
|
|
||||||
export async function get(): Promise<ICopyPatch[]> {
|
export async function get(): Promise<ICopyPatch[]> {
|
||||||
const files = (
|
const allFilesInSource = await glob('**/*', {
|
||||||
await glob('**/*', {
|
filesOnly: true,
|
||||||
filesOnly: true,
|
cwd: SRC_DIR,
|
||||||
cwd: SRC_DIR,
|
})
|
||||||
})
|
const files = allFilesInSource.filter(
|
||||||
).filter(
|
|
||||||
(f) => !(f.endsWith('.patch') || f.split('/').includes('node_modules'))
|
(f) => !(f.endsWith('.patch') || f.split('/').includes('node_modules'))
|
||||||
)
|
)
|
||||||
|
|
||||||
const manualPatches: ICopyPatch[] = []
|
const manualPatches: ICopyPatch[] = []
|
||||||
|
|
||||||
files.map((i) => {
|
files.map((index) => {
|
||||||
const group = i.split('/')[0]
|
const group = index.split('/')[0]
|
||||||
|
|
||||||
if (!manualPatches.find((m) => m.name == group)) {
|
if (!manualPatches.some((m) => m.name == group)) {
|
||||||
manualPatches.push({
|
manualPatches.push({
|
||||||
name: group,
|
name: group,
|
||||||
src: files.filter((f) => f.split('/')[0] == group),
|
src: files.filter((f) => f.split('/')[0] == group),
|
||||||
|
@ -95,8 +94,8 @@ export async function get(): Promise<ICopyPatch[]> {
|
||||||
return manualPatches
|
return manualPatches
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function apply(src: string[]): Promise<void> {
|
export async function apply(source: string[]): Promise<void> {
|
||||||
for (const item of src) {
|
for (const item of source) {
|
||||||
await copyManual(item)
|
await copyManual(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,8 +1,10 @@
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
import execa from 'execa'
|
import execa from 'execa'
|
||||||
import { PATCH_ARGS, ENGINE_DIR } from '../../constants'
|
import { PATCH_ARGS, ENGINE_DIR } from '../../constants'
|
||||||
|
import { log } from '../../log'
|
||||||
import { IMelonPatch } from './command'
|
import { IMelonPatch } from './command'
|
||||||
|
|
||||||
export interface IGitPatch extends IMelonPatch {
|
export interface IGitPatch extends IMelonPatch {
|
||||||
|
@ -14,11 +16,11 @@ export async function apply(path: string): Promise<void> {
|
||||||
await execa('git', ['apply', '-R', ...PATCH_ARGS, path], {
|
await execa('git', ['apply', '-R', ...PATCH_ARGS, path], {
|
||||||
cwd: ENGINE_DIR,
|
cwd: ENGINE_DIR,
|
||||||
})
|
})
|
||||||
} catch (_e) {
|
} catch {
|
||||||
// If the patch has already been applied, we want to revert it. Because
|
// If the patch has already been applied, we want to revert it. Because
|
||||||
// there is no good way to check this we are just going to catch and
|
// there is no good way to check this we are just going to catch and
|
||||||
// discard the error
|
// discard the error
|
||||||
null
|
undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
const { stdout, exitCode } = await execa(
|
const { stdout, exitCode } = await execa(
|
||||||
|
@ -27,5 +29,5 @@ export async function apply(path: string): Promise<void> {
|
||||||
{ cwd: ENGINE_DIR }
|
{ cwd: ENGINE_DIR }
|
||||||
)
|
)
|
||||||
|
|
||||||
if (exitCode != 0) throw stdout
|
if (exitCode != 0) log.error(stdout)
|
||||||
}
|
}
|
|
@ -1,27 +1,29 @@
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
import { existsSync, readdirSync } from 'fs'
|
import { existsSync, readdirSync } from 'node:fs'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'node:path'
|
||||||
import { bin_name } from '..'
|
import { bin_name } from '..'
|
||||||
import { ENGINE_DIR } from '../constants'
|
import { ENGINE_DIR } from '../constants'
|
||||||
import { log } from '../log'
|
import { log } from '../log'
|
||||||
import { config, dispatch } from '../utils'
|
import { config, dispatch } from '../utils'
|
||||||
|
|
||||||
export const run = async (chrome?: string) => {
|
export const run = async (chrome?: string) => {
|
||||||
const dirs = readdirSync(ENGINE_DIR)
|
const directories = readdirSync(ENGINE_DIR)
|
||||||
const objDirname = dirs.find((dir) => dir.startsWith('obj-'))
|
const objectDirname = directories.find((directory) =>
|
||||||
|
directory.startsWith('obj-')
|
||||||
|
)
|
||||||
|
|
||||||
if (!objDirname) {
|
if (!objectDirname) {
|
||||||
throw new Error(`${config.name} needs to be built before you can do this.`)
|
throw new Error(`${config.name} needs to be built before you can do this.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const objDir = resolve(ENGINE_DIR, objDirname)
|
const objectDirectory = resolve(ENGINE_DIR, objectDirname)
|
||||||
|
|
||||||
if (existsSync(objDir)) {
|
if (existsSync(objectDirectory)) {
|
||||||
dispatch(
|
dispatch(
|
||||||
'./mach',
|
'./mach',
|
||||||
['run'].concat(chrome ? ['-chrome', chrome] : []),
|
['run', ...(chrome ? ['-chrome', chrome] : [])],
|
||||||
ENGINE_DIR,
|
ENGINE_DIR,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
import { writeFileSync, existsSync, mkdirSync, readFileSync } from 'fs'
|
import { writeFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs'
|
||||||
import { copyFile } from 'fs/promises'
|
import { copyFile } from 'node:fs/promises'
|
||||||
import { join, dirname } from 'path'
|
import { join, dirname } from 'node:path'
|
||||||
|
|
||||||
import prompts from 'prompts'
|
import prompts from 'prompts'
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ import {
|
||||||
configPath,
|
configPath,
|
||||||
delay,
|
delay,
|
||||||
getLatestFF,
|
getLatestFF,
|
||||||
projectDir,
|
projectDirectory,
|
||||||
SupportedProducts,
|
SupportedProducts,
|
||||||
walkDirectory,
|
walkDirectory,
|
||||||
} from '../utils'
|
} from '../utils'
|
||||||
|
@ -48,7 +48,7 @@ export async function setupProject(): Promise<void> {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Firefox developer edition (Not recommended)',
|
title: 'Firefox developer edition (Not recommended)',
|
||||||
value: SupportedProducts.FirefoxDev,
|
value: SupportedProducts.FirefoxDevelopment,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Firefox beta (Not recommended)',
|
title: 'Firefox beta (Not recommended)',
|
||||||
|
@ -136,10 +136,10 @@ export async function setupProject(): Promise<void> {
|
||||||
await copyOptional(['browser/themes'])
|
await copyOptional(['browser/themes'])
|
||||||
}
|
}
|
||||||
|
|
||||||
writeFileSync(configPath, JSON.stringify(config, null, 2))
|
writeFileSync(configPath, JSON.stringify(config, undefined, 2))
|
||||||
|
|
||||||
// Append important stuff to gitignore
|
// Append important stuff to gitignore
|
||||||
const gitignore = join(projectDir, '.gitignore')
|
const gitignore = join(projectDirectory, '.gitignore')
|
||||||
let gitignoreContents = ''
|
let gitignoreContents = ''
|
||||||
|
|
||||||
if (existsSync(gitignore)) {
|
if (existsSync(gitignore)) {
|
||||||
|
@ -149,48 +149,64 @@ export async function setupProject(): Promise<void> {
|
||||||
gitignoreContents += '\n.dotbuild/\nengine/\nfirefox-*/\nnode_modules/\n'
|
gitignoreContents += '\n.dotbuild/\nengine/\nfirefox-*/\nnode_modules/\n'
|
||||||
|
|
||||||
writeFileSync(gitignore, gitignoreContents)
|
writeFileSync(gitignore, gitignoreContents)
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
console.log(e)
|
console.log(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Filesystem templating
|
// Filesystem templating
|
||||||
|
|
||||||
export const templateDir = join(__dirname, '../..', 'template')
|
// eslint-disable-next-line unicorn/prefer-module
|
||||||
|
export const templateDirectory = join(__dirname, '../..', 'template')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy files from the template directory that have .optional in their path,
|
||||||
|
* based on the function parameters
|
||||||
|
*
|
||||||
|
* @param files The files that should be coppied
|
||||||
|
*/
|
||||||
async function copyOptional(files: string[]) {
|
async function copyOptional(files: string[]) {
|
||||||
await Promise.all(
|
const directoryContents = await walkDirectory(templateDirectory)
|
||||||
(
|
|
||||||
await walkDirectory(templateDir)
|
for (const file of directoryContents) {
|
||||||
|
if (
|
||||||
|
!file.includes('.optional') &&
|
||||||
|
!files
|
||||||
|
.map((induvidualFile) => file.includes(induvidualFile))
|
||||||
|
.some(Boolean)
|
||||||
)
|
)
|
||||||
.filter((f) => f.includes('.optional'))
|
continue
|
||||||
.filter((f) => files.map((file) => f.includes(file)).some((b) => b))
|
|
||||||
.map(async (file) => {
|
const outLocation = join(
|
||||||
const out = join(projectDir, file.replace(templateDir, '')).replace(
|
projectDirectory,
|
||||||
'.optional',
|
file.replace(templateDirectory, '')
|
||||||
''
|
).replace('.optional', '')
|
||||||
)
|
|
||||||
if (!existsSync(out)) {
|
if (!existsSync(outLocation)) {
|
||||||
mkdirSync(dirname(out), { recursive: true })
|
mkdirSync(dirname(outLocation), { recursive: true })
|
||||||
await copyFile(file, out)
|
await copyFile(file, outLocation)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy all non-optional files from the template directory
|
||||||
|
*/
|
||||||
async function copyRequired() {
|
async function copyRequired() {
|
||||||
await Promise.all(
|
const directoryContents = await walkDirectory(templateDirectory)
|
||||||
(
|
|
||||||
await walkDirectory(templateDir)
|
for (const file of directoryContents) {
|
||||||
|
if (file.includes('.optional')) continue
|
||||||
|
|
||||||
|
const outLocation = join(
|
||||||
|
projectDirectory,
|
||||||
|
file.replace(templateDirectory, '')
|
||||||
)
|
)
|
||||||
.filter((f) => !f.includes('.optional'))
|
|
||||||
.map(async (file) => {
|
if (!existsSync(outLocation)) {
|
||||||
const out = join(projectDir, file.replace(templateDir, ''))
|
mkdirSync(dirname(outLocation), { recursive: true })
|
||||||
if (!existsSync(out)) {
|
await copyFile(file, outLocation)
|
||||||
mkdirSync(dirname(out), { recursive: true })
|
}
|
||||||
await copyFile(file, out)
|
}
|
||||||
}
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
import { existsSync } from 'fs'
|
import { existsSync } from 'node:fs'
|
||||||
import { log } from '../log'
|
import { log } from '../log'
|
||||||
import { BIN_NAME, ENGINE_DIR } from '../constants'
|
import { BIN_NAME, ENGINE_DIR } from '../constants'
|
||||||
import { dispatch, hasConfig } from '../utils'
|
import { dispatch, hasConfig } from '../utils'
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
import { stat, writeFile } from 'fs/promises'
|
import { writeFile } from 'node:fs/promises'
|
||||||
import { dirname, join } from 'path'
|
import { dirname, join } from 'node:path'
|
||||||
import { create } from 'xmlbuilder2'
|
import { create } from 'xmlbuilder2'
|
||||||
import { DIST_DIR } from '../../constants'
|
import { DIST_DIR } from '../../constants'
|
||||||
import { dynamicConfig, ensureDir, generateHash, getSize } from '../../utils'
|
import {
|
||||||
|
dynamicConfig,
|
||||||
|
ensureDirectory,
|
||||||
|
generateHash,
|
||||||
|
getSize,
|
||||||
|
} from '../../utils'
|
||||||
import {
|
import {
|
||||||
downloadAddon,
|
downloadAddon,
|
||||||
getAddons,
|
getAddons,
|
||||||
|
@ -45,6 +50,6 @@ export async function generateAddonUpdateFiles() {
|
||||||
'update.xml'
|
'update.xml'
|
||||||
)
|
)
|
||||||
|
|
||||||
await ensureDir(dirname(path))
|
await ensureDirectory(dirname(path))
|
||||||
await writeFile(path, root.end({ prettyPrint: true }))
|
await writeFile(path, root.end({ prettyPrint: true }))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { existsSync } from 'fs'
|
import { existsSync } from 'node:fs'
|
||||||
import { readFile, writeFile } from 'fs/promises'
|
import { readFile, writeFile } from 'node:fs/promises'
|
||||||
import { parse } from 'ini'
|
import { parse } from 'ini'
|
||||||
import { isAppleSilicon } from 'is-apple-silicon'
|
import { isAppleSilicon } from 'is-apple-silicon'
|
||||||
import { dirname, join } from 'path'
|
import { dirname, join } from 'node:path'
|
||||||
import { create } from 'xmlbuilder2'
|
import { create } from 'xmlbuilder2'
|
||||||
import { bin_name, config } from '../..'
|
import { bin_name, config } from '../..'
|
||||||
import { DIST_DIR, OBJ_DIR } from '../../constants'
|
import { DIST_DIR, OBJ_DIR } from '../../constants'
|
||||||
|
@ -41,7 +41,8 @@ export async function getPlatformConfig() {
|
||||||
if (!existsSync(platformINI))
|
if (!existsSync(platformINI))
|
||||||
platformINI = join(OBJ_DIR, 'dist', 'bin', 'platform.ini')
|
platformINI = join(OBJ_DIR, 'dist', 'bin', 'platform.ini')
|
||||||
|
|
||||||
return parse((await readFile(platformINI)).toString())
|
const iniContents = await readFile(platformINI)
|
||||||
|
return parse(iniContents.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
function getReleaseMarName(releaseInfo: ReleaseInfo): string | undefined {
|
function getReleaseMarName(releaseInfo: ReleaseInfo): string | undefined {
|
||||||
|
@ -52,12 +53,15 @@ function getReleaseMarName(releaseInfo: ReleaseInfo): string | undefined {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (process.platform) {
|
switch (process.platform) {
|
||||||
case 'win32':
|
case 'win32': {
|
||||||
return releaseInfo.x86?.windowsMar
|
return releaseInfo.x86?.windowsMar
|
||||||
case 'darwin':
|
}
|
||||||
|
case 'darwin': {
|
||||||
return releaseInfo.x86?.macosMar
|
return releaseInfo.x86?.macosMar
|
||||||
case 'linux':
|
}
|
||||||
|
case 'linux': {
|
||||||
return releaseInfo.x86?.linuxMar
|
return releaseInfo.x86?.linuxMar
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +88,7 @@ async function writeUpdateFileToDisk(
|
||||||
channel: string,
|
channel: string,
|
||||||
updateObject: {
|
updateObject: {
|
||||||
updates: {
|
updates: {
|
||||||
update: Record<string, any>
|
update: Record<string, string | undefined>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
import execa from 'execa'
|
import execa from 'execa'
|
||||||
import { existsSync, mkdirSync, readdirSync } from 'fs'
|
import { existsSync, mkdirSync, readdirSync } from 'node:fs'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'node:path'
|
||||||
import { log } from '../log'
|
import { log } from '../log'
|
||||||
|
|
||||||
export const BIN_NAME = 'gluon'
|
export const BIN_NAME = 'gluon'
|
||||||
|
@ -63,13 +63,13 @@ export const OBJ_DIR = resolve(ENGINE_DIR, `obj-${CONFIG_GUESS}`)
|
||||||
|
|
||||||
// TODO: Remove this, it is unused
|
// TODO: Remove this, it is unused
|
||||||
export const FTL_STRING_LINE_REGEX =
|
export const FTL_STRING_LINE_REGEX =
|
||||||
/(([a-zA-Z0-9-]*|\.[a-z-]*) =(.*|\.)|\[[a-zA-Z0-9]*\].*(\n\s?\s?})?|\*\[[a-zA-Z0-9]*\] .*(\n\s?\s?})?)/gm
|
/(([\dA-Za-z-]*|\.[a-z-]*) =(.*|\.)|\[[\dA-Za-z]*].*(\n\s?\s?})?|\*\[[\dA-Za-z]*] .*(\n\s?\s?})?)/gm
|
||||||
|
|
||||||
// =================
|
// =================
|
||||||
// Windows constants
|
// Windows constants
|
||||||
// =================
|
// =================
|
||||||
|
|
||||||
export let BASH_PATH: string | null = null
|
export let BASH_PATH: string | undefined
|
||||||
|
|
||||||
// All windows specific code should be located inside of this if statement
|
// All windows specific code should be located inside of this if statement
|
||||||
if (process.platform == 'win32') {
|
if (process.platform == 'win32') {
|
||||||
|
|
|
@ -3,14 +3,7 @@ import { config } from '..'
|
||||||
const otherBuildModes = `# You can change to other build modes by running:
|
const otherBuildModes = `# You can change to other build modes by running:
|
||||||
# $ gluon set buildMode [dev|debug|release]`
|
# $ gluon set buildMode [dev|debug|release]`
|
||||||
|
|
||||||
const platformOptimize =
|
const platformOptimize = getPlatformOptimiseFlags()
|
||||||
process.platform == 'darwin'
|
|
||||||
? 'ac_add_options --enable-optimize="-O3 -march=nehalem -mtune=haswell -w"'
|
|
||||||
: process.platform == 'linux'
|
|
||||||
? 'ac_add_options --enable-optimize="-O3 -march=haswell -mtune=haswell -w"'
|
|
||||||
: process.platform == 'win32'
|
|
||||||
? 'ac_add_options --enable-optimize="-O2 -Qvec -w -clang:-ftree-vectorize -clang:-msse3 -clang:-mssse3 -clang:-msse4.1 -clang:-mtune=haswell"'
|
|
||||||
: `# Unknown platform ${process.platform}`
|
|
||||||
|
|
||||||
export const internalMozconfg = (
|
export const internalMozconfg = (
|
||||||
brand: string,
|
brand: string,
|
||||||
|
@ -20,24 +13,27 @@ export const internalMozconfg = (
|
||||||
|
|
||||||
// Get the specific build options for the current build mode
|
// Get the specific build options for the current build mode
|
||||||
switch (buildMode) {
|
switch (buildMode) {
|
||||||
case 'dev':
|
case 'dev': {
|
||||||
buildOptions = `# Development build settings
|
buildOptions = `# Development build settings
|
||||||
${otherBuildModes}
|
${otherBuildModes}
|
||||||
ac_add_options --disable-debug`
|
ac_add_options --disable-debug`
|
||||||
break
|
break
|
||||||
case 'debug':
|
}
|
||||||
|
case 'debug': {
|
||||||
buildOptions = `# Debug build settings
|
buildOptions = `# Debug build settings
|
||||||
${otherBuildModes}
|
${otherBuildModes}
|
||||||
ac_add_options --enable-debug
|
ac_add_options --enable-debug
|
||||||
ac_add_options --disable-optimize`
|
ac_add_options --disable-optimize`
|
||||||
break
|
break
|
||||||
|
}
|
||||||
|
|
||||||
case 'release':
|
case 'release': {
|
||||||
buildOptions = `# Release build settings
|
buildOptions = `# Release build settings
|
||||||
ac_add_options --disable-debug
|
ac_add_options --disable-debug
|
||||||
ac_add_options --enable-optimize
|
ac_add_options --enable-optimize
|
||||||
${platformOptimize} # Taken from waterfox`
|
${platformOptimize} # Taken from waterfox`
|
||||||
break
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return `
|
return `
|
||||||
|
@ -61,3 +57,24 @@ export MOZ_APPUPDATE_HOST=${
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getPlatformOptimiseFlags(): string {
|
||||||
|
let optimiseFlags = `# Unknown platform ${process.platform}`
|
||||||
|
|
||||||
|
switch (process.platform) {
|
||||||
|
case 'linux': {
|
||||||
|
optimiseFlags = `ac_add_options --enable-optimize="-O3 -march=haswell -mtune=haswell -w"`
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'darwin': {
|
||||||
|
optimiseFlags = `ac_add_options --enable-optimize="-O3 -march=nehalem -mtune=haswell -w"`
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'win32': {
|
||||||
|
optimiseFlags = `ac_add_options --enable-optimize="-O2 -Qvec -w -clang:-ftree-vectorize -clang:-msse3 -clang:-mssse3 -clang:-msse4.1 -clang:-mtune=haswell"`
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return optimiseFlags
|
||||||
|
}
|
||||||
|
|
35
src/index.ts
35
src/index.ts
|
@ -4,19 +4,19 @@
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
import commander, { Command } from 'commander'
|
import commander, { Command } from 'commander'
|
||||||
import { existsSync, readFileSync } from 'fs'
|
import { existsSync, readFileSync } from 'node:fs'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'node:path'
|
||||||
|
|
||||||
import { errorHandler, config as configInited, versionFormatter } from './utils'
|
import { errorHandler, config as configInited, versionFormatter } from './utils'
|
||||||
import { commands } from './cmds'
|
import { commands } from './cmds'
|
||||||
import { BIN_NAME, ENGINE_DIR } from './constants'
|
import { BIN_NAME, ENGINE_DIR } from './constants'
|
||||||
import { updateCheck } from './middleware/update-check'
|
import { updateCheck } from './middleware/update-check'
|
||||||
import { registerCommand } from './middleware/registerCommand'
|
import { registerCommand } from './middleware/register-command'
|
||||||
import { log } from './log'
|
import { log } from './log'
|
||||||
|
|
||||||
// We have to use a dynamic require here, otherwise the typescript compiler
|
// We have to use a dynamic require here, otherwise the typescript compiler
|
||||||
// mucks up the directory structure
|
// mucks up the directory structure
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires, unicorn/prefer-module
|
||||||
const { version: gluonVersion } = require('../package.json')
|
const { version: gluonVersion } = require('../package.json')
|
||||||
|
|
||||||
export const config = configInited
|
export const config = configInited
|
||||||
|
@ -76,14 +76,13 @@ async function middleware(command: commander.Command) {
|
||||||
registerCommand(command.name())
|
registerCommand(command.name())
|
||||||
}
|
}
|
||||||
|
|
||||||
commands.forEach((command) => {
|
for (const command of commands) {
|
||||||
if (command.flags) {
|
if (
|
||||||
if (
|
command.flags &&
|
||||||
command.flags.platforms &&
|
command.flags.platforms &&
|
||||||
!command.flags.platforms.includes(process.platform)
|
!command.flags.platforms.includes(process.platform)
|
||||||
) {
|
) {
|
||||||
return
|
continue
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let buildCommand = program
|
let buildCommand = program
|
||||||
|
@ -92,11 +91,11 @@ commands.forEach((command) => {
|
||||||
.aliases(command?.aliases || [])
|
.aliases(command?.aliases || [])
|
||||||
|
|
||||||
// Register all of the required options
|
// Register all of the required options
|
||||||
command?.options?.forEach((opt) => {
|
for (const opt of command?.options || []) {
|
||||||
buildCommand = buildCommand.option(opt.arg, opt.description)
|
buildCommand = buildCommand.option(opt.arg, opt.description)
|
||||||
})
|
}
|
||||||
|
|
||||||
buildCommand = buildCommand.action(async (...args) => {
|
buildCommand = buildCommand.action(async (...arguments_) => {
|
||||||
// Start loading the controller in the background whilst middleware is
|
// Start loading the controller in the background whilst middleware is
|
||||||
// executing
|
// executing
|
||||||
const controller = command.requestController()
|
const controller = command.requestController()
|
||||||
|
@ -107,12 +106,12 @@ commands.forEach((command) => {
|
||||||
|
|
||||||
// Finish loading the controller and execute it
|
// Finish loading the controller and execute it
|
||||||
// eslint-disable-next-line @typescript-eslint/no-extra-semi
|
// eslint-disable-next-line @typescript-eslint/no-extra-semi
|
||||||
;(await controller)(...args)
|
;(await controller)(...arguments_)
|
||||||
})
|
})
|
||||||
})
|
}
|
||||||
|
|
||||||
process
|
process
|
||||||
.on('uncaughtException', errorHandler)
|
.on('uncaughtException', errorHandler)
|
||||||
.on('unhandledException', (err) => errorHandler(err, true))
|
.on('unhandledException', (error) => errorHandler(error, true))
|
||||||
|
|
||||||
program.parse(process.argv)
|
program.parse(process.argv)
|
||||||
|
|
48
src/log.ts
48
src/log.ts
|
@ -4,6 +4,9 @@
|
||||||
import chalk from 'chalk'
|
import chalk from 'chalk'
|
||||||
import prompts from 'prompts'
|
import prompts from 'prompts'
|
||||||
|
|
||||||
|
const formatToDoubleDigit = (r: number) =>
|
||||||
|
r.toString().length == 1 ? `0${r}` : r
|
||||||
|
|
||||||
class Log {
|
class Log {
|
||||||
private startTime: number
|
private startTime: number
|
||||||
|
|
||||||
|
@ -26,15 +29,15 @@ class Log {
|
||||||
const mins = Math.floor((elapsedTime / (60 * 1000)) % 60)
|
const mins = Math.floor((elapsedTime / (60 * 1000)) % 60)
|
||||||
const hours = Math.floor((elapsedTime / (60 * 60 * 1000)) % 24)
|
const hours = Math.floor((elapsedTime / (60 * 60 * 1000)) % 24)
|
||||||
|
|
||||||
const format = (r: number) => (r.toString().length == 1 ? `0${r}` : r)
|
return `${formatToDoubleDigit(hours)}:${formatToDoubleDigit(
|
||||||
|
mins
|
||||||
return `${format(hours)}:${format(mins)}:${format(secs)}`
|
)}:${formatToDoubleDigit(secs)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
set isDebug(val: boolean) {
|
set isDebug(value: boolean) {
|
||||||
log.debug(`Logger debug mode has been ${val ? 'enabled' : 'disabled'}`)
|
log.debug(`Logger debug mode has been ${value ? 'enabled' : 'disabled'}`)
|
||||||
this._isDebug = val
|
this._isDebug = value
|
||||||
log.debug(`Logger debug mode has been ${val ? 'enabled' : 'disabled'}`)
|
log.debug(`Logger debug mode has been ${value ? 'enabled' : 'disabled'}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
get isDebug() {
|
get isDebug() {
|
||||||
|
@ -46,8 +49,8 @@ class Log {
|
||||||
*
|
*
|
||||||
* @param args The information you want to provide to the user
|
* @param args The information you want to provide to the user
|
||||||
*/
|
*/
|
||||||
debug(...args: unknown[]): void {
|
debug(...arguments_: unknown[]): void {
|
||||||
if (this.isDebug) console.debug(...args)
|
if (this.isDebug) console.debug(...arguments_)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,8 +60,8 @@ class Log {
|
||||||
*
|
*
|
||||||
* @param args The information you want to provide to the user
|
* @param args The information you want to provide to the user
|
||||||
*/
|
*/
|
||||||
info(...args: unknown[]): void {
|
info(...arguments_: unknown[]): void {
|
||||||
console.info(chalk.blueBright.bold(this.getDiff()), ...args)
|
console.info(chalk.blueBright.bold(this.getDiff()), ...arguments_)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,8 +71,8 @@ class Log {
|
||||||
*
|
*
|
||||||
* @param args The information you want to provide to the user
|
* @param args The information you want to provide to the user
|
||||||
*/
|
*/
|
||||||
warning(...args: unknown[]): void {
|
warning(...arguments_: unknown[]): void {
|
||||||
console.warn(chalk.yellowBright.bold(' WARNING'), ...args)
|
console.warn(chalk.yellowBright.bold(' WARNING'), ...arguments_)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,8 +81,8 @@ class Log {
|
||||||
*
|
*
|
||||||
* @param args The information you want to provide to the user
|
* @param args The information you want to provide to the user
|
||||||
*/
|
*/
|
||||||
async hardWarning(...args: unknown[]): Promise<void> {
|
async hardWarning(...arguments_: unknown[]): Promise<void> {
|
||||||
console.info('', chalk.bgRed.bold('WARNING'), ...args)
|
console.info('', chalk.bgRed.bold('WARNING'), ...arguments_)
|
||||||
|
|
||||||
const { answer } = await prompts({
|
const { answer } = await prompts({
|
||||||
type: 'confirm',
|
type: 'confirm',
|
||||||
|
@ -95,9 +98,12 @@ class Log {
|
||||||
*
|
*
|
||||||
* @param args The information you want to provide to the user
|
* @param args The information you want to provide to the user
|
||||||
*/
|
*/
|
||||||
success(...args: unknown[]): void {
|
success(...arguments_: unknown[]): void {
|
||||||
console.log()
|
console.log()
|
||||||
console.log(`\n${chalk.greenBright.bold('SUCCESS')}`, args.join('\n\t'))
|
console.log(
|
||||||
|
`\n${chalk.greenBright.bold('SUCCESS')}`,
|
||||||
|
arguments_.join('\n\t')
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -105,11 +111,11 @@ class Log {
|
||||||
*
|
*
|
||||||
* @param args The error you want to throw or a type that you want to convert to an error
|
* @param args The error you want to throw or a type that you want to convert to an error
|
||||||
*/
|
*/
|
||||||
error(...args: (Error | unknown)[]): never {
|
error(...arguments_: (Error | unknown)[]): never {
|
||||||
throw args[0] instanceof Error
|
throw arguments_[0] instanceof Error
|
||||||
? args[0]
|
? arguments_[0]
|
||||||
: new Error(
|
: new Error(
|
||||||
...args.map((a) =>
|
...arguments_.map((a) =>
|
||||||
typeof a !== 'undefined' ? (a as object).toString() : a
|
typeof a !== 'undefined' ? (a as object).toString() : a
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
* Responsible for checking if all new patches have been applied
|
* Responsible for checking if all new patches have been applied
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { existsSync, readFileSync, writeFileSync } from 'fs'
|
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'node:path'
|
||||||
import { log } from '../log'
|
import { log } from '../log'
|
||||||
import { MELON_DIR, SRC_DIR } from '../constants'
|
import { MELON_DIR, SRC_DIR } from '../constants'
|
||||||
import { walkDirectory } from '../utils'
|
import { walkDirectory } from '../utils'
|
||||||
|
@ -14,14 +14,12 @@ import { walkDirectory } from '../utils'
|
||||||
export const patchCountFile = resolve(MELON_DIR, 'patchCount')
|
export const patchCountFile = resolve(MELON_DIR, 'patchCount')
|
||||||
|
|
||||||
export const patchCheck = async (): Promise<void> => {
|
export const patchCheck = async (): Promise<void> => {
|
||||||
const fileList = (await walkDirectory(resolve(SRC_DIR))).filter((file) =>
|
const directoryCotnents = await walkDirectory(resolve(SRC_DIR))
|
||||||
file.endsWith('.patch')
|
|
||||||
)
|
const fileList = directoryCotnents.filter((file) => file.endsWith('.patch'))
|
||||||
const patchCount = fileList.length
|
const patchCount = fileList.length
|
||||||
|
|
||||||
if (!existsSync(patchCountFile)) {
|
if (!existsSync(patchCountFile)) writeFileSync(patchCountFile, '0')
|
||||||
writeFileSync(patchCountFile, '0')
|
|
||||||
}
|
|
||||||
|
|
||||||
const recordedPatchCount = Number(readFileSync(patchCountFile).toString())
|
const recordedPatchCount = Number(readFileSync(patchCountFile).toString())
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
import { writeFileSync } from 'fs'
|
import { writeFileSync } from 'node:fs'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'node:path'
|
||||||
import { MELON_DIR } from '../constants'
|
import { MELON_DIR } from '../constants'
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -15,9 +15,9 @@ export const updateCheck = async (): Promise<void> => {
|
||||||
log.warning(
|
log.warning(
|
||||||
`Latest version of Firefox (${version}) does not match frozen version (${firefoxVersion}).`
|
`Latest version of Firefox (${version}) does not match frozen version (${firefoxVersion}).`
|
||||||
)
|
)
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
log.warning(`Failed to check for updates.`)
|
log.warning(`Failed to check for updates.`)
|
||||||
log.askForReport()
|
log.askForReport()
|
||||||
log.error(e)
|
log.error(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
2
src/types.d.ts
vendored
2
src/types.d.ts
vendored
|
@ -11,7 +11,7 @@ export interface Cmd {
|
||||||
* writing, is getting a touch long
|
* writing, is getting a touch long
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
requestController: () => Promise<(...args: any) => void>
|
requestController: () => Promise<(...arguments_: any) => void>
|
||||||
|
|
||||||
options?: CmdOption[]
|
options?: CmdOption[]
|
||||||
aliases?: string[]
|
aliases?: string[]
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
import { readFile } from 'fs/promises'
|
import { readFile } from 'node:fs/promises'
|
||||||
import { createHash } from 'crypto'
|
import { createHash } from 'node:crypto'
|
||||||
import { readItem, writeItem } from './store'
|
import { readItem, writeItem } from './store'
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -21,9 +21,9 @@
|
||||||
// Adapted from the `command-exists` node module
|
// Adapted from the `command-exists` node module
|
||||||
// https://github.com/mathisonian/command-exists
|
// https://github.com/mathisonian/command-exists
|
||||||
|
|
||||||
import { execSync } from 'child_process'
|
import { execSync } from 'node:child_process'
|
||||||
import { accessSync, constants } from 'fs'
|
import { accessSync, constants } from 'node:fs'
|
||||||
import path from 'path'
|
import path from 'node:path'
|
||||||
|
|
||||||
const onWindows = process.platform == 'win32'
|
const onWindows = process.platform == 'win32'
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ const fileNotExistsSync = (commandName: string): boolean => {
|
||||||
try {
|
try {
|
||||||
accessSync(commandName, constants.F_OK)
|
accessSync(commandName, constants.F_OK)
|
||||||
return false
|
return false
|
||||||
} catch (e) {
|
} catch {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ const localExecutableSync = (commandName: string): boolean => {
|
||||||
try {
|
try {
|
||||||
accessSync(commandName, constants.F_OK | constants.X_OK)
|
accessSync(commandName, constants.F_OK | constants.X_OK)
|
||||||
return true
|
return true
|
||||||
} catch (e) {
|
} catch {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ const commandExistsUnixSync = function (
|
||||||
'; exit 0; }'
|
'; exit 0; }'
|
||||||
)
|
)
|
||||||
return !!stdout
|
return !!stdout
|
||||||
} catch (error) {
|
} catch {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ const commandExistsWindowsSync = function (
|
||||||
): boolean {
|
): boolean {
|
||||||
// Regex from Julio from: https://stackoverflow.com/questions/51494579/regex-windows-path-validator
|
// Regex from Julio from: https://stackoverflow.com/questions/51494579/regex-windows-path-validator
|
||||||
if (
|
if (
|
||||||
!/^(?!(?:.*\s|.*\.|\W+)$)(?:[a-zA-Z]:)?(?:(?:[^<>:"|?*\n])+(?:\/\/|\/|\\\\|\\)?)+$/m.test(
|
!/^(?!(?:.*\s|.*\.|\W+)$)(?:[A-Za-z]:)?(?:[^\n"*:<>?|]+(?:\/\/|\/|\\\\|\\)?)+$/m.test(
|
||||||
commandName
|
commandName
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
@ -82,7 +82,7 @@ const commandExistsWindowsSync = function (
|
||||||
try {
|
try {
|
||||||
const stdout = execSync('where ' + cleanedCommandName, { stdio: [] })
|
const stdout = execSync('where ' + cleanedCommandName, { stdio: [] })
|
||||||
return !!stdout
|
return !!stdout
|
||||||
} catch (error) {
|
} catch {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ function cleanInput(toBeCleaned: string): string {
|
||||||
// Windows has a different cleaning process to Unix, so we should go through
|
// Windows has a different cleaning process to Unix, so we should go through
|
||||||
// that process first
|
// that process first
|
||||||
if (onWindows) {
|
if (onWindows) {
|
||||||
const isPathName = /[\\]/.test(toBeCleaned)
|
const isPathName = /\\/.test(toBeCleaned)
|
||||||
if (isPathName) {
|
if (isPathName) {
|
||||||
const dirname = '"' + path.dirname(toBeCleaned) + '"'
|
const dirname = '"' + path.dirname(toBeCleaned) + '"'
|
||||||
const basename = '"' + path.basename(toBeCleaned) + '"'
|
const basename = '"' + path.basename(toBeCleaned) + '"'
|
||||||
|
@ -102,7 +102,7 @@ function cleanInput(toBeCleaned: string): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise go through the unix cleaning process
|
// Otherwise go through the unix cleaning process
|
||||||
if (/[^A-Za-z0-9_\\/:=-]/.test(toBeCleaned)) {
|
if (/[^\w/:=\\-]/.test(toBeCleaned)) {
|
||||||
toBeCleaned = "'" + toBeCleaned.replace(/'/g, "'\\''") + "'"
|
toBeCleaned = "'" + toBeCleaned.replace(/'/g, "'\\''") + "'"
|
||||||
toBeCleaned = toBeCleaned
|
toBeCleaned = toBeCleaned
|
||||||
.replace(/^(?:'')+/g, '') // unduplicate single-quote at the beginning
|
.replace(/^(?:'')+/g, '') // unduplicate single-quote at the beginning
|
||||||
|
@ -114,9 +114,5 @@ function cleanInput(toBeCleaned: string): string {
|
||||||
|
|
||||||
export function commandExistsSync(commandName: string): boolean {
|
export function commandExistsSync(commandName: string): boolean {
|
||||||
const cleanedCommandName = cleanInput(commandName)
|
const cleanedCommandName = cleanInput(commandName)
|
||||||
if (onWindows) {
|
return onWindows ? commandExistsWindowsSync(commandName, cleanedCommandName) : commandExistsUnixSync(commandName, cleanedCommandName);
|
||||||
return commandExistsWindowsSync(commandName, cleanedCommandName)
|
|
||||||
} else {
|
|
||||||
return commandExistsUnixSync(commandName, cleanedCommandName)
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'fs'
|
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs'
|
||||||
import {
|
import {
|
||||||
configPath,
|
configPath,
|
||||||
defaultConfig,
|
defaultConfig,
|
||||||
|
|
|
@ -5,21 +5,21 @@
|
||||||
* Responsible for loading, parsing and checking the config file for melon
|
* Responsible for loading, parsing and checking the config file for melon
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { existsSync, readFileSync, writeFileSync } from 'fs'
|
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
||||||
import { join } from 'path'
|
import { join } from 'node:path'
|
||||||
import { BIN_NAME } from '../constants'
|
import { BIN_NAME } from '../constants'
|
||||||
|
|
||||||
import { log } from '../log'
|
import { log } from '../log'
|
||||||
|
|
||||||
export const projectDir = process.cwd()
|
export const projectDirectory = process.cwd()
|
||||||
export const configPath = join(projectDir, 'gluon.json')
|
export const configPath = join(projectDirectory, 'gluon.json')
|
||||||
|
|
||||||
let hasWarnedAboutConfig = false
|
let hasWarnedAboutConfig = false
|
||||||
|
|
||||||
export enum SupportedProducts {
|
export enum SupportedProducts {
|
||||||
Firefox = 'firefox',
|
Firefox = 'firefox',
|
||||||
FirefoxESR = 'firefox-esr',
|
FirefoxESR = 'firefox-esr',
|
||||||
FirefoxDev = 'firefox-dev',
|
FirefoxDevelopment = 'firefox-dev',
|
||||||
FirefoxBeta = 'firefox-beta',
|
FirefoxBeta = 'firefox-beta',
|
||||||
FirefoxNightly = 'firefox-nightly',
|
FirefoxNightly = 'firefox-nightly',
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ export enum SupportedProducts {
|
||||||
export const validProducts = [
|
export const validProducts = [
|
||||||
SupportedProducts.Firefox,
|
SupportedProducts.Firefox,
|
||||||
SupportedProducts.FirefoxESR,
|
SupportedProducts.FirefoxESR,
|
||||||
SupportedProducts.FirefoxDev,
|
SupportedProducts.FirefoxDevelopment,
|
||||||
SupportedProducts.FirefoxBeta,
|
SupportedProducts.FirefoxBeta,
|
||||||
SupportedProducts.FirefoxNightly,
|
SupportedProducts.FirefoxNightly,
|
||||||
]
|
]
|
||||||
|
@ -216,10 +216,10 @@ export function getConfig(): Config {
|
||||||
try {
|
try {
|
||||||
// Try to parse the contents of the file. May not be valid JSON
|
// Try to parse the contents of the file. May not be valid JSON
|
||||||
fileParsed = JSON.parse(fileContents)
|
fileParsed = JSON.parse(fileContents)
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
// Report the error to the user
|
// Report the error to the user
|
||||||
log.error(`Error parsing ${BIN_NAME} config file located at ${configPath}`)
|
log.error(`Error parsing ${BIN_NAME} config file located at ${configPath}`)
|
||||||
log.error(e)
|
log.error(error)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +295,7 @@ export function getConfig(): Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function saveConfig() {
|
export function saveConfig() {
|
||||||
writeFileSync(configPath, JSON.stringify(config, null, 2))
|
writeFileSync(configPath, JSON.stringify(config, undefined, 2))
|
||||||
}
|
}
|
||||||
|
|
||||||
export const config = getConfig()
|
export const config = getConfig()
|
||||||
|
|
|
@ -36,26 +36,29 @@ export const configDispatch = (
|
||||||
if (config?.shell) {
|
if (config?.shell) {
|
||||||
switch (config.shell) {
|
switch (config.shell) {
|
||||||
// Don't change anything if we are using the default shell
|
// Don't change anything if we are using the default shell
|
||||||
case 'default':
|
case 'default': {
|
||||||
break
|
break
|
||||||
|
}
|
||||||
|
|
||||||
case 'unix':
|
case 'unix': {
|
||||||
// Bash path provides a unix shell on windows
|
// Bash path provides a unix shell on windows
|
||||||
shell = BASH_PATH || false
|
shell = BASH_PATH || false
|
||||||
break
|
break
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default: {
|
||||||
log.error(`dispatch() does not understand the shell '${shell}'`)
|
log.error(`dispatch() does not understand the shell '${shell}'`)
|
||||||
break
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handle = (data: string | Error, killOnError?: boolean) => {
|
const handle = (data: string | Error, killOnError?: boolean) => {
|
||||||
const d = data.toString()
|
const dataAsString = data.toString()
|
||||||
|
|
||||||
d.split('\n').forEach((line: string) => {
|
for (const line of dataAsString.split('\n')) {
|
||||||
if (line.length !== 0) logger(removeTimestamp(line))
|
if (line.length > 0) logger(removeTimestamp(line))
|
||||||
})
|
}
|
||||||
|
|
||||||
if (killOnError) {
|
if (killOnError) {
|
||||||
log.error('Command failed. See error above.')
|
log.error('Command failed. See error above.')
|
||||||
|
@ -67,7 +70,7 @@ export const configDispatch = (
|
||||||
cwd: config?.cwd || process.cwd(),
|
cwd: config?.cwd || process.cwd(),
|
||||||
shell: shell,
|
shell: shell,
|
||||||
env: {
|
env: {
|
||||||
...(config?.env || {}),
|
...config?.env,
|
||||||
...process.env,
|
...process.env,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -89,13 +92,13 @@ export const configDispatch = (
|
||||||
*/
|
*/
|
||||||
export const dispatch = (
|
export const dispatch = (
|
||||||
cmd: string,
|
cmd: string,
|
||||||
args?: string[],
|
arguments_?: string[],
|
||||||
cwd?: string,
|
cwd?: string,
|
||||||
killOnError?: boolean,
|
killOnError?: boolean,
|
||||||
logger = (data: string) => log.info(data)
|
logger = (data: string) => log.info(data)
|
||||||
): Promise<boolean> => {
|
): Promise<boolean> => {
|
||||||
return configDispatch(cmd, {
|
return configDispatch(cmd, {
|
||||||
args: args,
|
args: arguments_,
|
||||||
cwd: cwd,
|
cwd: cwd,
|
||||||
killOnError: killOnError,
|
killOnError: killOnError,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
import { createWriteStream } from 'fs'
|
import { createWriteStream } from 'node:fs'
|
||||||
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import cliProgress from 'cli-progress'
|
import cliProgress from 'cli-progress'
|
||||||
import { Duplex } from 'stream'
|
import { Duplex } from 'node:stream'
|
||||||
import { log } from '../log'
|
import { log } from '../log'
|
||||||
|
|
||||||
export async function downloadFileToLocation(
|
export async function downloadFileToLocation(
|
||||||
|
@ -44,11 +44,11 @@ export async function downloadFileToLocation(
|
||||||
receivedBytes += chunk.length
|
receivedBytes += chunk.length
|
||||||
})
|
})
|
||||||
data.pipe(writer)
|
data.pipe(writer)
|
||||||
data.on('error', (err: unknown) => {
|
data.on('error', (error: unknown) => {
|
||||||
log.warning(
|
log.warning(
|
||||||
`An error occured whilst downloading ${url}. It might be ignored`
|
`An error occured whilst downloading ${url}. It might be ignored`
|
||||||
)
|
)
|
||||||
reject(err)
|
reject(error)
|
||||||
})
|
})
|
||||||
|
|
||||||
const progressInterval = setInterval(
|
const progressInterval = setInterval(
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
import * as dynamicConfig from './dynamicConfig'
|
import * as dynamicConfig from './dynamic-config'
|
||||||
import { readItem, removeItem } from './store'
|
import { readItem, removeItem } from './store'
|
||||||
|
|
||||||
describe('set', () => {
|
describe('set', () => {
|
|
@ -2,12 +2,12 @@
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
import chalk from 'chalk'
|
import chalk from 'chalk'
|
||||||
import { readFileSync } from 'fs'
|
import { readFileSync } from 'node:fs'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'node:path'
|
||||||
import { MELON_DIR } from '../constants'
|
import { MELON_DIR } from '../constants'
|
||||||
import { log } from '../log'
|
import { log } from '../log'
|
||||||
|
|
||||||
export const errorHandler = (err: Error, isUnhandledRej: boolean): void => {
|
export const errorHandler = (error: Error, isUnhandledRej: boolean): never => {
|
||||||
let cc = readFileSync(resolve(MELON_DIR, 'command')).toString()
|
let cc = readFileSync(resolve(MELON_DIR, 'command')).toString()
|
||||||
cc = cc.replace(/(\r\n|\n|\r)/gm, '')
|
cc = cc.replace(/(\r\n|\n|\r)/gm, '')
|
||||||
|
|
||||||
|
@ -21,11 +21,11 @@ export const errorHandler = (err: Error, isUnhandledRej: boolean): void => {
|
||||||
console.log(
|
console.log(
|
||||||
`\n\t`,
|
`\n\t`,
|
||||||
isUnhandledRej
|
isUnhandledRej
|
||||||
? err.toString().replace(/\n/g, '\n\t ')
|
? error.toString().replace(/\n/g, '\n\t ')
|
||||||
: err.message.replace(/\n/g, '\n\t ')
|
: error.message.replace(/\n/g, '\n\t ')
|
||||||
)
|
)
|
||||||
if (err.stack || isUnhandledRej) {
|
if (error.stack || isUnhandledRej) {
|
||||||
const stack: string[] | undefined = err.stack?.split('\n')
|
const stack: string[] | undefined = error.stack?.split('\n')
|
||||||
|
|
||||||
if (!stack) return
|
if (!stack) return
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,9 @@ import {
|
||||||
openSync,
|
openSync,
|
||||||
rmSync,
|
rmSync,
|
||||||
writeSync,
|
writeSync,
|
||||||
} from 'fs'
|
} from 'node:fs'
|
||||||
import { mkdir, readdir, stat, symlink } from 'fs/promises'
|
import { mkdir, readdir, stat } from 'node:fs/promises'
|
||||||
import { join, isAbsolute, dirname, relative } from 'path'
|
import { join, isAbsolute } from 'node:path'
|
||||||
|
|
||||||
import { log } from '../log'
|
import { log } from '../log'
|
||||||
|
|
||||||
|
@ -24,19 +24,19 @@ import { log } from '../log'
|
||||||
export const windowsPathToUnix = (path: string): string =>
|
export const windowsPathToUnix = (path: string): string =>
|
||||||
process.platform == 'win32' ? path.replace(/\\/g, '/') : path
|
process.platform == 'win32' ? path.replace(/\\/g, '/') : path
|
||||||
|
|
||||||
export async function walkDirectory(dirName: string): Promise<string[]> {
|
export async function walkDirectory(directory: string): Promise<string[]> {
|
||||||
const output = []
|
const output = []
|
||||||
|
|
||||||
if (!isAbsolute(dirName)) {
|
if (!isAbsolute(directory)) {
|
||||||
log.askForReport()
|
log.askForReport()
|
||||||
log.error('Please provide an absolute input to walkDirectory')
|
log.error('Please provide an absolute input to walkDirectory')
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const directoryContents = await readdir(dirName)
|
const directoryContents = await readdir(directory)
|
||||||
|
|
||||||
for (const file of directoryContents) {
|
for (const file of directoryContents) {
|
||||||
const fullPath = join(dirName, file)
|
const fullPath = join(directory, file)
|
||||||
const fStat = await stat(fullPath)
|
const fStat = await stat(fullPath)
|
||||||
|
|
||||||
if (fStat.isDirectory()) {
|
if (fStat.isDirectory()) {
|
||||||
|
@ -47,9 +47,9 @@ export async function walkDirectory(dirName: string): Promise<string[]> {
|
||||||
output.push(fullPath)
|
output.push(fullPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
log.askForReport()
|
log.askForReport()
|
||||||
log.error(e)
|
log.error(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
@ -57,21 +57,21 @@ export async function walkDirectory(dirName: string): Promise<string[]> {
|
||||||
|
|
||||||
export type TreeType = { [property: string]: string[] | TreeType }
|
export type TreeType = { [property: string]: string[] | TreeType }
|
||||||
|
|
||||||
export async function walkDirectoryTree(dirName: string): Promise<TreeType> {
|
export async function walkDirectoryTree(directory: string): Promise<TreeType> {
|
||||||
const output: TreeType = {}
|
const output: TreeType = {}
|
||||||
|
|
||||||
if (!isAbsolute(dirName)) {
|
if (!isAbsolute(directory)) {
|
||||||
log.askForReport()
|
log.askForReport()
|
||||||
log.error('Please provide an absolute input to walkDirectory')
|
log.error('Please provide an absolute input to walkDirectory')
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const directoryContents = await readdir(dirName)
|
const directoryContents = await readdir(directory)
|
||||||
|
|
||||||
const currentOut = []
|
const currentOut = []
|
||||||
|
|
||||||
for (const file of directoryContents) {
|
for (const file of directoryContents) {
|
||||||
const fullPath = join(dirName, file)
|
const fullPath = join(directory, file)
|
||||||
const fStat = await stat(fullPath)
|
const fStat = await stat(fullPath)
|
||||||
|
|
||||||
if (fStat.isDirectory()) {
|
if (fStat.isDirectory()) {
|
||||||
|
@ -82,26 +82,26 @@ export async function walkDirectoryTree(dirName: string): Promise<TreeType> {
|
||||||
}
|
}
|
||||||
|
|
||||||
output['.'] = currentOut
|
output['.'] = currentOut
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
log.askForReport()
|
log.askForReport()
|
||||||
log.error(e)
|
log.error(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function ensureDir(dirName: string): Promise<void> {
|
export async function ensureDirectory(directory: string): Promise<void> {
|
||||||
if (!existsSync(dirName)) {
|
if (!existsSync(directory)) {
|
||||||
await mkdirp(dirName)
|
await mkdirp(directory)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mkdirp(dirName: string): Promise<string | undefined> {
|
export function mkdirp(directory: string): Promise<string | undefined> {
|
||||||
return mkdir(dirName, { recursive: true })
|
return mkdir(directory, { recursive: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mkdirpSync(dirName: string): string | undefined {
|
export function mkdirpSync(directory: string): string | undefined {
|
||||||
return mkdirSync(dirName, { recursive: true })
|
return mkdirSync(directory, { recursive: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
export function appendToFileSync(fileName: string, content: string): void {
|
export function appendToFileSync(fileName: string, content: string): void {
|
||||||
|
@ -110,58 +110,6 @@ export function appendToFileSync(fileName: string, content: string): void {
|
||||||
closeSync(file)
|
closeSync(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createSymlink(
|
|
||||||
srcPath: string,
|
|
||||||
destPath: string,
|
|
||||||
type?: string
|
|
||||||
): Promise<void> {
|
|
||||||
if (existsSync(destPath)) return
|
|
||||||
|
|
||||||
const { toDest: src } = symlinkPaths(srcPath, destPath)
|
|
||||||
|
|
||||||
const dir = dirname(destPath)
|
|
||||||
const exists = existsSync(dir)
|
|
||||||
if (exists) return await symlink(src, destPath, type)
|
|
||||||
await mkdirp(dir)
|
|
||||||
return await symlink(src, destPath, type)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapted from fs-extra
|
|
||||||
* @param srcPath
|
|
||||||
* @param destPath
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function symlinkPaths(
|
|
||||||
srcPath: string,
|
|
||||||
destPath: string
|
|
||||||
): { toCwd: string; toDest: string } {
|
|
||||||
if (isAbsolute(srcPath)) {
|
|
||||||
if (!existsSync(srcPath)) throw new Error('absolute srcpath does not exist')
|
|
||||||
|
|
||||||
return {
|
|
||||||
toCwd: srcPath,
|
|
||||||
toDest: srcPath,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const dstdir = dirname(destPath)
|
|
||||||
const relativeToDst = join(dstdir, srcPath)
|
|
||||||
if (existsSync(relativeToDst))
|
|
||||||
return {
|
|
||||||
toCwd: relativeToDst,
|
|
||||||
toDest: srcPath,
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!existsSync(srcPath))
|
|
||||||
throw new Error('relative srcpath does not exist')
|
|
||||||
return {
|
|
||||||
toCwd: srcPath,
|
|
||||||
toDest: relative(dstdir, srcPath),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function filesExist(files: string[]): boolean {
|
export function filesExist(files: string[]): boolean {
|
||||||
return files.every((file) => existsSync(file))
|
return files.every((file) => existsSync(file))
|
||||||
}
|
}
|
||||||
|
@ -175,5 +123,6 @@ export function ensureEmpty(path: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getSize(path: string): Promise<number> {
|
export async function getSize(path: string): Promise<number> {
|
||||||
return (await stat(path)).size
|
const fileInfo = await stat(path)
|
||||||
|
return fileInfo.size
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
export * from './commandExists'
|
export * from './command-exists'
|
||||||
export * from './changeTracking'
|
export * from './change-tracking'
|
||||||
export * from './delay'
|
export * from './delay'
|
||||||
export * from './dispatch'
|
export * from './dispatch'
|
||||||
export * from './error-handler'
|
export * from './error-handler'
|
||||||
export * from './version'
|
export * from './version'
|
||||||
export * from './config'
|
export * from './config'
|
||||||
export * from './stringTemplate'
|
export * from './string-template'
|
||||||
export * from './fs'
|
export * from './fs'
|
||||||
export * from './versionFormatter'
|
export * from './version-formatter'
|
||||||
export * as dynamicConfig from './dynamicConfig'
|
export * as dynamicConfig from './dynamic-config'
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'fs'
|
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs'
|
||||||
import { join } from 'path'
|
import { join } from 'node:path'
|
||||||
import { equip, None, OptionEquipped } from 'rustic'
|
import { equip, None, OptionEquipped } from 'rustic'
|
||||||
|
|
||||||
import { MELON_DIR } from '../constants'
|
import { MELON_DIR } from '../constants'
|
||||||
|
|
||||||
export const readItem = <T>(key: string): OptionEquipped<T> => {
|
export const readItem = <T>(key: string): OptionEquipped<T> => {
|
||||||
const dir = join(MELON_DIR, `${key}.json`)
|
const fileLocation = join(MELON_DIR, `${key}.json`)
|
||||||
|
|
||||||
if (!existsSync(dir)) {
|
if (!existsSync(fileLocation)) {
|
||||||
return equip<T>(None)
|
return equip<T>(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = readFileSync(dir).toString()
|
const data = readFileSync(fileLocation).toString()
|
||||||
|
|
||||||
return equip(JSON.parse(data))
|
return equip(JSON.parse(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
export const writeItem = <T>(key: string, data: T) => {
|
export const writeItem = <T>(key: string, data: T) => {
|
||||||
const dir = join(MELON_DIR, `${key}.json`)
|
const fileLocation = join(MELON_DIR, `${key}.json`)
|
||||||
writeFileSync(dir, JSON.stringify(data, null, 2))
|
writeFileSync(fileLocation, JSON.stringify(data, undefined, 2))
|
||||||
}
|
}
|
||||||
|
|
||||||
export const removeItem = (key: string) => {
|
export const removeItem = (key: string) => {
|
||||||
|
|
|
@ -8,15 +8,15 @@ export function stringTemplate(
|
||||||
template: string,
|
template: string,
|
||||||
variables: { [key: string]: string | number }
|
variables: { [key: string]: string | number }
|
||||||
): string {
|
): string {
|
||||||
let temp = template
|
let temporary = template
|
||||||
|
|
||||||
for (const variable in variables) {
|
for (const variable in variables) {
|
||||||
// Replace only replaces the first instance of a string. We want to
|
// Replace only replaces the first instance of a string. We want to
|
||||||
// replace all instances
|
// replace all instances
|
||||||
while (temp.includes(`\${${variable}}`)) {
|
while (temporary.includes(`\${${variable}}`)) {
|
||||||
temp = temp.replace(`\${${variable}}`, variables[variable].toString())
|
temporary = temporary.replace(`\${${variable}}`, variables[variable].toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return temp
|
return temporary
|
||||||
}
|
}
|
|
@ -15,10 +15,10 @@ export interface Task {
|
||||||
export class TaskList {
|
export class TaskList {
|
||||||
tasks: Task[]
|
tasks: Task[]
|
||||||
loggingStyle: LoggingMode = 'normal'
|
loggingStyle: LoggingMode = 'normal'
|
||||||
loggingIndentation: string = ''
|
loggingIndentation = ''
|
||||||
loggingOnError: LoggingErrorMode = 'throw'
|
loggingOnError: LoggingErrorMode = 'throw'
|
||||||
|
|
||||||
error: Error | null = null
|
error?: Error
|
||||||
|
|
||||||
constructor(tasks: Task[]) {
|
constructor(tasks: Task[]) {
|
||||||
this.tasks = tasks
|
this.tasks = tasks
|
||||||
|
@ -49,22 +49,27 @@ export class TaskList {
|
||||||
const prefixTemplate = `[${type.toUpperCase()}]`
|
const prefixTemplate = `[${type.toUpperCase()}]`
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'start':
|
case 'start': {
|
||||||
prefix += kleur.bold().gray(prefixTemplate)
|
prefix += kleur.bold().gray(prefixTemplate)
|
||||||
break
|
break
|
||||||
case 'finish':
|
}
|
||||||
|
case 'finish': {
|
||||||
prefix += kleur.bold().green(prefixTemplate)
|
prefix += kleur.bold().green(prefixTemplate)
|
||||||
break
|
break
|
||||||
case 'fail':
|
}
|
||||||
|
case 'fail': {
|
||||||
prefix += kleur.bold().red(prefixTemplate)
|
prefix += kleur.bold().red(prefixTemplate)
|
||||||
break
|
break
|
||||||
case 'skip':
|
}
|
||||||
|
case 'skip': {
|
||||||
prefix += kleur.bold().yellow(prefixTemplate)
|
prefix += kleur.bold().yellow(prefixTemplate)
|
||||||
break
|
break
|
||||||
case 'info':
|
}
|
||||||
|
case 'info': {
|
||||||
prefix += ' '
|
prefix += ' '
|
||||||
prefix += kleur.bold().cyan(prefixTemplate)
|
prefix += kleur.bold().cyan(prefixTemplate)
|
||||||
break
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`${prefix} ${name}`)
|
console.log(`${prefix} ${name}`)
|
||||||
|
@ -94,17 +99,17 @@ export class TaskList {
|
||||||
|
|
||||||
await result.indent(this.loggingIndentation + ' ').run()
|
await result.indent(this.loggingIndentation + ' ').run()
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
if (this.loggingOnError == 'throw') {
|
if (this.loggingOnError == 'throw') {
|
||||||
this.log('fail', task.name)
|
this.log('fail', task.name)
|
||||||
throw e
|
throw error
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.loggingOnError == 'inline') {
|
if (this.loggingOnError == 'inline') {
|
||||||
this.log('fail', `${task.name}: ${e}`)
|
this.log('fail', `${task.name}: ${error}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.error = e as Error
|
this.error = error as Error
|
||||||
}
|
}
|
||||||
|
|
||||||
this.log('finish', task.name)
|
this.log('finish', task.name)
|
|
@ -7,8 +7,8 @@ export const versionFormatter = (
|
||||||
options: ({ name: string; value: string } | null | string)[]
|
options: ({ name: string; value: string } | null | string)[]
|
||||||
): string => {
|
): string => {
|
||||||
const spacesValue = Math.max(
|
const spacesValue = Math.max(
|
||||||
...options.map((arg) =>
|
...options.map((argument) =>
|
||||||
typeof arg === 'string' ? 0 : arg?.value?.length || 0
|
typeof argument === 'string' ? 0 : argument?.value?.length || 0
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { SupportedProducts } from './config'
|
||||||
const firefoxTargets = JSON.parse(`{
|
const firefoxTargets = JSON.parse(`{
|
||||||
"${SupportedProducts.Firefox}": "LATEST_FIREFOX_VERSION",
|
"${SupportedProducts.Firefox}": "LATEST_FIREFOX_VERSION",
|
||||||
"${SupportedProducts.FirefoxBeta}": "LATEST_FIREFOX_DEVEL_VERSION",
|
"${SupportedProducts.FirefoxBeta}": "LATEST_FIREFOX_DEVEL_VERSION",
|
||||||
"${SupportedProducts.FirefoxDev}": "FIREFOX_DEVEDITION",
|
"${SupportedProducts.FirefoxDevelopment}": "FIREFOX_DEVEDITION",
|
||||||
"${SupportedProducts.FirefoxESR}": "FIREFOX_ESR",
|
"${SupportedProducts.FirefoxESR}": "FIREFOX_ESR",
|
||||||
"${SupportedProducts.FirefoxNightly}": "FIREFOX_NIGHTLY"
|
"${SupportedProducts.FirefoxNightly}": "FIREFOX_NIGHTLY"
|
||||||
}`)
|
}`)
|
||||||
|
@ -22,9 +22,9 @@ export const getLatestFF = async (
|
||||||
)
|
)
|
||||||
|
|
||||||
return data[firefoxTargets[product]]
|
return data[firefoxTargets[product]]
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
log.warning('Failed to get latest firefox version with error:')
|
log.warning('Failed to get latest firefox version with error:')
|
||||||
log.error(e)
|
log.error(error)
|
||||||
|
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
|
177
yarn.lock
177
yarn.lock
|
@ -127,6 +127,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076"
|
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076"
|
||||||
integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==
|
integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==
|
||||||
|
|
||||||
|
"@babel/helper-validator-identifier@^7.19.1":
|
||||||
|
version "7.19.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2"
|
||||||
|
integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==
|
||||||
|
|
||||||
"@babel/helper-validator-option@^7.18.6":
|
"@babel/helper-validator-option@^7.18.6":
|
||||||
version "7.18.6"
|
version "7.18.6"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8"
|
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8"
|
||||||
|
@ -1114,6 +1119,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190"
|
||||||
integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==
|
integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==
|
||||||
|
|
||||||
|
"@types/normalize-package-data@^2.4.0":
|
||||||
|
version "2.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301"
|
||||||
|
integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==
|
||||||
|
|
||||||
"@types/picomatch@^2.3.0":
|
"@types/picomatch@^2.3.0":
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/picomatch/-/picomatch-2.3.0.tgz#75db5e75a713c5a83d5b76780c3da84a82806003"
|
resolved "https://registry.yarnpkg.com/@types/picomatch/-/picomatch-2.3.0.tgz#75db5e75a713c5a83d5b76780c3da84a82806003"
|
||||||
|
@ -1525,6 +1535,11 @@ buffer@^5.2.0, buffer@^5.5.0:
|
||||||
base64-js "^1.3.1"
|
base64-js "^1.3.1"
|
||||||
ieee754 "^1.1.13"
|
ieee754 "^1.1.13"
|
||||||
|
|
||||||
|
builtin-modules@^3.3.0:
|
||||||
|
version "3.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6"
|
||||||
|
integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==
|
||||||
|
|
||||||
callsites@^3.0.0:
|
callsites@^3.0.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
|
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
|
||||||
|
@ -1577,11 +1592,23 @@ ci-info@^3.2.0:
|
||||||
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.2.tgz#6d2967ffa407466481c6c90b6e16b3098f080128"
|
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.2.tgz#6d2967ffa407466481c6c90b6e16b3098f080128"
|
||||||
integrity sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==
|
integrity sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==
|
||||||
|
|
||||||
|
ci-info@^3.4.0:
|
||||||
|
version "3.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.5.0.tgz#bfac2a29263de4c829d806b1ab478e35091e171f"
|
||||||
|
integrity sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==
|
||||||
|
|
||||||
cjs-module-lexer@^1.0.0:
|
cjs-module-lexer@^1.0.0:
|
||||||
version "1.2.2"
|
version "1.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40"
|
resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40"
|
||||||
integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==
|
integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==
|
||||||
|
|
||||||
|
clean-regexp@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/clean-regexp/-/clean-regexp-1.0.0.tgz#8df7c7aae51fd36874e8f8d05b9180bc11a3fed7"
|
||||||
|
integrity sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==
|
||||||
|
dependencies:
|
||||||
|
escape-string-regexp "^1.0.5"
|
||||||
|
|
||||||
cli-progress@^3.9.1:
|
cli-progress@^3.9.1:
|
||||||
version "3.11.2"
|
version "3.11.2"
|
||||||
resolved "https://registry.yarnpkg.com/cli-progress/-/cli-progress-3.11.2.tgz#f8c89bd157e74f3f2c43bcfb3505670b4d48fc77"
|
resolved "https://registry.yarnpkg.com/cli-progress/-/cli-progress-3.11.2.tgz#f8c89bd157e74f3f2c43bcfb3505670b4d48fc77"
|
||||||
|
@ -1863,6 +1890,26 @@ escodegen@^2.0.0:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
source-map "~0.6.1"
|
source-map "~0.6.1"
|
||||||
|
|
||||||
|
eslint-plugin-unicorn@^44.0.2:
|
||||||
|
version "44.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/eslint-plugin-unicorn/-/eslint-plugin-unicorn-44.0.2.tgz#6324a001c0a5e2ac00fb51b30db27d14c6c36ab3"
|
||||||
|
integrity sha512-GLIDX1wmeEqpGaKcnMcqRvMVsoabeF0Ton0EX4Th5u6Kmf7RM9WBl705AXFEsns56ESkEs0uyelLuUTvz9Tr0w==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-validator-identifier" "^7.19.1"
|
||||||
|
ci-info "^3.4.0"
|
||||||
|
clean-regexp "^1.0.0"
|
||||||
|
eslint-utils "^3.0.0"
|
||||||
|
esquery "^1.4.0"
|
||||||
|
indent-string "^4.0.0"
|
||||||
|
is-builtin-module "^3.2.0"
|
||||||
|
lodash "^4.17.21"
|
||||||
|
pluralize "^8.0.0"
|
||||||
|
read-pkg-up "^7.0.1"
|
||||||
|
regexp-tree "^0.1.24"
|
||||||
|
safe-regex "^2.1.1"
|
||||||
|
semver "^7.3.7"
|
||||||
|
strip-indent "^3.0.0"
|
||||||
|
|
||||||
eslint-scope@^5.1.1:
|
eslint-scope@^5.1.1:
|
||||||
version "5.1.1"
|
version "5.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
|
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
|
||||||
|
@ -2271,6 +2318,11 @@ has@^1.0.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
function-bind "^1.1.1"
|
function-bind "^1.1.1"
|
||||||
|
|
||||||
|
hosted-git-info@^2.1.4:
|
||||||
|
version "2.8.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
|
||||||
|
integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
|
||||||
|
|
||||||
html-encoding-sniffer@^2.0.1:
|
html-encoding-sniffer@^2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3"
|
resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3"
|
||||||
|
@ -2350,6 +2402,11 @@ imurmurhash@^0.1.4:
|
||||||
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
|
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
|
||||||
integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
|
integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
|
||||||
|
|
||||||
|
indent-string@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251"
|
||||||
|
integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==
|
||||||
|
|
||||||
inflight@^1.0.4:
|
inflight@^1.0.4:
|
||||||
version "1.0.6"
|
version "1.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||||
|
@ -2387,6 +2444,13 @@ is-arrayish@^0.3.1:
|
||||||
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
|
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
|
||||||
integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
|
integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
|
||||||
|
|
||||||
|
is-builtin-module@^3.2.0:
|
||||||
|
version "3.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.0.tgz#bb0310dfe881f144ca83f30100ceb10cf58835e0"
|
||||||
|
integrity sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==
|
||||||
|
dependencies:
|
||||||
|
builtin-modules "^3.3.0"
|
||||||
|
|
||||||
is-core-module@^2.9.0:
|
is-core-module@^2.9.0:
|
||||||
version "2.9.0"
|
version "2.9.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69"
|
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69"
|
||||||
|
@ -3071,7 +3135,7 @@ lodash.merge@^4.6.2:
|
||||||
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
||||||
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
|
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
|
||||||
|
|
||||||
lodash@^4.7.0:
|
lodash@^4.17.21, lodash@^4.7.0:
|
||||||
version "4.17.21"
|
version "4.17.21"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||||
|
@ -3154,6 +3218,11 @@ min-document@^2.19.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
dom-walk "^0.1.0"
|
dom-walk "^0.1.0"
|
||||||
|
|
||||||
|
min-indent@^1.0.0:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
|
||||||
|
integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
|
||||||
|
|
||||||
minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2:
|
minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2:
|
||||||
version "3.1.2"
|
version "3.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
||||||
|
@ -3228,6 +3297,16 @@ node-releases@^2.0.6:
|
||||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503"
|
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503"
|
||||||
integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==
|
integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==
|
||||||
|
|
||||||
|
normalize-package-data@^2.5.0:
|
||||||
|
version "2.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
|
||||||
|
integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==
|
||||||
|
dependencies:
|
||||||
|
hosted-git-info "^2.1.4"
|
||||||
|
resolve "^1.10.0"
|
||||||
|
semver "2 || 3 || 4 || 5"
|
||||||
|
validate-npm-package-license "^3.0.1"
|
||||||
|
|
||||||
normalize-path@^3.0.0:
|
normalize-path@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||||
|
@ -3342,7 +3421,7 @@ parse-headers@^2.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.5.tgz#069793f9356a54008571eb7f9761153e6c770da9"
|
resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.5.tgz#069793f9356a54008571eb7f9761153e6c770da9"
|
||||||
integrity sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==
|
integrity sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==
|
||||||
|
|
||||||
parse-json@^5.2.0:
|
parse-json@^5.0.0, parse-json@^5.2.0:
|
||||||
version "5.2.0"
|
version "5.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd"
|
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd"
|
||||||
integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==
|
integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==
|
||||||
|
@ -3416,6 +3495,11 @@ pkg-dir@^4.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
find-up "^4.0.0"
|
find-up "^4.0.0"
|
||||||
|
|
||||||
|
pluralize@^8.0.0:
|
||||||
|
version "8.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1"
|
||||||
|
integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==
|
||||||
|
|
||||||
png-to-ico@^2.1.4:
|
png-to-ico@^2.1.4:
|
||||||
version "2.1.4"
|
version "2.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/png-to-ico/-/png-to-ico-2.1.4.tgz#0f14674c79e23bbd4367696b5852693edf28dbee"
|
resolved "https://registry.yarnpkg.com/png-to-ico/-/png-to-ico-2.1.4.tgz#0f14674c79e23bbd4367696b5852693edf28dbee"
|
||||||
|
@ -3523,6 +3607,25 @@ react-is@^17.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
|
||||||
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
|
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
|
||||||
|
|
||||||
|
read-pkg-up@^7.0.1:
|
||||||
|
version "7.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507"
|
||||||
|
integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==
|
||||||
|
dependencies:
|
||||||
|
find-up "^4.1.0"
|
||||||
|
read-pkg "^5.2.0"
|
||||||
|
type-fest "^0.8.1"
|
||||||
|
|
||||||
|
read-pkg@^5.2.0:
|
||||||
|
version "5.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc"
|
||||||
|
integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==
|
||||||
|
dependencies:
|
||||||
|
"@types/normalize-package-data" "^2.4.0"
|
||||||
|
normalize-package-data "^2.5.0"
|
||||||
|
parse-json "^5.0.0"
|
||||||
|
type-fest "^0.6.0"
|
||||||
|
|
||||||
readable-stream@^3.1.1, readable-stream@^3.4.0:
|
readable-stream@^3.1.1, readable-stream@^3.4.0:
|
||||||
version "3.6.0"
|
version "3.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
|
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
|
||||||
|
@ -3537,6 +3640,11 @@ regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4:
|
||||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
|
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
|
||||||
integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
|
integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
|
||||||
|
|
||||||
|
regexp-tree@^0.1.24, regexp-tree@~0.1.1:
|
||||||
|
version "0.1.24"
|
||||||
|
resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.24.tgz#3d6fa238450a4d66e5bc9c4c14bb720e2196829d"
|
||||||
|
integrity sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==
|
||||||
|
|
||||||
regexpp@^3.2.0:
|
regexpp@^3.2.0:
|
||||||
version "3.2.0"
|
version "3.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
|
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
|
||||||
|
@ -3569,7 +3677,7 @@ resolve.exports@^1.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9"
|
resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9"
|
||||||
integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==
|
integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==
|
||||||
|
|
||||||
resolve@^1.20.0:
|
resolve@^1.10.0, resolve@^1.20.0:
|
||||||
version "1.22.1"
|
version "1.22.1"
|
||||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
|
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
|
||||||
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
|
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
|
||||||
|
@ -3619,6 +3727,13 @@ safe-buffer@~5.1.1:
|
||||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
||||||
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
||||||
|
|
||||||
|
safe-regex@^2.1.1:
|
||||||
|
version "2.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-2.1.1.tgz#f7128f00d056e2fe5c11e81a1324dd974aadced2"
|
||||||
|
integrity sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==
|
||||||
|
dependencies:
|
||||||
|
regexp-tree "~0.1.1"
|
||||||
|
|
||||||
"safer-buffer@>= 2.1.2 < 3":
|
"safer-buffer@>= 2.1.2 < 3":
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||||
|
@ -3636,6 +3751,11 @@ saxes@^5.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
xmlchars "^2.2.0"
|
xmlchars "^2.2.0"
|
||||||
|
|
||||||
|
"semver@2 || 3 || 4 || 5":
|
||||||
|
version "5.7.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||||
|
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
||||||
|
|
||||||
semver@7.x, semver@^7.3.2, semver@^7.3.5, semver@^7.3.7:
|
semver@7.x, semver@^7.3.2, semver@^7.3.5, semver@^7.3.7:
|
||||||
version "7.3.7"
|
version "7.3.7"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f"
|
||||||
|
@ -3728,6 +3848,32 @@ source-map@^0.7.3:
|
||||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656"
|
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656"
|
||||||
integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==
|
integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==
|
||||||
|
|
||||||
|
spdx-correct@^3.0.0:
|
||||||
|
version "3.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9"
|
||||||
|
integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==
|
||||||
|
dependencies:
|
||||||
|
spdx-expression-parse "^3.0.0"
|
||||||
|
spdx-license-ids "^3.0.0"
|
||||||
|
|
||||||
|
spdx-exceptions@^2.1.0:
|
||||||
|
version "2.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d"
|
||||||
|
integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==
|
||||||
|
|
||||||
|
spdx-expression-parse@^3.0.0:
|
||||||
|
version "3.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679"
|
||||||
|
integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==
|
||||||
|
dependencies:
|
||||||
|
spdx-exceptions "^2.1.0"
|
||||||
|
spdx-license-ids "^3.0.0"
|
||||||
|
|
||||||
|
spdx-license-ids@^3.0.0:
|
||||||
|
version "3.0.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz#69077835abe2710b65f03969898b6637b505a779"
|
||||||
|
integrity sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==
|
||||||
|
|
||||||
sprintf-js@~1.0.2:
|
sprintf-js@~1.0.2:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||||
|
@ -3781,6 +3927,13 @@ strip-final-newline@^2.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
|
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
|
||||||
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
|
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
|
||||||
|
|
||||||
|
strip-indent@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001"
|
||||||
|
integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==
|
||||||
|
dependencies:
|
||||||
|
min-indent "^1.0.0"
|
||||||
|
|
||||||
strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
|
strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
|
||||||
version "3.1.1"
|
version "3.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
|
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
|
||||||
|
@ -3991,6 +4144,16 @@ type-fest@^0.21.3:
|
||||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
|
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
|
||||||
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
|
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
|
||||||
|
|
||||||
|
type-fest@^0.6.0:
|
||||||
|
version "0.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b"
|
||||||
|
integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==
|
||||||
|
|
||||||
|
type-fest@^0.8.1:
|
||||||
|
version "0.8.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
|
||||||
|
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
|
||||||
|
|
||||||
typedarray-to-buffer@^3.1.5:
|
typedarray-to-buffer@^3.1.5:
|
||||||
version "3.1.5"
|
version "3.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
|
resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
|
||||||
|
@ -4054,6 +4217,14 @@ v8-to-istanbul@^8.1.0:
|
||||||
convert-source-map "^1.6.0"
|
convert-source-map "^1.6.0"
|
||||||
source-map "^0.7.3"
|
source-map "^0.7.3"
|
||||||
|
|
||||||
|
validate-npm-package-license@^3.0.1:
|
||||||
|
version "3.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"
|
||||||
|
integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==
|
||||||
|
dependencies:
|
||||||
|
spdx-correct "^3.0.0"
|
||||||
|
spdx-expression-parse "^3.0.0"
|
||||||
|
|
||||||
w3c-hr-time@^1.0.2:
|
w3c-hr-time@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"
|
resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue