123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- "use strict";
- const log = require("npmlog");
- const { describeRefSync } = require("@lerna/describe-ref");
- const { hasTags } = require("./lib/has-tags");
- const { collectPackages } = require("./lib/collect-packages");
- const { getPackagesForOption } = require("./lib/get-packages-for-option");
- const { makeDiffPredicate } = require("./lib/make-diff-predicate");
- module.exports.collectUpdates = collectUpdates;
- module.exports.collectPackages = collectPackages;
- module.exports.getPackagesForOption = getPackagesForOption;
- /**
- * @typedef {object} UpdateCollectorOptions
- * @property {string} [bump] The semver bump keyword (patch/minor/major) or explicit version used
- * @property {boolean} [canary] Whether or not to use a "nightly" range (`ref^..ref`) for commits
- * @property {string[]} [ignoreChanges]
- * A list of globs that match files/directories whose changes
- * should not be considered when identifying changed packages
- * @property {boolean} [includeMergedTags]
- * Whether or not to include the --first-parent flag when calling `git describe`
- * (awkwardly, pass `true` to _omit_ the flag, the default is to include it)
- * @property {boolean | string[]} [forcePublish] Which packages, if any, to always include
- * Force all packages to be versioned with `true`, or pass a list of globs that match package names
- * @property {string} [since] Ref to use when querying git, defaults to most recent annotated tag
- * @property {boolean} [conventionalCommits]
- * @property {boolean} [conventionalGraduate]
- * @property {boolean} [excludeDependents]
- */
- /**
- * Create a list of graph nodes representing packages changed since the previous release, tagged or otherwise.
- * @param {import("@lerna/package").Package[]} filteredPackages
- * @param {import("@lerna/package-graph").PackageGraph} packageGraph
- * @param {import("@lerna/child-process").ExecOpts} execOpts
- * @param {UpdateCollectorOptions} commandOptions
- */
- function collectUpdates(filteredPackages, packageGraph, execOpts, commandOptions) {
- const { forcePublish, conventionalCommits, conventionalGraduate, excludeDependents } = commandOptions;
- // If --conventional-commits and --conventional-graduate are both set, ignore --force-publish
- const useConventionalGraduate = conventionalCommits && conventionalGraduate;
- const forced = getPackagesForOption(useConventionalGraduate ? conventionalGraduate : forcePublish);
- const packages =
- filteredPackages.length === packageGraph.size
- ? packageGraph
- : new Map(filteredPackages.map(({ name }) => [name, packageGraph.get(name)]));
- let committish = commandOptions.since;
- if (hasTags(execOpts)) {
- // describe the last annotated tag in the current branch
- const { sha, refCount, lastTagName } = describeRefSync(execOpts, commandOptions.includeMergedTags);
- // TODO: warn about dirty tree?
- if (refCount === "0" && forced.size === 0 && !committish) {
- // no commits since previous release
- log.notice("", "Current HEAD is already released, skipping change detection.");
- return [];
- }
- if (commandOptions.canary) {
- // if it's a merge commit, it will return all the commits that were part of the merge
- // ex: If `ab7533e` had 2 commits, ab7533e^..ab7533e would contain 2 commits + the merge commit
- committish = `${sha}^..${sha}`;
- } else if (!committish) {
- // if no tags found, this will be undefined and we'll use the initial commit
- committish = lastTagName;
- }
- }
- if (forced.size) {
- // "warn" might seem a bit loud, but it is appropriate for logging anything _forced_
- log.warn(
- useConventionalGraduate ? "conventional-graduate" : "force-publish",
- forced.has("*") ? "all packages" : Array.from(forced.values()).join("\n")
- );
- }
- if (useConventionalGraduate) {
- // --conventional-commits --conventional-graduate
- if (forced.has("*")) {
- log.info("", "Graduating all prereleased packages");
- } else {
- log.info("", "Graduating prereleased packages");
- }
- } else if (!committish || forced.has("*")) {
- // --force-publish or no tag
- log.info("", "Assuming all packages changed");
- return collectPackages(packages, {
- onInclude: (name) => log.verbose("updated", name),
- excludeDependents,
- });
- }
- log.info("", `Looking for changed packages since ${committish}`);
- const hasDiff = makeDiffPredicate(committish, execOpts, commandOptions.ignoreChanges);
- const needsBump =
- !commandOptions.bump || commandOptions.bump.startsWith("pre")
- ? () => false
- : /* skip packages that have not been previously prereleased */
- (node) => node.prereleaseId;
- const isForced = (node, name) =>
- (forced.has("*") || forced.has(name)) && (useConventionalGraduate ? node.prereleaseId : true);
- return collectPackages(packages, {
- isCandidate: (node, name) => isForced(node, name) || needsBump(node) || hasDiff(node),
- onInclude: (name) => log.verbose("updated", name),
- excludeDependents,
- });
- }
|