Correctly identify dependency versions chosen by Go

This commit is contained in:
Lane Seppala
2022-06-16 22:46:09 -06:00
parent 9a1dc9e4d6
commit be130df09a
8 changed files with 282 additions and 163 deletions
+79 -22
View File
@@ -72,8 +72,28 @@ function main() {
}
}
}
const packageCache = yield (0, process_1.processGoGraph)(goModDir);
const manifest = yield (0, process_1.processGoBuildTarget)(goModDir, goBuildTarget, packageCache);
const directDeps = yield (0, process_1.processGoDirectDependencies)(goModDir, goBuildTarget);
const indirectDeps = yield (0, process_1.processGoIndirectDependencies)(goModDir, goBuildTarget);
const packageCache = yield (0, process_1.processGoGraph)(goModDir, directDeps, indirectDeps);
// no file path if using the pseudotargets "all" or "./..."
const filepath = goBuildTarget === 'all' || goBuildTarget === './...'
? undefined
: path_1.default.join(goModDir, goBuildTarget);
const manifest = new dependency_submission_toolkit_1.Manifest(goBuildTarget, filepath);
directDeps.forEach((pkgUrl) => {
const dep = packageCache.lookupPackage(pkgUrl);
if (!dep) {
throw new Error('assertion failed: expected all direct dependencies to have entries in PackageCache');
}
manifest.addDirectDependency(dep);
});
indirectDeps.forEach((pkgUrl) => {
const dep = packageCache.lookupPackage(pkgUrl);
if (!dep) {
throw new Error('assertion failed: expected all indirect dependencies to have entries in PackageCache');
}
manifest.addIndirectDependency(dep);
});
const snapshot = new dependency_submission_toolkit_1.Snapshot({
name: 'actions/go-dependency-submission',
url: 'https://github.com/actions/go-dependency-submission',
@@ -194,17 +214,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.processGoBuildTarget = exports.processGoGraph = void 0;
const path_1 = __importDefault(__nccwpck_require__(1017));
exports.processGoIndirectDependencies = exports.processGoDirectDependencies = exports.processGoGraph = void 0;
const exec = __importStar(__nccwpck_require__(1514));
const core = __importStar(__nccwpck_require__(2186));
const dependency_submission_toolkit_1 = __nccwpck_require__(9810);
const parse_1 = __nccwpck_require__(5933);
function processGoGraph(goModDir) {
function processGoGraph(goModDir, directDependencies, indirectDependencies) {
return __awaiter(this, void 0, void 0, function* () {
console.log(`Running 'go mod graph' in ${goModDir}`);
const goModGraph = yield exec.getExecOutput('go', ['mod', 'graph'], {
@@ -215,39 +231,80 @@ function processGoGraph(goModDir) {
core.setFailed("'go mod graph' failed!");
throw new Error("Failed to execute 'go mod graph'");
}
/* add all direct and indirect packages to a new PackageCache */
const cache = new dependency_submission_toolkit_1.PackageCache();
directDependencies.forEach((pkg) => {
cache.package(pkg);
});
indirectDependencies.forEach((pkg) => {
cache.package(pkg);
});
const packageAssocList = (0, parse_1.parseGoModGraph)(goModGraph.stdout);
packageAssocList.forEach(([parentPkg, childPkg]) => {
cache.package(parentPkg).dependsOn(cache.package(childPkg));
/* Look up the parent package in the cache. go mod graph will return
* multiple versions of packages with the same namespace and name. We
* select only package versions used in the Go build target. */
const targetPackage = cache.lookupPackage(parentPkg);
if (!targetPackage)
return;
/* Build a matcher to select on the namespace+name of the child package in
* the cache. The child package version specified by go mod graph is not
* the one guaranteed to be selected when building Go build targets. */
const matcher = {
name: childPkg.name
};
if (childPkg.namespace)
matcher.namespace = childPkg.namespace;
/* There should only ever be a single package with a namespace+name in the
* build target list. Go does not support multiple versions of the same
* package */
const matches = cache.packagesMatching(matcher);
if (matches.length !== 1) {
throw new Error('assertion failed: expected one package in cache with namespace+name. ' +
'Found: ' +
JSON.stringify(matches));
}
// create the dependency relationship
targetPackage.dependsOn(matches[0]);
});
return cache;
});
}
exports.processGoGraph = processGoGraph;
// For a specific Go _build target_, this template lists all dependencies used
// to build the build target It does not provide association between the
// For a specific Go _build target_, these templates list dependencies used to
// in the build target. It does not provide association between the
// dependencies (i.e. which dependencies depend on which)
// eslint-disable-next-line quotes
// eslint-disable-next-line no-useless-escape
const GO_LIST_DEP_TEMPLATE = '{{define "M"}}{{.Path}}@{{.Version}}{{end}}{{with .Module}}{{if not .Main}}{{if .Replace}}{{template "M" .Replace}}{{else}}{{template "M" .}}{{end}}{{end}}{{end}}';
function processGoBuildTarget(goModDir, goBuildTarget, cache) {
const GO_DIRECT_DEPS_TEMPLATE = '{{define "M"}}{{if not .Indirect}}{{.Path}}@{{.Version}}{{end}}{{end}}{{with .Module}}{{if not .Main}}{{if .Replace}}{{template "M" .Replace}}{{else}}{{template "M" .}}{{end}}{{end}}{{end}}';
// eslint-disable-next-line quotes
// eslint-disable-next-line no-useless-escape
const GO_INDIRECT_DEPS_TEMPLATE = '{{define "M"}}{{if .Indirect}}{{.Path}}@{{.Version}}{{end}}{{end}}{{with .Module}}{{if not .Main}}{{if .Replace}}{{template "M" .Replace}}{{else}}{{template "M" .}}{{end}}{{end}}{{end}}';
function processGoDirectDependencies(goModDir, goBuildTarget) {
return __awaiter(this, void 0, void 0, function* () {
console.log(`Running go package detection in ${goModDir} on build target ${goBuildTarget}`);
const goList = yield exec.getExecOutput('go', ['list', '-deps', '-f', GO_LIST_DEP_TEMPLATE, goBuildTarget], { cwd: goModDir });
console.log(`go direct package detection in ${goModDir} on build target ${goBuildTarget}`);
return processGoList(goModDir, goBuildTarget, GO_DIRECT_DEPS_TEMPLATE);
});
}
exports.processGoDirectDependencies = processGoDirectDependencies;
function processGoIndirectDependencies(goModDir, goBuildTarget) {
return __awaiter(this, void 0, void 0, function* () {
console.log(`go indirect package detection in ${goModDir} on build target ${goBuildTarget}`);
return processGoList(goModDir, goBuildTarget, GO_INDIRECT_DEPS_TEMPLATE);
});
}
exports.processGoIndirectDependencies = processGoIndirectDependencies;
function processGoList(goModDir, goBuildTarget, goListTemplate) {
return __awaiter(this, void 0, void 0, function* () {
const goList = yield exec.getExecOutput('go', ['list', '-deps', '-f', goListTemplate, goBuildTarget], { cwd: goModDir });
if (goList.exitCode !== 0) {
core.error(goList.stderr);
core.setFailed("'go list' failed!");
throw new Error("Failed to execute 'go list'");
}
const dependencies = (0, parse_1.parseGoList)(goList.stdout);
const manifest = new dependency_submission_toolkit_1.BuildTarget(goBuildTarget, path_1.default.join(goModDir, goBuildTarget));
dependencies.forEach((dep) => {
manifest.addBuildDependency(cache.package(dep));
});
return manifest;
return (0, parse_1.parseGoList)(goList.stdout);
});
}
exports.processGoBuildTarget = processGoBuildTarget;
/***/ }),
+1 -1
View File
File diff suppressed because one or more lines are too long
-87
View File
@@ -1,87 +0,0 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.processGoBuildTarget = exports.processGoGraph = void 0;
const path_1 = __importDefault(require("path"));
const exec = __importStar(require("@actions/exec"));
const core = __importStar(require("@actions/core"));
const dependency_submission_toolkit_1 = require("@github/dependency-submission-toolkit");
const parse_1 = require("./parse");
function processGoGraph(goModDir) {
return __awaiter(this, void 0, void 0, function* () {
console.log(`Running 'go mod graph' in ${goModDir}`);
const goModGraph = yield exec.getExecOutput('go', ['mod', 'graph'], {
cwd: goModDir
});
if (goModGraph.exitCode !== 0) {
core.error(goModGraph.stderr);
core.setFailed("'go mod graph' failed!");
throw new Error("Failed to execute 'go mod graph'");
}
const cache = new dependency_submission_toolkit_1.PackageCache();
const packageAssocList = (0, parse_1.parseGoModGraph)(goModGraph.stdout);
packageAssocList.forEach(([parentPkg, childPkg]) => {
cache.package(parentPkg).dependsOn(cache.package(childPkg));
});
return cache;
});
}
exports.processGoGraph = processGoGraph;
// For a specific Go _build target_, this template lists all dependencies used
// to build the build target It does not provide association between the
// dependencies (i.e. which dependencies depend on which)
// eslint-disable-next-line quotes
// eslint-disable-next-line no-useless-escape
const GO_LIST_DEP_TEMPLATE = '{{define "M"}}{{.Path}}@{{.Version}}{{end}}{{with .Module}}{{if not .Main}}{{if .Replace}}{{template "M" .Replace}}{{else}}{{template "M" .}}{{end}}{{end}}{{end}}';
function processGoBuildTarget(goModDir, goBuildTarget, cache) {
return __awaiter(this, void 0, void 0, function* () {
console.log(`Running go package detection in ${goModDir} on build target ${goBuildTarget}`);
const goList = yield exec.getExecOutput('go', ['list', '-deps', '-f', GO_LIST_DEP_TEMPLATE, goBuildTarget], { cwd: goModDir });
if (goList.exitCode !== 0) {
core.error(goList.stderr);
core.setFailed("'go list' failed!");
throw new Error("Failed to execute 'go list'");
}
const dependencies = (0, parse_1.parseGoList)(goList.stdout);
const manifest = new dependency_submission_toolkit_1.BuildTarget(goBuildTarget, path_1.default.join(goModDir, goBuildTarget));
dependencies.forEach((dep) => {
manifest.addBuildDependency(cache.package(dep));
});
return manifest;
});
}
exports.processGoBuildTarget = processGoBuildTarget;
+7 -7
View File
@@ -12,7 +12,7 @@
"@actions/core": "^1.6.0",
"@actions/exec": "^1.1.1",
"@actions/github": "^5.0.3",
"@github/dependency-submission-toolkit": "^1.1.2",
"@github/dependency-submission-toolkit": "^1.2.0",
"packageurl-js": "^0.0.6"
},
"devDependencies": {
@@ -673,9 +673,9 @@
}
},
"node_modules/@github/dependency-submission-toolkit": {
"version": "1.1.2",
"resolved": "https://npm.pkg.github.com/download/@github/dependency-submission-toolkit/1.1.2/742faf4570a1f30532adc02edde4b27b7bd6b9439ce9bb39c2322eaca07239e1",
"integrity": "sha512-uJyVJN9fUJf2djNLT9mNwBSbkQ+AdYuOBmUffHnHFhF+3kCN6zqy3m+3Iw//Ixln7kpe8qN7W0ZVGFOesXYZXA==",
"version": "1.2.0",
"resolved": "https://npm.pkg.github.com/download/@github/dependency-submission-toolkit/1.2.0/cd4d278f4bad1f7056d73bc205b8c7484980f7ffcb9c52c1df36dbc366a6221c",
"integrity": "sha512-b51hiCwNDO9Eim2MPvyeTDD1XxN7gpptRLGtUsnTpf8kcCILnVSbmbwjLfj4HNDbzg05yqfqW5jnI6ET2aFIqA==",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.6.0",
@@ -6383,9 +6383,9 @@
}
},
"@github/dependency-submission-toolkit": {
"version": "1.1.2",
"resolved": "https://npm.pkg.github.com/download/@github/dependency-submission-toolkit/1.1.2/742faf4570a1f30532adc02edde4b27b7bd6b9439ce9bb39c2322eaca07239e1",
"integrity": "sha512-uJyVJN9fUJf2djNLT9mNwBSbkQ+AdYuOBmUffHnHFhF+3kCN6zqy3m+3Iw//Ixln7kpe8qN7W0ZVGFOesXYZXA==",
"version": "1.2.0",
"resolved": "https://npm.pkg.github.com/download/@github/dependency-submission-toolkit/1.2.0/cd4d278f4bad1f7056d73bc205b8c7484980f7ffcb9c52c1df36dbc366a6221c",
"integrity": "sha512-b51hiCwNDO9Eim2MPvyeTDD1XxN7gpptRLGtUsnTpf8kcCILnVSbmbwjLfj4HNDbzg05yqfqW5jnI6ET2aFIqA==",
"requires": {
"@actions/core": "^1.6.0",
"@actions/exec": "^1.1.1",
+1 -1
View File
@@ -43,7 +43,7 @@
"@actions/core": "^1.6.0",
"@actions/exec": "^1.1.1",
"@actions/github": "^5.0.3",
"@github/dependency-submission-toolkit": "^1.1.2",
"@github/dependency-submission-toolkit": "^1.2.0",
"packageurl-js": "^0.0.6"
}
}
+41 -6
View File
@@ -3,9 +3,17 @@ import fs from 'fs'
import * as core from '@actions/core'
import * as github from '@actions/github'
import { Snapshot, submitSnapshot } from '@github/dependency-submission-toolkit'
import {
Snapshot,
Manifest,
submitSnapshot
} from '@github/dependency-submission-toolkit'
import { processGoGraph, processGoBuildTarget } from './process'
import {
processGoGraph,
processGoDirectDependencies,
processGoIndirectDependencies
} from './process'
async function main () {
const goModPath = path.normalize(core.getInput('go-mod-path'))
@@ -35,12 +43,39 @@ async function main () {
}
}
const packageCache = await processGoGraph(goModDir)
const manifest = await processGoBuildTarget(
const directDeps = await processGoDirectDependencies(goModDir, goBuildTarget)
const indirectDeps = await processGoIndirectDependencies(
goModDir,
goBuildTarget,
packageCache
goBuildTarget
)
const packageCache = await processGoGraph(goModDir, directDeps, indirectDeps)
// no file path if using the pseudotargets "all" or "./..."
const filepath =
goBuildTarget === 'all' || goBuildTarget === './...'
? undefined
: path.join(goModDir, goBuildTarget)
const manifest = new Manifest(goBuildTarget, filepath)
directDeps.forEach((pkgUrl) => {
const dep = packageCache.lookupPackage(pkgUrl)
if (!dep) {
throw new Error(
'assertion failed: expected all direct dependencies to have entries in PackageCache'
)
}
manifest.addDirectDependency(dep)
})
indirectDeps.forEach((pkgUrl) => {
const dep = packageCache.lookupPackage(pkgUrl)
if (!dep) {
throw new Error(
'assertion failed: expected all indirect dependencies to have entries in PackageCache'
)
}
manifest.addIndirectDependency(dep)
})
const snapshot = new Snapshot(
{
name: 'actions/go-dependency-submission',
+78 -9
View File
@@ -1,17 +1,86 @@
import { processGoGraph, processGoBuildTarget } from './process'
import {
processGoGraph,
processGoDirectDependencies,
processGoIndirectDependencies
} from './process'
// NOTE: these tests all require "go" to be installed and available on the PATH!
//
describe('processGoGraph', () => {
describe('processGoDirectDependencies', () => {
test('run in go-example', async () => {
const cache = await processGoGraph('go-example')
expect(cache.countPackages()).toEqual(8)
const manifest = await processGoBuildTarget(
const purls = await processGoDirectDependencies(
'go-example',
'cmd/octocat.go',
cache
'cmd/octocat.go'
)
expect(manifest.directDependencies()).toHaveLength(4)
expect(manifest.indirectDependencies()).toHaveLength(2)
expect(purls).toHaveLength(1)
expect(purls).toEqual([
{
type: 'golang',
name: 'color',
namespace: 'github.com/fatih',
version: 'v1.13.0',
qualifiers: null,
subpath: null
}
])
})
})
describe('processGoIndirectDependencies', () => {
test('run in go-example', async () => {
const purls = await processGoIndirectDependencies(
'go-example',
'cmd/octocat.go'
)
expect(purls).toHaveLength(3)
expect(purls).toEqual([
{
type: 'golang',
name: 'sys',
namespace: 'golang.org/x',
version: 'v0.0.0-20210630005230-0f9fa26af87c',
qualifiers: null,
subpath: null
},
{
type: 'golang',
name: 'go-isatty',
namespace: 'github.com/mattn',
version: 'v0.0.14',
qualifiers: null,
subpath: null
},
{
type: 'golang',
name: 'go-colorable',
namespace: 'github.com/mattn',
version: 'v0.1.9',
qualifiers: null,
subpath: null
}
])
})
})
describe('processGoGraph', () => {
test.only('run in go-example', async () => {
const directDeps = await processGoDirectDependencies(
'go-example',
'cmd/octocat.go'
)
const indirectDeps = await processGoIndirectDependencies(
'go-example',
'cmd/octocat.go'
)
const cache = await processGoGraph('go-example', directDeps, indirectDeps)
// we expect the number of direct dependencies + indirect
expect(cache.countPackages()).toEqual(4)
const colorDep = cache.lookupPackage(
'pkg:golang/github.com/fatih/color@v1.13.0'
)
expect(colorDep).not.toBeUndefined()
if (colorDep) expect(colorDep.dependencies).toHaveLength(2)
})
})
+75 -30
View File
@@ -1,16 +1,16 @@
import path from 'path'
import { PackageURL } from 'packageurl-js'
import * as exec from '@actions/exec'
import * as core from '@actions/core'
import {
Manifest,
BuildTarget,
PackageCache
} from '@github/dependency-submission-toolkit'
import { PackageCache } from '@github/dependency-submission-toolkit'
import { parseGoModGraph, parseGoList } from './parse'
export async function processGoGraph (goModDir: string): Promise<PackageCache> {
export async function processGoGraph (
goModDir: string,
directDependencies: Array<PackageURL>,
indirectDependencies: Array<PackageURL>
): Promise<PackageCache> {
console.log(`Running 'go mod graph' in ${goModDir}`)
const goModGraph = await exec.getExecOutput('go', ['mod', 'graph'], {
cwd: goModDir
@@ -21,35 +21,89 @@ export async function processGoGraph (goModDir: string): Promise<PackageCache> {
throw new Error("Failed to execute 'go mod graph'")
}
/* add all direct and indirect packages to a new PackageCache */
const cache = new PackageCache()
directDependencies.forEach((pkg) => {
cache.package(pkg)
})
indirectDependencies.forEach((pkg) => {
cache.package(pkg)
})
const packageAssocList = parseGoModGraph(goModGraph.stdout)
packageAssocList.forEach(([parentPkg, childPkg]) => {
cache.package(parentPkg).dependsOn(cache.package(childPkg))
/* Look up the parent package in the cache. go mod graph will return
* multiple versions of packages with the same namespace and name. We
* select only package versions used in the Go build target. */
const targetPackage = cache.lookupPackage(parentPkg)
if (!targetPackage) return
/* Build a matcher to select on the namespace+name of the child package in
* the cache. The child package version specified by go mod graph is not
* the one guaranteed to be selected when building Go build targets. */
const matcher: { name: string; namespace?: string } = {
name: childPkg.name
}
if (childPkg.namespace) matcher.namespace = childPkg.namespace
/* There should only ever be a single package with a namespace+name in the
* build target list. Go does not support multiple versions of the same
* package */
const matches = cache.packagesMatching(matcher)
if (matches.length !== 1) {
throw new Error(
'assertion failed: expected one package in cache with namespace+name. ' +
'Found: ' +
JSON.stringify(matches)
)
}
// create the dependency relationship
targetPackage.dependsOn(matches[0])
})
return cache
}
// For a specific Go _build target_, this template lists all dependencies used
// to build the build target It does not provide association between the
// For a specific Go _build target_, these templates list dependencies used to
// in the build target. It does not provide association between the
// dependencies (i.e. which dependencies depend on which)
// eslint-disable-next-line quotes
// eslint-disable-next-line no-useless-escape
const GO_LIST_DEP_TEMPLATE =
'{{define "M"}}{{.Path}}@{{.Version}}{{end}}{{with .Module}}{{if not .Main}}{{if .Replace}}{{template "M" .Replace}}{{else}}{{template "M" .}}{{end}}{{end}}{{end}}'
const GO_DIRECT_DEPS_TEMPLATE =
'{{define "M"}}{{if not .Indirect}}{{.Path}}@{{.Version}}{{end}}{{end}}{{with .Module}}{{if not .Main}}{{if .Replace}}{{template "M" .Replace}}{{else}}{{template "M" .}}{{end}}{{end}}{{end}}'
// eslint-disable-next-line quotes
// eslint-disable-next-line no-useless-escape
const GO_INDIRECT_DEPS_TEMPLATE =
'{{define "M"}}{{if .Indirect}}{{.Path}}@{{.Version}}{{end}}{{end}}{{with .Module}}{{if not .Main}}{{if .Replace}}{{template "M" .Replace}}{{else}}{{template "M" .}}{{end}}{{end}}{{end}}'
export async function processGoBuildTarget (
export async function processGoDirectDependencies (
goModDir: string,
goBuildTarget: string
): Promise<Array<PackageURL>> {
console.log(
`go direct package detection in ${goModDir} on build target ${goBuildTarget}`
)
return processGoList(goModDir, goBuildTarget, GO_DIRECT_DEPS_TEMPLATE)
}
export async function processGoIndirectDependencies (
goModDir: string,
goBuildTarget: string
): Promise<Array<PackageURL>> {
console.log(
`go indirect package detection in ${goModDir} on build target ${goBuildTarget}`
)
return processGoList(goModDir, goBuildTarget, GO_INDIRECT_DEPS_TEMPLATE)
}
async function processGoList (
goModDir: string,
goBuildTarget: string,
cache: PackageCache
): Promise<Manifest> {
console.log(
`Running go package detection in ${goModDir} on build target ${goBuildTarget}`
)
goListTemplate: string
): Promise<Array<PackageURL>> {
const goList = await exec.getExecOutput(
'go',
['list', '-deps', '-f', GO_LIST_DEP_TEMPLATE, goBuildTarget],
['list', '-deps', '-f', goListTemplate, goBuildTarget],
{ cwd: goModDir }
)
if (goList.exitCode !== 0) {
@@ -58,14 +112,5 @@ export async function processGoBuildTarget (
throw new Error("Failed to execute 'go list'")
}
const dependencies = parseGoList(goList.stdout)
const manifest = new BuildTarget(
goBuildTarget,
path.join(goModDir, goBuildTarget)
)
dependencies.forEach((dep) => {
manifest.addBuildDependency(cache.package(dep))
})
return manifest
return parseGoList(goList.stdout)
}