Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Go - Support projects with embed files #434

Merged
merged 4 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ export class GoTreeNode extends RootNode {
directDependenciesGeneralInfos.push(new GeneralInfo(nameVersionTuple[0], nameVersionTuple[1], ['None'], '', PackageType.Go));
}

// Filter out go min version that is written in go mod e.g. [email protected]
directDependenciesGeneralInfos = directDependenciesGeneralInfos.filter(generalInfo => !generalInfo.artifactId.startsWith('go@'));

// Create a set of packages that are actually in use in the project
let goListPackages: Set<string> = new Set<string>();
goList.forEach((dependency: string) => {
Expand Down
43 changes: 31 additions & 12 deletions src/main/utils/goUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ export class GoUtils {

try {
goModAbsDir = this.prepareGoModAbs(logManager);
this.prepareProjectWorkspace(workspaceDir, targetDir, goModAbsDir);
this.prepareProjectWorkspace(workspaceDir, targetDir, goModAbsDir, logManager, GoUtils.executeGoRun);
} finally {
if (goModAbsDir) {
try {
Expand All @@ -167,6 +167,11 @@ export class GoUtils {
return tmpGoModPath;
}

private static executeGoRun(destPath: string, sourceDir: string, goModAbsDir: string) {
const cmd: string = `go run . -goModPath=${destPath} -wd=${sourceDir}`;
ScanUtils.executeCmd(cmd, goModAbsDir);
}

/**
* Copy gomod-absolutizer Go files to a temp directory.
* The gomod-absolutizer is used to change relative paths in go.mod files to absolute paths.
Expand Down Expand Up @@ -199,11 +204,23 @@ export class GoUtils {
* @param targetDir - Target directory to copy relevant files to.
* @param goModAbsDir - Path to the location of the gomod-absolutizer tool.
*/
private static prepareProjectWorkspace(sourceDir: string, targetDir: string, goModAbsDir: string) {
public static prepareProjectWorkspace(
sourceDir: string,
targetDir: string,
goModAbsDir: string,
logManager: LogManager,
executeCmdFunction: (goModPath: string, sourceDir: string, goModAbsDir: string) => void
) {
logManager.logMessage('Copy go workspace from' + sourceDir + ', to' + targetDir, 'DEBUG');
walkdir.find(sourceDir, { follow_symlinks: false, sync: true }, function(curPath: string, stat: fs.Stats) {
let destPath: string = path.resolve(targetDir, path.relative(sourceDir, curPath));

if (stat.isDirectory()) {
if (!(curPath === sourceDir)) {
if (GoUtils.shouldSkipDirectory(curPath, '.git', 'testdata', '.idea', '.vscode')) {
this.ignore(curPath);
return;
}
if (curPath !== sourceDir) {
// Skip subdirectories with go.mod files.
// These directories are different Go projects and their go files should not be in the root project.
let files: string[] = fs.readdirSync(curPath).filter(fn => fn === 'go.mod');
Expand All @@ -219,20 +236,22 @@ export class GoUtils {
return;
}

// Files other than go.mod and *.go files are not necessary to build the dependency tree of used Go packages.
// Go files should be copied to allow running `go list -f "{{with .Module}}{{.Path}} {{.Version}}{{end}}" all`
// and to get the list package that are actually in use by the Go project.
if (curPath.endsWith('.go')) {
fs.copySync(curPath, destPath);
return;
}
logManager.logMessage('Copying ' + curPath + ' to ' + destPath, 'DEBUG');
fs.copySync(curPath, destPath);

// The root go.mod file is copied and relative path in "replace" are resolved to absolute paths.
if (path.basename(curPath) === 'go.mod') {
fs.copySync(curPath, destPath);
ScanUtils.executeCmd('go run . -goModPath=' + destPath + ' -wd=' + sourceDir, goModAbsDir);
executeCmdFunction(destPath, sourceDir, goModAbsDir);
return;
}
});
}
private static shouldSkipDirectory(dirPath: string, ...dirToIgnore: string[]) {
for (let dir of dirToIgnore) {
if (dirPath.includes(path.sep + dir)) {
return true;
}
}
return false;
}
}
8 changes: 8 additions & 0 deletions src/test/resources/go/embedProject/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module embedProject

go 1.16

require (
github.com/jfrog/jfrog-cli-core v1.9.0
github.com/jfrog/jfrog-client-go v0.26.1 // indirect
)
13 changes: 13 additions & 0 deletions src/test/resources/go/embedProject/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package embedProject

import (
_ "embed"
"github.com/jfrog/jfrog-cli-core/artifactory/commands/curl"
"github.com/jfrog/jfrog-cli-core/common/commands"
)
//go:embed version.txt
var buildVersion string

func main() {
curl.NewRtCurlCommand(commands.CurlCommand{})
}
Empty file.
Empty file.
Empty file.
2 changes: 1 addition & 1 deletion src/test/resources/go/project2/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbaEHo=
github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo=
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
Expand Down
47 changes: 37 additions & 10 deletions src/test/tests/goUtils.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { assert } from 'chai';
import { before } from 'mocha';
import fs from 'fs-extra';
import * as path from 'path';
import * as vscode from 'vscode';
import { ConnectionManager } from '../../main/connect/connectionManager';
Expand Down Expand Up @@ -132,6 +133,18 @@ describe('Go Utils Tests', async () => {
assert.deepEqual(child.parent, parent.children[0]);
});

/**
* The project is with dependencies, and embed file
*/
it('Create go dependencies with embed file', async () => {
let projectName: string = 'embedProject';
let expectedChildren: Map<string, number> = new Map();
expectedChildren.set('github.com/jfrog/jfrog-cli-core:1.9.0', 10);
expectedChildren.set('github.com/jfrog/jfrog-client-go:0.26.1', 8);
expectedChildren.set('github.com/golang/go:' + GoUtils.getGoVersion().format(), 0);
await createGoDependencyTreeAndValidate(projectName, expectedChildren);
});

/**
* The project is with dependencies, but without go.sum
*/
Expand All @@ -140,17 +153,19 @@ describe('Go Utils Tests', async () => {
let expectedChildren: Map<string, number> = new Map();
expectedChildren.set('github.com/jfrog/jfrog-cli-core:1.9.0', 11);
expectedChildren.set('github.com/jfrog/jfrog-client-go:0.26.1', 9);
createGoDependencyTreeAndValidate(projectName, expectedChildren);
expectedChildren.set('github.com/golang/go:' + GoUtils.getGoVersion().format(), 0);
await createGoDependencyTreeAndValidate(projectName, expectedChildren);
});

/**
* The project is with dependencies and go.sum, but with checksum mismatch on github.com/dsnet/compress
* The project is with dependencies and go.sum,
*/
it('Project 2 - Create go project with dependencies', async () => {
let projectName: string = 'project2';
let expectedChildren: Map<string, number> = new Map();
expectedChildren.set('github.com/jfrog/gocmd:0.1.12', 2);
createGoDependencyTreeAndValidate(projectName, expectedChildren);
expectedChildren.set('github.com/golang/go:' + GoUtils.getGoVersion().format(), 0);
await createGoDependencyTreeAndValidate(projectName, expectedChildren);
});

/**
Expand All @@ -161,7 +176,8 @@ describe('Go Utils Tests', async () => {
let projectName: string = 'project3';
let expectedChildren: Map<string, number> = new Map();
expectedChildren.set('github.com/test/subproject:0.0.0-00010101000000-000000000000', 1);
createGoDependencyTreeAndValidate(projectName, expectedChildren);
expectedChildren.set('github.com/golang/go:' + GoUtils.getGoVersion().format(), 0);
await createGoDependencyTreeAndValidate(projectName, expectedChildren);
});

/**
Expand All @@ -172,7 +188,8 @@ describe('Go Utils Tests', async () => {
let projectName: string = 'project4';
let expectedChildren: Map<string, number> = new Map();
expectedChildren.set('github.com/test/subproject:0.0.0-00010101000000-000000000000', 1);
createGoDependencyTreeAndValidate(projectName, expectedChildren);
expectedChildren.set('github.com/golang/go:' + GoUtils.getGoVersion().format(), 0);
await createGoDependencyTreeAndValidate(projectName, expectedChildren);
});

async function runCreateGoDependenciesTrees(workspaceFolders: vscode.WorkspaceFolder[], parent: DependenciesTreeNode) {
Expand All @@ -195,12 +212,8 @@ describe('Go Utils Tests', async () => {

function validateDependencyTreeResults(projectName: string, expectedChildren: Map<string, number>, node: DependenciesTreeNode) {
let parent: DependenciesTreeNode | null = getNodeByArtifactId(node, projectName);
if (!parent) {
assert.isNotNull(node);
return;
}

let children: DependenciesTreeNode[] = parent.children;
let children: DependenciesTreeNode[] = parent?.children || [];
assert.lengthOf(children, expectedChildren.size);
children.forEach(child => {
assert.isTrue(expectedChildren.has(child.componentId));
Expand All @@ -218,4 +231,18 @@ describe('Go Utils Tests', async () => {
} as vscode.WorkspaceFolder
];
}

describe('prepareProjectWorkspace util', () => {
it('Exclude all kind of files', () => {
// Define the source and target directories for testing
const sourceDir: string = path.join(tmpDir, 'prepareProjectWorkspace');
const targetDir: string = path.join(tmpDir, 'tmpDir');

GoUtils.prepareProjectWorkspace(sourceDir, targetDir, '', logManager, () => {
return;
});

assert.isFalse(fs.existsSync(targetDir), 'The target directory should not exist since all files should be excluded');
});
});
});
Loading