Skip to content

Commit

Permalink
fix: refactor argument transformation for Gradle, add tests (#78)
Browse files Browse the repository at this point in the history
  • Loading branch information
kyegupov authored Jun 7, 2019
1 parent 0d601e1 commit bdadba0
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 53 deletions.
72 changes: 35 additions & 37 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,15 +288,7 @@ function leftPad(s: string, n: number) {

async function getAllDeps(root, targetFile, options: SingleRootInspectOptions | MultiRootsInspectOptions):
Promise<JsonDepsScriptResult> {
const args = buildArgs(
root, targetFile,
options['configuration-matching'],
options['configuration-attributes'],
options.args);

let tmpInitGradle: tmp.SynchrounousResult | null = null;

// TODO: move to buildArgs, adjust tests
let initGradlePath: string | null = null;
if (/index.js$/.test(__filename)) {
// running from ./dist
Expand All @@ -308,9 +300,14 @@ async function getAllDeps(root, targetFile, options: SingleRootInspectOptions |
throw new Error('Cannot locate Snyk init.gradle script');
}

const args = buildArgs(
root, targetFile, initGradlePath,
options);

// We could be running from a bundled CLI generated by `pkg`.
// The Node filesystem in that case is not real: https://github.com/zeit/pkg#snapshot-filesystem
// Copying the injectable script into a temp file.
let tmpInitGradle: tmp.SynchrounousResult | null = null;
try {
tmpInitGradle = tmp.fileSync({postfix: '-init.gradle'});
await fs.createReadStream(initGradlePath).pipe(fs.createWriteStream('', {fd: tmpInitGradle!.fd}));
Expand All @@ -321,25 +318,6 @@ async function getAllDeps(root, targetFile, options: SingleRootInspectOptions |
throw error;
}

if (!isMultiSubProject(options)) {
args.push('-PonlySubProject=' + (options['gradle-sub-project'] || '.'));
}

args.push('-I ' + initGradlePath);

// There might be a legacy --configuration option in 'args'.
// It has been superseded by --configuration-matching option for Snyk CLI (see buildArgs),
// but we are handling it to support the legacy setups.
args.forEach((a, i) => {
// Transform --configuration=foo
args[i] = a.replace(/^--configuration[= ]([a-zA-Z_]+)/, `-Pconfiguration=${quot}^$1$$${quot}`);
// Transform --configuration foo
if (a === '--configuration') {
args[i] = `-Pconfiguration=${quot}^${args[i + 1]}$${quot}`;
args[i + 1] = '';
}
});

const command = getCommand(root, targetFile);
const fullCommandText = 'gradle command: ' + command + ' ' + args.join(' ');
debugLog('Executing ' + fullCommandText);
Expand Down Expand Up @@ -455,10 +433,10 @@ function getCommand(root, targetFile) {
}

function buildArgs(
root, targetFile,
configurationMatching: string|undefined,
configurationAttributes: string|undefined,
gradleArgs?: string[]) {
root: string,
targetFile: string | null,
initGradlePath: string,
options: SingleRootInspectOptions | MultiRootsInspectOptions) {
const args: string[] = [];
args.push('snykResolvedDepsJson', '-q');
if (targetFile) {
Expand All @@ -475,11 +453,11 @@ function buildArgs(
}

// Arguments to init script are supplied as properties: https://stackoverflow.com/a/48370451
if (configurationMatching) {
args.push(`-Pconfiguration=${quot}${configurationMatching}${quot}`);
if (options['configuration-matching']) {
args.push(`-Pconfiguration=${quot}${options['configuration-matching']}${quot}`);
}
if (configurationAttributes) {
args.push(`-PconfAttr=${quot}${configurationAttributes}${quot}`);
if (options['configuration-attributes']) {
args.push(`-PconfAttr=${quot}${options['configuration-attributes']}${quot}`);
}

// For some reason, this is not required for Unix, but on Windows, without this flag, apparently,
Expand All @@ -491,9 +469,29 @@ function buildArgs(
// Not `=false` to be compatible with 3.5.x: https://github.com/gradle/gradle/issues/1827
args.push('-Dorg.gradle.parallel=');

if (gradleArgs) {
args.push(...gradleArgs);
if (!isMultiSubProject(options)) {
args.push('-PonlySubProject=' + (options['gradle-sub-project'] || '.'));
}

args.push('-I ' + initGradlePath);

if (options.args) {
args.push(...options.args);
}

// There might be a legacy --configuration option in 'args'.
// It has been superseded by --configuration-matching option for Snyk CLI (see buildArgs),
// but we are handling it to support the legacy setups.
args.forEach((a, i) => {
// Transform --configuration=foo
args[i] = a.replace(/^--configuration[= ]([a-zA-Z_]+)/, `-Pconfiguration=${quot}^$1$$${quot}`);
// Transform --configuration foo
if (a === '--configuration') {
args[i] = `-Pconfiguration=${quot}^${args[i + 1]}$${quot}`;
args[i + 1] = '';
}
});

return args;
}

Expand Down
53 changes: 37 additions & 16 deletions test/functional/gradle-plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,70 @@ const isWin = /^win/.test(os.platform());
const quot = isWin ? '"' : '\'';

test('check build args with array (new configuration arg)', async (t) => {
const result = testableMethods.buildArgs(null, null, "confRegex", undefined, [
'--build-file',
'build.gradle',
]);
const result = testableMethods.buildArgs(
'.',
null,
'/tmp/init.gradle',
{
'configuration-matching':'confRegex',
args: ['--build-file', 'build.gradle']
}
);
t.deepEqual(result, [
'snykResolvedDepsJson',
'-q',
`-Pconfiguration=${quot}confRegex${quot}`,
'--no-daemon',
'-Dorg.gradle.parallel=',
'-PonlySubProject=.',
'-I /tmp/init.gradle',
'--build-file',
'build.gradle',
]);
});

test('check build args with array (legacy configuration arg)', async (t) => {
const result = testableMethods.buildArgs(null, null, undefined, undefined, [
'--build-file',
'build.gradle',
'--configuration',
'compile',
]);
const result = testableMethods.buildArgs(
'.',
null,
'/tmp/init.gradle',
{
args: ['--build-file', 'build.gradle', '--configuration=compile']
}
);
t.deepEqual(result, [
'snykResolvedDepsJson',
'-q',
'--no-daemon',
'-Dorg.gradle.parallel=',
'-PonlySubProject=.',
'-I /tmp/init.gradle',
'--build-file',
'build.gradle',
'--configuration',
'compile',
`-Pconfiguration=${quot}^compile$${quot}`,
]);
});

test('check build args with string', async (t) => {
const result = testableMethods.buildArgs(null, null, undefined, undefined,
['--build-file build.gradle --configuration compile']);
test('check build args with scan all subprojects', async (t) => {
const result = testableMethods.buildArgs(
'.',
null,
'/tmp/init.gradle',
{
multiDepRoots: true,
args: ['--build-file', 'build.gradle', '--configuration', 'compile']
}
);
t.deepEqual(result, [
'snykResolvedDepsJson',
'-q',
'--no-daemon',
'-Dorg.gradle.parallel=',
'--build-file build.gradle --configuration compile',
'-I /tmp/init.gradle',
'--build-file',
'build.gradle',
`-Pconfiguration=${quot}^compile$${quot}`,
'', // this is a harmless artifact of argument transformation
]);
});

Expand Down

0 comments on commit bdadba0

Please sign in to comment.