Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions eslint_temporary_suppressions.js
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,12 @@ export default [
'@typescript-eslint/no-unsafe-return': 'off',
},
},
{
files: ['packages/build/src/plugins/child/diff.js'],
rules: {
'n/no-missing-import': 'off',
},
},
{
files: ['packages/build/src/plugins/child/error.js'],
rules: {
Expand Down Expand Up @@ -1062,6 +1068,12 @@ export default [
'@typescript-eslint/no-unsafe-assignment': 'off',
},
},
{
files: ['packages/build/src/plugins_core/functions_install/index.js'],
rules: {
'n/no-missing-import': 'off',
},
},
{
files: ['packages/build/src/plugins_core/pre_cleanup/index.ts'],
rules: {
Expand Down
22 changes: 0 additions & 22 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 0 additions & 9 deletions packages/build/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,30 +78,21 @@
"@netlify/run-utils": "^7.1.0",
"@netlify/zip-it-and-ship-it": "15.3.0",
"@sindresorhus/slugify": "^2.0.0",
"ansi-escapes": "^7.0.0",
"ansis": "^4.1.0",
"clean-stack": "^5.0.0",
"execa": "^8.0.0",
"fast-string-width": "^3.0.2",
"fdir": "^6.0.1",
"figures": "^6.0.0",
"filter-obj": "^6.0.0",
"hot-shots": "11.4.0",
"ignore": "^7.0.0",
"indent-string": "^5.0.0",
"is-plain-obj": "^4.0.0",
"keep-func-props": "^6.0.0",
"log-process-errors": "^11.0.0",
"memoize-one": "^6.0.0",
"minimatch": "^10.2.4",
"os-name": "^6.0.0",
"p-event": "^6.0.0",
"p-filter": "^4.0.0",
"p-locate": "^6.0.0",
"p-map": "^7.0.0",
"p-reduce": "^3.0.0",
"package-directory": "^8.0.0",
"path-exists": "^5.0.0",
"pretty-ms": "^9.0.0",
"ps-list": "^8.0.0",
"read-package-up": "^11.0.0",
Expand Down
5 changes: 2 additions & 3 deletions packages/build/src/core/bin.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import { readFileSync } from 'fs'
import process from 'process'

import { includeKeys } from 'filter-obj'
import yargs from 'yargs'
import { hideBin } from 'yargs/helpers'

Expand All @@ -21,7 +20,7 @@ const packJson = JSON.parse(readFileSync(new URL('../../package.json', import.me
// sense only in CLI, such as CLI flags parsing and exit code.
const runCli = async function () {
const flags = parseFlags()
const flagsA = includeKeys(flags, isUserFlag)
const flagsA = Object.fromEntries(Object.entries(flags).filter(isUserFlag))

const state = { done: false }
process.on('exit', onExit.bind(undefined, state))
Expand Down Expand Up @@ -52,7 +51,7 @@ NETLIFY_BUILD_. For example the environment variable NETLIFY_BUILD_DRY=true can
be used instead of the CLI flag --dry.`

// Remove `yargs`-specific options, shortcuts, dash-cased and aliases
const isUserFlag = function (key, value) {
const isUserFlag = function ([key, value]) {
return value !== undefined && !INTERNAL_KEYS.has(key) && key.length !== 1 && !key.includes('-')
}

Expand Down
2 changes: 1 addition & 1 deletion packages/build/src/core/constants.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { relative, normalize, join } from 'path'

import { getCacheDir } from '@netlify/cache-utils'
import { pathExists } from 'path-exists'
import { pathExists } from '../utils/path_exists.js'

import { ROOT_PACKAGE_JSON } from '../utils/json.js'

Expand Down
18 changes: 14 additions & 4 deletions packages/build/src/core/dry.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import pFilter from 'p-filter'

import { logDryRunStart, logDryRunStep, logDryRunEnd } from '../log/messages/dry.js'
import { runsOnlyOnBuildFailure } from '../plugins/events.js'

Expand All @@ -13,9 +11,21 @@ export const doDryRun = async function ({
logs,
featureFlags,
}) {
const successSteps = await pFilter(steps, ({ event, condition }) =>
shouldIncludeStep({ buildDir, event, condition, netlifyConfig, constants, buildbotServerSocket, featureFlags }),
const includedSteps = await Promise.all(
steps.map(async (step) => {
const shouldInclude = await shouldIncludeStep({
buildDir,
event: step.event,
condition: step.condition,
netlifyConfig,
constants,
buildbotServerSocket,
featureFlags,
})
return shouldInclude ? step : null
}),
)
const successSteps = includedSteps.filter(Boolean)
const eventWidth = Math.max(...successSteps.map(getEventLength))
const stepsCount = successSteps.length

Expand Down
3 changes: 1 addition & 2 deletions packages/build/src/core/missing_side_file.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { relative } from 'path'

import { pathExists } from 'path-exists'

import { logMissingSideFile } from '../log/messages/core.js'
import { pathExists } from '../utils/path_exists.js'

// Some files like `_headers` and `_redirects` must be copied to the publishing
// directory to be used in production. When those are present in the repository
Expand Down
6 changes: 2 additions & 4 deletions packages/build/src/env/changes.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { env } from 'process'

import { includeKeys } from 'filter-obj'

// If plugins modify `process.env`, this is propagated in other plugins and in
// `build.command`. Since those are different processes, we figure out when they
// do this and communicate the new `process.env` to other processes.
Expand All @@ -12,8 +10,8 @@ export const getNewEnvChanges = function (envBefore, netlifyConfig, netlifyConfi
}

const diffEnv = function (envBefore, envAfter) {
const envChanges = includeKeys(envAfter, (name, value) => value !== envBefore[name])
const deletedEnv = includeKeys(envBefore, (name) => envAfter[name] === undefined)
const envChanges = Object.fromEntries(Object.entries(envAfter).filter(([name, value]) => value !== envBefore[name]))
const deletedEnv = Object.fromEntries(Object.entries(envBefore).filter(([name]) => envAfter[name] === undefined))
const deletedEnvA = Object.fromEntries(Object.entries(deletedEnv).map(setToNull))
return { ...envChanges, ...deletedEnvA }
}
Expand Down
4 changes: 1 addition & 3 deletions packages/build/src/env/main.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { env } from 'process'

import { includeKeys } from 'filter-obj'

import { getParentColorEnv } from '../log/colors.js'

// Retrieve the environment variables passed to plugins and `build.command`
// When run locally, this tries to emulate the production environment.
export const getChildEnv = function ({ envOpt, env: allConfigEnv }) {
const parentColorEnv = getParentColorEnv()
const parentEnv = { ...env, ...allConfigEnv, ...envOpt, ...parentColorEnv }
return includeKeys(parentEnv, shouldKeepEnv)
return Object.fromEntries(Object.entries(parentEnv).filter(([key]) => shouldKeepEnv(key)))
}

const shouldKeepEnv = function (key: string) {
Expand Down
4 changes: 1 addition & 3 deletions packages/build/src/env/metadata.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { env } from 'process'

import { includeKeys } from 'filter-obj'

// Retrieve environment variables used in error monitoring
export const getEnvMetadata = function (childEnv = env) {
return includeKeys(childEnv, isEnvMetadata)
return Object.fromEntries(Object.entries(childEnv).filter(([name]) => isEnvMetadata(name)))
}

const isEnvMetadata = function (name) {
Expand Down
6 changes: 3 additions & 3 deletions packages/build/src/error/api.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import isPlainObj from 'is-plain-obj'
import { isPlainObject } from '../utils/is_plain_object.js'

import { addErrorInfo } from './info.js'

Expand Down Expand Up @@ -34,8 +34,8 @@ const apiMethodHandler = async function (endpoint, method, parameters, ...args)
const redactError = function (error) {
if (
error instanceof Error &&
isPlainObj(error.data) &&
isPlainObj(error.data.headers) &&
isPlainObject(error.data) &&
isPlainObject(error.data.headers) &&
typeof error.data.headers.Authorization === 'string'
) {
error.data.headers.Authorization = error.data.headers.Authorization.replace(HEX_REGEXP, 'HEX')
Expand Down
2 changes: 1 addition & 1 deletion packages/build/src/error/handle.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { cwd as getCwd } from 'process'

import { pathExists } from 'path-exists'
import { pathExists } from '../utils/path_exists.js'

import { ErrorParam } from '../core/types.js'
import { logBuildError } from '../log/messages/core.js'
Expand Down
21 changes: 9 additions & 12 deletions packages/build/src/error/parse/clean_stack.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { stripVTControlCharacters } from 'node:util'
import { cwd } from 'process'

import cleanStack from 'clean-stack'

// Clean stack traces:
// - remove our internal code, e.g. the logic spawning plugins
// - remove node modules and Node.js internals
Expand Down Expand Up @@ -37,13 +35,7 @@ const cleanStackLine = function (lines, line) {
return lines
}

const lineC = cleanStack(lineB)

if (lineC === '') {
return lines
}

return `${lines}\n${lineC}`
return `${lines}\n${lineB}`
}

// `process.cwd()` can sometimes fail: directory name too long, current
Expand All @@ -61,7 +53,12 @@ const STACK_LINE_REGEXP = /^\s+at /

const shouldRemoveStackLine = function (line) {
const lineA = normalizePathSlashes(line)
return INTERNAL_STACK_STRINGS.some((stackString) => lineA.includes(stackString)) || INTERNAL_STACK_REGEXP.test(lineA)

return (
INTERNAL_STACK_STRINGS.some((stackString) => lineA.includes(stackString)) ||
INTERNAL_STACK_REGEXP.test(lineA) ||
NODE_STACK_REGEXP.test(lineA)
)
}

const INTERNAL_STACK_STRINGS = [
Expand All @@ -71,10 +68,10 @@ const INTERNAL_STACK_STRINGS = [
// nyc internal code
'node_modules/append-transform',
'node_modules/signal-exit',
// Node internals
'(node:',
]

const NODE_STACK_REGEXP = /\bnode:|\(native\)|\bat native\b/

// This is only needed for local builds and tests
const INTERNAL_STACK_REGEXP = /(lib\/|tests\/helpers\/|tests\/.*\/tests.js|node_modules)/

Expand Down
2 changes: 1 addition & 1 deletion packages/build/src/install/main.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { homedir } from 'os'

import { execa } from 'execa'
import { pathExists } from 'path-exists'

import { addErrorInfo } from '../error/info.js'
import { pathExists } from '../utils/path_exists.js'

// Install Node.js dependencies in a specific directory
export const installDependencies = function ({ packageRoot, isLocal }) {
Expand Down
3 changes: 1 addition & 2 deletions packages/build/src/install/missing.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import { promises as fs } from 'node:fs'
import { normalize } from 'node:path'
import { fileURLToPath } from 'node:url'

import { pathExists } from 'path-exists'

import { logInstallMissingPlugins, logInstallIntegrations } from '../log/messages/install.js'
import { pathExists } from '../utils/path_exists.js'

import { addExactDependencies } from './main.js'

Expand Down
11 changes: 3 additions & 8 deletions packages/build/src/log/messages/core.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import ansiEscapes from 'ansi-escapes'
import prettyMs from 'pretty-ms'

import { getFullErrorInfo } from '../../error/parse/parse.js'
Expand Down Expand Up @@ -52,9 +51,8 @@ A "${sideFile}" file is present in the repository but is missing in the publish
)
}

// @todo use `terminal-link` (https://github.com/sindresorhus/terminal-link)
// instead of `ansi-escapes` once
// https://github.com/jamestalmage/supports-hyperlinks/pull/12 is fixed
const ansiLink = (text: string, url: string) => `\u001B]8;;${url}\u0007${text}\u001B]8;;\u0007`

export const logLingeringProcesses = function (logs, commands) {
logWarning(
logs,
Expand All @@ -66,9 +64,6 @@ The build completed successfully, but the following processes were still running
logWarning(
logs,
`
These processes have been terminated. In case this creates a problem for your build, refer to this ${ansiEscapes.link(
'article',
'https://answers.netlify.com/t/support-guide-how-to-address-the-warning-message-related-to-terminating-processes-in-builds/35277',
)} for details about why this process termination happens and how to fix it.`,
These processes have been terminated. In case this creates a problem for your build, refer to this ${ansiLink('article', 'https://answers.netlify.com/t/support-guide-how-to-address-the-warning-message-related-to-terminating-processes-in-builds/35277')} for details about why this process termination happens and how to fix it.`,
)
}
3 changes: 1 addition & 2 deletions packages/build/src/log/messages/mutations.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { promises as fs } from 'fs'
import { inspect } from 'util'

import { pathExists } from 'path-exists'

import { pathExists } from '../../utils/path_exists.js'
import { log, logMessage, logSubHeader } from '../logger.js'

export const logConfigMutations = function (logs, newConfigMutations, debug) {
Expand Down
5 changes: 3 additions & 2 deletions packages/build/src/plugins/child/diff.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { isDeepStrictEqual } from 'util'

import isPlainObj from 'is-plain-obj'
import rfdc from 'rfdc'

import { isPlainObject } from '../../utils/is_plain_object.js'

const clone = rfdc()

// Copy `netlifyConfig` so we can compare before/after mutating it
Expand Down Expand Up @@ -32,7 +33,7 @@ const diffObjects = function (objA, objB, parentKeys) {
const valueB = objB[key]
const keys = [...parentKeys, key]

if (isPlainObj(valueA) && isPlainObj(valueB)) {
if (isPlainObject(valueA) && isPlainObject(valueB)) {
return diffObjects(valueA, valueB, keys)
}

Expand Down
Loading
Loading