Skip to content
This repository has been archived by the owner on May 22, 2024. It is now read-only.

feat: Make additional function attributes available via functions manifest #1221

Merged
merged 26 commits into from
Jan 12, 2023
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
209b447
feat: pass additional-function-attributes
jackiewmacharia Oct 12, 2022
61a564e
chore: make attributes available to functions manifest
jackiewmacharia Oct 14, 2022
b39c535
fix: fix linting
jackiewmacharia Oct 14, 2022
5f6e420
fix: use optional chaining
jackiewmacharia Oct 14, 2022
7a55dc3
fix: add ext
jackiewmacharia Nov 21, 2022
8a0a033
fix: fix tests
jackiewmacharia Nov 21, 2022
06e2c09
fix: change internal directory name in constants.ts
khendrikse Jan 9, 2023
ee0c043
feat: add test for go functions with displayName and from an internal…
khendrikse Jan 9, 2023
ccadb79
feat: add test for rust functions build from internal folder with dis…
khendrikse Jan 9, 2023
be4d323
feat: add test for nodejs functions build from internal folder with d…
khendrikse Jan 9, 2023
4901e39
test: figure out windows breakn
khendrikse Jan 9, 2023
4380c3f
fix: take windows paths into account when checking for internal funct…
khendrikse Jan 9, 2023
67c39ea
test: add unit test for checkIsInternalFunction
khendrikse Jan 10, 2023
825cf20
docs: add new return values
khendrikse Jan 10, 2023
c9c31bf
test: move tests into a better fixtures structure
khendrikse Jan 10, 2023
0b617d0
fix: use unixify for checkIsInternalFunction, config, bundler, module…
khendrikse Jan 11, 2023
e7b17b5
feat: add internalFunctionsFolder option to zipfunctionoptions
khendrikse Jan 11, 2023
9f5b99b
test: fix tests
khendrikse Jan 11, 2023
8858617
test: add test for zipFunction and code to support that as well
khendrikse Jan 11, 2023
196933d
test: change toBeTruthy to toBe(true) and isInternalFunction to inter…
khendrikse Jan 11, 2023
ab7f943
chore: change displayName input to name
khendrikse Jan 11, 2023
8e02225
chore: change internalFunction to isInternal
khendrikse Jan 11, 2023
17150e2
chore: revert unixify, rename tests and internalFunctionsFolder to in…
khendrikse Jan 12, 2023
b444d1c
test: revert unixify for module to see if windows test still fails
khendrikse Jan 12, 2023
4e77889
Revert "test: revert unixify for module to see if windows test still …
khendrikse Jan 12, 2023
be0654d
Merge branch 'main' into feat/pass-additional-function-attributes
khendrikse Jan 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 22 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ The following properties are accepted:
The `[name]` placeholder will be replaced by the name of the function, allowing you to use it to construct the path to
the target directory.

- `name`

A name to use when displaying the function in the Netlify UI. Populates the `displayName` property in the functions manifest for the specified function.

#### `featureFlags`

See [feature flags](#feature-flags).
Expand All @@ -159,7 +163,7 @@ See [feature flags](#feature-flags).
- _Type_: `string`
- _Default value_: `undefined`

Defines the path for a manifest file to be created with the results of the functions bundling. This file is a
Defines the full path, including the file name, to use for the manifest file that will be created with the functions bundling results. For example, `path/to/manifest.json`. This file is a
JSON-formatted string with the following properties:

- `functions`: An array with the functions created, in the same format as returned by `zipFunctions`
Expand All @@ -172,11 +176,18 @@ JSON-formatted string with the following properties:

#### `parallelLimit`

- _Type_: `number`\
- _Type_: `number`
- _Default value_: `5`

Maximum number of functions to bundle at the same time.

#### `internalFunctionsFolder`
khendrikse marked this conversation as resolved.
Show resolved Hide resolved

- _Type_: `string`
- _Default value_: `undefined`

Defines the path to the folder with internal functions. Used to populate a function's `isInternal` property, if its path is within this specified internal functions folder.

### Return value

This returns a `Promise` resolving to an array of objects describing each archive. Every object has the following
Expand All @@ -202,6 +213,14 @@ properties.

The size of the generated archive, in bytes.

- `isInternal` `boolean`

If the function path has a match with the `internalFunctionsFolder` property, this boolean will be true.

- `displayName` `string`

If there was a user-defined configuration object applied to the function, and it had a `name` defined. This will be returned here.

Additionally, the following properties also exist for Node.js functions:

- `bundler`: `string`
Expand Down Expand Up @@ -257,7 +276,7 @@ Additionally, the following properties also exist for Node.js functions:
```js
import { zipFunction } from '@netlify/zip-it-and-ship-it'

const archive = await zipFunctions('functions/function.js', 'functions-dist')
const archive = await zipFunction('functions/function.js', 'functions-dist')
```

This is like [`zipFunctions()`](#zipfunctionssrcfolder-destfolder-options) except it bundles a single Function.
Expand Down
1 change: 1 addition & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ interface FunctionConfig {
rustTargetDirectory?: string
schedule?: string
zipGo?: boolean
name?: string

// Temporary configuration property, only meant to be used by the deploy
// configuration API. Once we start emitting ESM files for all ESM functions,
Expand Down
17 changes: 16 additions & 1 deletion src/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ interface ManifestFunction {
path: string
runtime: string
schedule?: string
displayName?: string
bundler?: string
isInternal?: boolean
}

export interface Manifest {
Expand All @@ -36,10 +39,22 @@ export const createManifest = async ({ functions, path }: { functions: FunctionR
await fs.writeFile(path, JSON.stringify(payload))
}

const formatFunctionForManifest = ({ mainFile, name, path, runtime, schedule }: FunctionResult): ManifestFunction => ({
const formatFunctionForManifest = ({
mainFile,
name,
path,
runtime,
schedule,
displayName,
bundler,
isInternal,
}: FunctionResult): ManifestFunction => ({
mainFile,
name,
path: resolve(path),
runtime,
schedule,
displayName,
bundler,
isInternal,
})
18 changes: 16 additions & 2 deletions src/runtimes/go/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,16 @@ const processSource = async ({
}
}

const zipFunction: ZipFunction = async function ({ config, destFolder, filename, mainFile, srcDir, srcPath, stat }) {
const zipFunction: ZipFunction = async function ({
config,
destFolder,
filename,
mainFile,
srcDir,
srcPath,
stat,
isInternal,
}) {
const destPath = join(destFolder, filename)
const isSource = extname(mainFile) === '.go'

Expand Down Expand Up @@ -151,7 +160,12 @@ const zipFunction: ZipFunction = async function ({ config, destFolder, filename,
await copyFile(binary.path, destPath)
}

return { config, path: destPath }
return {
config,
path: destPath,
displayName: config?.name,
isInternal,
}
}

const runtime: Runtime = { findFunctionsInPaths, findFunctionInPath, name: RuntimeType.GO, zipFunction }
Expand Down
5 changes: 2 additions & 3 deletions src/runtimes/node/bundlers/zisi/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ import { pathExists } from 'path-exists'
// @ts-expect-error types are wrong
import { async as asyncResolve } from 'resolve'
import semver from 'semver'
import unixify from 'unixify'

// The types do not include the mjs api of resolve
const resolveLib = asyncResolve as typeof import('resolve')

const require = createRequire(import.meta.url)

const BACKSLASH_REGEXP = /\\/g

// Find the path to a module's `package.json`
// We need to use `resolve` instead of `require.resolve()` because:
// - it is async
Expand Down Expand Up @@ -107,7 +106,7 @@ const resolvePackageFallback = async function (moduleName: string, baseDirs: str
const isPackageDir = async function (moduleName: string, dir: string) {
// Need to use `endsWith()` to take into account `@scope/package`.
// Backslashes need to be converted for Windows.
if (!dir.replace(BACKSLASH_REGEXP, '/').endsWith(moduleName) || !(await pathExists(`${dir}/package.json`))) {
if (!unixify(dir).endsWith(moduleName) || !(await pathExists(`${dir}/package.json`))) {
khendrikse marked this conversation as resolved.
Show resolved Hide resolved
return
}

Expand Down
3 changes: 3 additions & 0 deletions src/runtimes/node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const zipFunction: ZipFunction = async function ({
srcDir,
srcPath,
stat,
isInternal,
}) {
const pluginsModulesPath = await getPluginsModulesPath(srcDir)
const bundlerName = await getBundlerName({
Expand Down Expand Up @@ -126,6 +127,8 @@ const zipFunction: ZipFunction = async function ({
nativeNodeModules,
nodeModulesWithDynamicImports,
path: zipPath,
displayName: config?.name,
isInternal,
}
}

Expand Down
7 changes: 3 additions & 4 deletions src/runtimes/node/utils/module.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import requirePackageName from 'require-package-name'

// Windows path normalization
const BACKSLASH_REGEXP = /\\/g
import unixify from 'unixify'

// When doing require("moduleName/file/path"), only keep `moduleName`
export const getModuleName = function (dependency: string): string {
const dependencyA = dependency.replace(BACKSLASH_REGEXP, '/')
// Windows path normalization
const dependencyA = unixify(dependency)
khendrikse marked this conversation as resolved.
Show resolved Hide resolved
const moduleName = requirePackageName(dependencyA)

return moduleName
Expand Down
3 changes: 3 additions & 0 deletions src/runtimes/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export interface ZipFunctionResult {
nativeNodeModules?: object
nodeModulesWithDynamicImports?: string[]
path: string
isInternal?: boolean
displayName?: string
}

export type ZipFunction = (
Expand All @@ -56,6 +58,7 @@ export type ZipFunction = (
destFolder: string
featureFlags: FeatureFlags
repositoryRoot?: string
isInternal?: boolean
} & FunctionSource,
) => Promise<ZipFunctionResult>

Expand Down
8 changes: 7 additions & 1 deletion src/runtimes/rust/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ const zipFunction: ZipFunction = async function ({
srcDir,
srcPath,
stat,
isInternal,
}) {
const destPath = join(destFolder, `${filename}.zip`)
const isSource = extname(mainFile) === '.rs'
Expand All @@ -157,7 +158,12 @@ const zipFunction: ZipFunction = async function ({
await zipBinary({ ...zipOptions, srcPath, stat })
}

return { config, path: destPath }
return {
config,
path: destPath,
displayName: config?.name,
isInternal,
}
}

const runtime: Runtime = { findFunctionsInPaths, findFunctionInPath, name: RuntimeType.RUST, zipFunction }
Expand Down
10 changes: 10 additions & 0 deletions src/zip.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { promises as fs } from 'fs'
import { resolve } from 'path'

import isPathInside from 'is-path-inside'
import pMap from 'p-map'

import { ArchiveFormat } from './archive.js'
Expand All @@ -27,12 +28,14 @@ interface ZipFunctionOptions {
zipGo?: boolean
systemLog?: LogFunction
debug?: boolean
internalFunctionsFolder?: string
}

export type ZipFunctionsOptions = ZipFunctionOptions & {
configFileDirectories?: string[]
manifest?: string
parallelLimit?: number
internalFunctionsFolder?: string
}

const DEFAULT_PARALLEL_LIMIT = 5
Expand Down Expand Up @@ -60,6 +63,7 @@ export const zipFunctions = async function (
repositoryRoot = basePath,
systemLog,
debug,
internalFunctionsFolder,
}: ZipFunctionsOptions = {},
) {
validateArchiveFormat(archiveFormat)
Expand All @@ -68,6 +72,8 @@ export const zipFunctions = async function (
const cache = new RuntimeCache()
const featureFlags = getFlags(inputFeatureFlags)
const srcFolders = resolveFunctionsDirectories(relativeSrcFolders)
const internalFunctionsPath = internalFunctionsFolder && resolve(internalFunctionsFolder)

const [paths] = await Promise.all([listFunctionsDirectories(srcFolders), fs.mkdir(destFolder, { recursive: true })])
const functions = await getFunctionsFromPaths(paths, {
cache,
Expand Down Expand Up @@ -104,6 +110,7 @@ export const zipFunctions = async function (
srcDir: func.srcDir,
srcPath: func.srcPath,
stat: func.stat,
isInternal: Boolean(internalFunctionsPath && isPathInside(func.srcPath, internalFunctionsPath)),
})
const durationNs = endTimer(startIntervalTime)
const logObject = {
Expand Down Expand Up @@ -148,6 +155,7 @@ export const zipFunction = async function (
repositoryRoot = basePath,
systemLog,
debug,
internalFunctionsFolder,
}: ZipFunctionOptions = {},
) {
validateArchiveFormat(archiveFormat)
Expand All @@ -157,6 +165,7 @@ export const zipFunction = async function (
const srcPath = resolve(relativeSrcPath)
const cache = new RuntimeCache()
const functions = await getFunctionsFromPaths([srcPath], { cache, config: inputConfig, dedupe: true, featureFlags })
const internalFunctionsPath = internalFunctionsFolder && resolve(internalFunctionsFolder)

if (functions.size === 0) {
return
Expand Down Expand Up @@ -199,6 +208,7 @@ export const zipFunction = async function (
srcDir,
srcPath,
stat: stats,
isInternal: Boolean(internalFunctionsPath && isPathInside(srcPath, internalFunctionsPath)),
})
const durationNs = endTimer(startIntervalTime)
const logObject = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package main

import (
"fmt"
)

func main() {
fmt.Println("Hello, world!")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package main

import (
"fmt"
)

func main() {
fmt.Println("Hello, world!")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/netlify/zip-it-and-ship-it/tests/fixtures/go-source

go 1.15
1 change: 1 addition & 0 deletions tests/fixtures/node-display-name/function-1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = true
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = true
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = true
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/target