"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const cli_utils_1 = require("@pnpm/cli-utils");
const error_1 = __importDefault(require("@pnpm/error"));
const lifecycle_1 = __importDefault(require("@pnpm/lifecycle"));
const logger_1 = __importDefault(require("@pnpm/logger"));
const sort_packages_1 = __importDefault(require("@pnpm/sort-packages"));
const path = require("path");
const pLimit = require("p-limit");
const realpathMissing = require("realpath-missing");
exports.default = async (params, opts) => {
    var _a;
    const [scriptName, ...passedThruArgs] = params;
    if (!scriptName) {
        throw new error_1.default('SCRIPT_NAME_IS_REQUIRED', 'You must specify the script you want to run');
    }
    let hasCommand = 0;
    const packageChunks = opts.sort
        ? sort_packages_1.default(opts.selectedProjectsGraph)
        : [Object.keys(opts.selectedProjectsGraph).sort()];
    const result = {
        fails: [],
        passes: 0,
    };
    const limitRun = pLimit((_a = opts.workspaceConcurrency) !== null && _a !== void 0 ? _a : 4);
    const stdio = (opts.workspaceConcurrency === 1 ||
        packageChunks.length === 1 && packageChunks[0].length === 1) ? 'inherit' : 'pipe';
    for (const chunk of packageChunks) {
        await Promise.all(chunk.map((prefix) => limitRun(async () => {
            var _a;
            const pkg = opts.selectedProjectsGraph[prefix];
            if (!((_a = pkg.package.manifest.scripts) === null || _a === void 0 ? void 0 : _a[scriptName]) ||
                process.env.npm_lifecycle_event === scriptName &&
                    process.env.PNPM_SCRIPT_SRC_DIR === prefix) {
                return;
            }
            hasCommand++;
            try {
                const lifecycleOpts = {
                    depPath: prefix,
                    extraBinPaths: opts.extraBinPaths,
                    pkgRoot: prefix,
                    rawConfig: opts.rawConfig,
                    rootModulesDir: await realpathMissing(path.join(prefix, 'node_modules')),
                    shellEmulator: opts.shellEmulator,
                    stdio,
                    unsafePerm: true,
                };
                if (pkg.package.manifest.scripts[`pre${scriptName}`]) {
                    await lifecycle_1.default(`pre${scriptName}`, pkg.package.manifest, lifecycleOpts);
                }
                await lifecycle_1.default(scriptName, pkg.package.manifest, { ...lifecycleOpts, args: passedThruArgs });
                if (pkg.package.manifest.scripts[`post${scriptName}`]) {
                    await lifecycle_1.default(`post${scriptName}`, pkg.package.manifest, lifecycleOpts);
                }
                result.passes++;
            }
            catch (err) {
                logger_1.default.info(err);
                if (!opts.bail) {
                    result.fails.push({
                        error: err,
                        message: err.message,
                        prefix,
                    });
                    return;
                }
                /* eslint-disable @typescript-eslint/dot-notation */
                err['code'] = 'ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL';
                err['prefix'] = prefix;
                /* eslint-enable @typescript-eslint/dot-notation */
                throw err;
            }
        })));
    }
    if (scriptName !== 'test' && !hasCommand && !opts.ifPresent) {
        const allPackagesAreSelected = Object.keys(opts.selectedProjectsGraph).length === opts.allProjects.length;
        if (allPackagesAreSelected) {
            throw new error_1.default('RECURSIVE_RUN_NO_SCRIPT', `None of the packages has a "${scriptName}" script`);
        }
        else {
            logger_1.default.info({
                message: `None of the selected packages has a "${scriptName}" script`,
                prefix: opts.workspaceDir,
            });
        }
    }
    cli_utils_1.throwOnCommandFail('pnpm recursive run', result);
};
//# sourceMappingURL=runRecursive.js.map