HEX
Server: Apache
System: Linux webd004.cluster130.gra.hosting.ovh.net 5.15.206-ovh-vps-grsec-zfs-classid #1 SMP Fri May 15 02:41:25 UTC 2026 x86_64
User: frenchy (106757)
PHP: 7.4.33
Disabled: _dyuweyrj4,_dyuweyrj4r,dl
Upload Files
File: /home/f/r/e/frenchy/www/french-american.org/current/node_modules/snyk-gradle-plugin/dist/index.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const os = require("os");
const fs = require("fs");
const path = require("path");
const subProcess = require("./sub-process");
const tmp = require("tmp");
const errors_1 = require("./errors");
const chalk_1 = require("chalk");
const cli_interface_1 = require("@snyk/cli-interface");
const debugModule = require("debug");
// To enable debugging output, use `snyk -d`
let logger = null;
function debugLog(s) {
    if (logger === null) {
        // Lazy init: Snyk CLI needs to process the CLI argument "-d" first.
        // TODO(BST-648): more robust handling of the debug settings
        if (process.env.DEBUG) {
            debugModule.enable(process.env.DEBUG);
        }
        logger = debugModule('snyk-gradle-plugin');
    }
    logger(s);
}
const packageFormatVersion = 'mvn:0.0.1';
const isWin = /^win/.test(os.platform());
const quot = isWin ? '"' : '\'';
const cannotResolveVariantMarkers = [
    'Cannot choose between the following',
    'Could not select value from candidates',
    'Unable to find a matching variant of project',
];
// General implementation. The result type depends on the runtime type of `options`.
function inspect(root, targetFile, options) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        if (!options) {
            options = { dev: false };
        }
        let subProject = options.subProject;
        if (subProject) {
            subProject = subProject.trim();
        }
        const plugin = {
            name: 'bundled:gradle',
            runtime: 'unknown',
            targetFile: targetFileFilteredForCompatibility(targetFile),
            meta: {},
        };
        if (cli_interface_1.legacyPlugin.isMultiSubProject(options)) {
            if (subProject) {
                throw new Error('gradle-sub-project flag is incompatible with multiDepRoots');
            }
            const scannedProjects = yield getAllDepsAllProjects(root, targetFile, options);
            plugin.meta = plugin.meta || {};
            return {
                plugin,
                scannedProjects,
            };
        }
        const depTreeAndDepRootNames = yield getAllDepsOneProject(root, targetFile, options, subProject);
        if (depTreeAndDepRootNames.allSubProjectNames) {
            plugin.meta = plugin.meta || {};
            plugin.meta.allSubProjectNames = depTreeAndDepRootNames.allSubProjectNames;
        }
        return {
            plugin,
            package: depTreeAndDepRootNames.depTree,
            meta: {
                gradleProjectName: depTreeAndDepRootNames.gradleProjectName,
            },
        };
    });
}
exports.inspect = inspect;
// See the comment for DepRoot.targetFile
// Note: for Gradle, we are not returning the name unless it's a .kts file.
// This is a workaround for a project naming problem happening in Registry
// (legacy projects are named without "build.gradle" attached to them).
// See ticket BST-529 re permanent solution.
function targetFileFilteredForCompatibility(targetFile) {
    return (path.basename(targetFile) === 'build.gradle.kts') ? targetFile : undefined;
}
function extractJsonFromScriptOutput(stdoutText) {
    const lines = stdoutText.split('\n');
    let jsonLine = null;
    lines.forEach((l) => {
        if (/^JSONDEPS /.test(l)) {
            if (jsonLine !== null) {
                throw new Error('More than one line with "JSONDEPS " prefix was returned; full output:\n' + stdoutText);
            }
            jsonLine = l.substr(9);
        }
    });
    if (jsonLine === null) {
        throw new Error('No line prefixed with "JSONDEPS " was returned; full output:\n' + stdoutText);
    }
    debugLog('The command produced JSONDEPS output of ' + jsonLine.length + ' characters');
    return JSON.parse(jsonLine);
}
function getAllDepsOneProject(root, targetFile, options, subProject) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const packageName = path.basename(root);
        const allProjectDeps = yield getAllDeps(root, targetFile, options);
        const allSubProjectNames = allProjectDeps.allSubProjectNames;
        if (subProject) {
            const { depTree, meta } = getDepsSubProject(root, subProject, allProjectDeps);
            return {
                depTree,
                allSubProjectNames,
                gradleProjectName: meta.gradleProjectName,
            };
        }
        const { projects, defaultProject } = allProjectDeps;
        const { depDict } = projects[defaultProject];
        return {
            depTree: {
                dependencies: depDict,
                name: packageName,
                // TODO: extract from project
                // https://snyksec.atlassian.net/browse/BST-558
                version: '0.0.0',
                packageFormatVersion,
            },
            allSubProjectNames,
            gradleProjectName: defaultProject,
        };
    });
}
function getDepsSubProject(root, subProject, allProjectDeps) {
    const packageName = `${path.basename(root)}/${subProject}`;
    const gradleProjectName = `${allProjectDeps.defaultProject}/${subProject}`;
    if (!allProjectDeps.projects || !allProjectDeps.projects[subProject]) {
        throw new errors_1.MissingSubProjectError(subProject, Object.keys(allProjectDeps));
    }
    const depDict = allProjectDeps.projects[subProject].depDict;
    return {
        depTree: {
            dependencies: depDict,
            name: packageName,
            // TODO: extract from project
            // https://snyksec.atlassian.net/browse/BST-558
            version: '0.0.0',
            packageFormatVersion,
        },
        meta: {
            gradleProjectName,
        },
    };
}
function getAllDepsAllProjects(root, targetFile, options) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const allProjectDeps = yield getAllDeps(root, targetFile, options);
        const basePackageName = path.basename(root);
        const packageVersion = '0.0.0';
        return Object.keys(allProjectDeps.projects).map((proj) => {
            const packageName = proj === allProjectDeps.defaultProject ? basePackageName : `${basePackageName}/${proj}`;
            const defaultProject = allProjectDeps.defaultProject;
            const gradleProjectName = proj === defaultProject ? defaultProject : `${defaultProject}/${proj}`;
            return {
                targetFile: targetFileFilteredForCompatibility(allProjectDeps.projects[proj].targetFile),
                meta: {
                    gradleProjectName,
                },
                depTree: {
                    dependencies: allProjectDeps.projects[proj].depDict,
                    name: packageName,
                    version: packageVersion,
                    packageFormatVersion,
                },
            };
        });
    });
}
const reEcho = /^SNYKECHO (.*)$/;
function printIfEcho(line) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const maybeMatch = reEcho.exec(line);
        if (maybeMatch) {
            debugLog(maybeMatch[1]);
        }
    });
}
// <insert a npm left-pad joke here>
function leftPad(s, n) {
    return ' '.repeat(Math.max(n - s.length, 0)) + s;
}
function getInjectedScriptPath() {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        let initGradleAsset = null;
        if (/index.js$/.test(__filename)) {
            // running from ./dist
            // path.join call has to be exactly in this format, needed by "pkg" to build a standalone Snyk CLI binary:
            // https://www.npmjs.com/package/pkg#detecting-assets-in-source-code
            initGradleAsset = path.join(__dirname, '../lib/init.gradle');
        }
        else if (/index.ts$/.test(__filename)) {
            // running from ./lib
            initGradleAsset = path.join(__dirname, 'init.gradle');
        }
        else {
            throw new Error('Cannot locate Snyk init.gradle script');
        }
        // 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.
        try {
            const tmpInitGradle = tmp.fileSync({ postfix: '-init.gradle' });
            fs.createReadStream(initGradleAsset).pipe(fs.createWriteStream('', { fd: tmpInitGradle.fd }));
            return { injectedScripPath: tmpInitGradle.name, cleanupCallback: tmpInitGradle.removeCallback };
        }
        catch (error) {
            error.message = error.message + '\n\n' +
                'Failed to create a temporary file to host Snyk init script for Gradle build analysis.';
            throw error;
        }
    });
}
function getAllDeps(root, targetFile, options) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const command = getCommand(root, targetFile);
        let gradleVersionOutput = '[COULD NOT RUN gradle -v] ';
        try {
            gradleVersionOutput = yield subProcess.execute(command, ['-v'], { cwd: root });
        }
        catch (_) {
            // intentionally empty
        }
        if (gradleVersionOutput.match(/Gradle 1/)) {
            throw new Error('Gradle 1.x is not supported');
        }
        const { injectedScripPath, cleanupCallback } = yield getInjectedScriptPath();
        const args = buildArgs(root, targetFile, injectedScripPath, options);
        const fullCommandText = 'gradle command: ' + command + ' ' + args.join(' ');
        debugLog('Executing ' + fullCommandText);
        try {
            const stdoutText = yield subProcess.execute(command, args, { cwd: root }, printIfEcho);
            if (cleanupCallback) {
                cleanupCallback();
            }
            return extractJsonFromScriptOutput(stdoutText);
        }
        catch (error0) {
            const error = error0;
            const gradleErrorMarkers = /^\s*>\s.*$/;
            const gradleErrorEssence = error.message.split('\n').filter((l) => gradleErrorMarkers.test(l)).join('\n');
            const orange = chalk_1.default.rgb(255, 128, 0);
            const blackOnYellow = chalk_1.default.bgYellowBright.black;
            gradleVersionOutput = orange(gradleVersionOutput);
            let mainErrorMessage = `Error running Gradle dependency analysis.

Please ensure you are calling the \`snyk\` command with correct arguments.
If the problem persists, contact support@snyk.io, providing the full error
message from above, starting with ===== DEBUG INFORMATION START =====.`;
            // Special case for Android, where merging the configurations is sometimes
            // impossible.
            // There are no automated tests for this yet (setting up Android SDK is quite problematic).
            // See test/manual/README.md
            if (cannotResolveVariantMarkers.find((m) => error.message.includes(m))) {
                // Extract attribute information via JSONATTRS marker:
                const jsonAttrs = JSON.parse(error.message.split('\n').filter((line) => /^JSONATTRS /.test(line))[0].substr(10));
                const attrNameWidth = Math.max(...Object.keys(jsonAttrs).map((name) => name.length));
                const jsonAttrsPretty = Object.keys(jsonAttrs).map((name) => chalk_1.default.whiteBright(leftPad(name, attrNameWidth)) + ': ' + chalk_1.default.gray(jsonAttrs[name].join(', '))).join('\n');
                mainErrorMessage = `Error running Gradle dependency analysis.

It seems like you are scanning an Android build with ambiguous dependency variants.
We cannot automatically resolve dependencies for such builds.

You have several options to make dependency resolution rules more specific:

1. Run Snyk CLI tool with an attribute filter, e.g.:
    ${chalk_1.default.whiteBright('snyk test --all-sub-projects --configuration-attributes=buildtype:release,usage:java-runtime')}

The filter will select matching attributes from those found in your configurations, use them
to select matching configuration(s) to be used to resolve dependencies. Any sub-string of the full
attribute name is enough.

Select the values for the attributes that would allow to unambiguously select the correct dependency
variant. The Gradle error message above should contain information about attributes found in
different variants.

Suggested attributes: buildtype, usage and your "flavor dimension" for Android builds.

The following attributes and their possible values were found in your configurations:
${jsonAttrsPretty}

2. Run Snyk CLI tool for specific configuration(s), e.g.:
    ${chalk_1.default.whiteBright("snyk test --gradle-sub-project=my-app --configuration-matching='^releaseRuntimeClasspath$'")}

(note that some configurations won't be present in every your subproject)

3. Converting your subproject dependency specifications from the form of
    ${chalk_1.default.whiteBright("implementation project(':mymodule')")}
to
    ${chalk_1.default.whiteBright("implementation project(path: ':mymodule', configuration: 'default')")}`;
            }
            error.message = `${chalk_1.default.red.bold('Gradle Error (short):\n' + gradleErrorEssence)}

${blackOnYellow('===== DEBUG INFORMATION START =====')}
${orange(fullCommandText)}
${orange(gradleVersionOutput)}
${orange(error.message)}
${blackOnYellow('===== DEBUG INFORMATION END =====')}

${chalk_1.default.red.bold(mainErrorMessage)}`;
            throw error;
        }
    });
}
function getCommand(root, targetFile) {
    const isWinLocal = /^win/.test(os.platform()); // local check, can be stubbed in tests
    const quotLocal = isWinLocal ? '"' : '\'';
    const wrapperScript = isWinLocal ? 'gradlew.bat' : './gradlew';
    // try to find a sibling wrapper script first
    let pathToWrapper = path.resolve(root, path.dirname(targetFile), wrapperScript);
    if (fs.existsSync(pathToWrapper)) {
        return quotLocal + pathToWrapper + quotLocal;
    }
    // now try to find a wrapper in the root
    pathToWrapper = path.resolve(root, wrapperScript);
    if (fs.existsSync(pathToWrapper)) {
        return quotLocal + pathToWrapper + quotLocal;
    }
    return 'gradle';
}
function buildArgs(root, targetFile, initGradlePath, options) {
    const args = [];
    args.push('snykResolvedDepsJson', '-q');
    if (targetFile) {
        if (!fs.existsSync(path.resolve(root, targetFile))) {
            throw new Error('File not found: "' + targetFile + '"');
        }
        args.push('--build-file');
        let formattedTargetFile = targetFile;
        if (/\s/.test(targetFile)) { // checking for whitespaces
            formattedTargetFile = quot + targetFile + quot;
        }
        args.push(formattedTargetFile);
    }
    // Arguments to init script are supplied as properties: https://stackoverflow.com/a/48370451
    if (options['configuration-matching']) {
        args.push(`-Pconfiguration=${quot}${options['configuration-matching']}${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,
    // Gradle process just never exits, from the Node's standpoint.
    args.push('--no-daemon');
    // Parallel builds can cause race conditions and multiple JSONDEPS lines in the output
    // Gradle 4.3.0+ has `--no-parallel` flag, but we want to support older versions.
    // Not `=false` to be compatible with 3.5.x: https://github.com/gradle/gradle/issues/1827
    args.push('-Dorg.gradle.parallel=');
    if (!cli_interface_1.legacyPlugin.isMultiSubProject(options)) {
        args.push('-PonlySubProject=' + (options.subProject || '.'));
    }
    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;
}
exports.exportsForTests = {
    buildArgs,
    extractJsonFromScriptOutput,
};
//# sourceMappingURL=index.js.map