Skip to content

Commit

Permalink
feat(npm-publish): Remove figgy-pudding
Browse files Browse the repository at this point in the history
  • Loading branch information
evocateur committed Nov 24, 2020
1 parent 1158f8e commit bdc162d
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 55 deletions.
2 changes: 0 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 19 additions & 23 deletions utils/npm-publish/__tests__/npm-publish.test.js
Expand Up @@ -20,8 +20,6 @@ const Package = require("@lerna/package");
// file under test
const npmPublish = require("..");

expect.extend(require("@lerna-test/figgy-pudding-matchers"));

describe("npm-publish", () => {
const mockTarData = Buffer.from("MOCK");
const mockManifest = { _normalized: true };
Expand All @@ -41,7 +39,7 @@ describe("npm-publish", () => {
);

it("calls external libraries with correct arguments", async () => {
const opts = new Map().set("tag", "published-tag");
const opts = { tag: "published-tag" };

await npmPublish(pkg, tarFilePath, opts);

Expand All @@ -50,10 +48,8 @@ describe("npm-publish", () => {
expect(publish).toHaveBeenCalledWith(
mockManifest,
mockTarData,
expect.figgyPudding({
dryRun: false,
expect.objectContaining({
defaultTag: "published-tag",
tag: "published-tag",
projectScope: "@scope",
})
);
Expand All @@ -65,8 +61,8 @@ describe("npm-publish", () => {
expect(publish).toHaveBeenCalledWith(
mockManifest,
mockTarData,
expect.figgyPudding({
tag: "latest",
expect.objectContaining({
defaultTag: "latest",
})
);
});
Expand All @@ -79,7 +75,7 @@ describe("npm-publish", () => {
},
})
);
const opts = new Map().set("tag", "temp-tag");
const opts = { tag: "temp-tag" };

await npmPublish(pkg, tarFilePath, opts);

Expand All @@ -90,13 +86,13 @@ describe("npm-publish", () => {
},
}),
mockTarData,
expect.figgyPudding({
tag: "temp-tag",
expect.objectContaining({
defaultTag: "temp-tag",
})
);
});

it("respects pkg.publishConfig.tag when opts.tag matches default", async () => {
it("respects pkg.publishConfig.tag when opts.defaultTag matches default", async () => {
readJSON.mockImplementationOnce((file, cb) =>
cb(null, {
publishConfig: {
Expand All @@ -114,8 +110,8 @@ describe("npm-publish", () => {
},
}),
mockTarData,
expect.figgyPudding({
tag: "beta",
expect.objectContaining({
defaultTag: "beta",
})
);
});
Expand Down Expand Up @@ -151,8 +147,8 @@ describe("npm-publish", () => {
name: "fancy-fancy",
}),
mockTarData,
expect.figgyPudding({
tag: "latest",
expect.objectContaining({
defaultTag: "latest",
})
);
});
Expand All @@ -165,7 +161,7 @@ describe("npm-publish", () => {
},
})
);
const opts = new Map().set("registry", "https://global-registry.com");
const opts = { registry: "https://global-registry.com" };

await npmPublish(pkg, tarFilePath, opts);

Expand All @@ -176,14 +172,14 @@ describe("npm-publish", () => {
},
}),
mockTarData,
expect.figgyPudding({
expect.objectContaining({
registry: "http://pkg-registry.com",
})
);
});

it("respects opts.dryRun", async () => {
const opts = new Map().set("dryRun", true);
const opts = { dryRun: true };

await npmPublish(pkg, tarFilePath, opts);

Expand All @@ -192,14 +188,14 @@ describe("npm-publish", () => {
});

it("calls publish lifecycles", async () => {
const aFiggyPudding = expect.figgyPudding({
const options = expect.objectContaining({
projectScope: "@scope",
});

await npmPublish(pkg, tarFilePath);

expect(runLifecycle).toHaveBeenCalledWith(pkg, "publish", aFiggyPudding);
expect(runLifecycle).toHaveBeenLastCalledWith(pkg, "postpublish", aFiggyPudding);
expect(runLifecycle).toHaveBeenCalledWith(pkg, "publish", options);
expect(runLifecycle).toHaveBeenLastCalledWith(pkg, "postpublish", options);
});

it("catches libnpm errors", async () => {
Expand All @@ -217,7 +213,7 @@ describe("npm-publish", () => {
silly: jest.fn(),
error: jest.fn(),
};
const opts = new Map().set("log", log);
const opts = { log };

await expect(npmPublish(pkg, tarFilePath, opts)).rejects.toThrow(
expect.objectContaining({
Expand Down
94 changes: 65 additions & 29 deletions utils/npm-publish/npm-publish.js
Expand Up @@ -6,7 +6,6 @@ const log = require("npmlog");
const { publish } = require("libnpmpublish");
const pify = require("pify");
const readJSON = require("read-package-json");
const figgyPudding = require("figgy-pudding");
const runLifecycle = require("@lerna/run-lifecycle");
const npa = require("npm-package-arg");
const otplease = require("@lerna/otplease");
Expand All @@ -15,39 +14,52 @@ module.exports = npmPublish;

const readJSONAsync = pify(readJSON);

const PublishConfig = figgyPudding(
{
"dry-run": { default: false },
dryRun: "dry-run",
log: { default: log },
"project-scope": {},
projectScope: "project-scope",
// from publishConfig
registry: {},
tag: { default: "latest" },
// npm v7 flattens 'tag' to 'defaultTag', so proxy here for back-compat
defaultTag: "tag",
},
{
other() {
// open it up for the sake of tests
return true;
},
}
);
/**
* @typedef {object} NpmPublishOptions
* @property {boolean} [dryRun]
* @property {string} [tag] Passed to libnpmpublish as `opts.defaultTag` to preserve npm v6 back-compat
*/

/**
* Alias dash-cased npmConf to camelCase
* @param {NpmPublishOptions} obj
* @returns {NpmPublishOptions}
*/
function flattenOptions(obj) {
return {
// eslint-disable-next-line dot-notation -- (npm v7 compat)
defaultTag: obj["tag"] || "latest",
dryRun: obj["dry-run"],
...obj,
};
}

function npmPublish(pkg, tarFilePath, _opts, otpCache) {
/**
* @typedef {import('npm-registry-fetch').FetchOptions & { access?: 'public' | 'restricted'; defaultTag?: string; }} LibNpmPublishOptions https://github.com/npm/libnpmpublish#opts
*/

/**
* Publish a package to the configured registry.
* @param {import("@lerna/package")} pkg
* @param {string} tarFilePath
* @param {LibNpmPublishOptions & NpmPublishOptions} [options]
* @param {import("@lerna/otplease").OneTimePasswordCache} [otpCache]
*/
function npmPublish(pkg, tarFilePath, options = {}, otpCache) {
const { dryRun, ...remainingOptions } = flattenOptions(options);
const { scope } = npa(pkg.name);
// pass only the package scope to libnpmpublish
let opts = PublishConfig(_opts, {
const opts = {
log,
...remainingOptions,
projectScope: scope,
});
};

opts.log.verbose("publish", pkg.name);

let chain = Promise.resolve();

if (!opts.dryRun) {
if (!dryRun) {
chain = chain.then(() => {
let { manifestLocation } = pkg;

Expand All @@ -62,18 +74,18 @@ function npmPublish(pkg, tarFilePath, _opts, otpCache) {
// non-default tag needs to override publishConfig.tag,
// which is merged into opts below if necessary
if (
opts.tag !== "latest" &&
opts.defaultTag !== "latest" &&
manifest.publishConfig &&
manifest.publishConfig.tag &&
manifest.publishConfig.tag !== opts.tag
manifest.publishConfig.tag !== opts.defaultTag
) {
// eslint-disable-next-line no-param-reassign
manifest.publishConfig.tag = opts.tag;
manifest.publishConfig.tag = opts.defaultTag;
}

// publishConfig is no longer consumed in n-r-f, so merge here
if (manifest.publishConfig) {
opts = opts.concat(manifest.publishConfig);
Object.assign(opts, publishConfigToOpts(manifest.publishConfig));
}

return otplease((innerOpts) => publish(manifest, tarData, innerOpts), opts, otpCache).catch((err) => {
Expand All @@ -97,3 +109,27 @@ function npmPublish(pkg, tarFilePath, _opts, otpCache) {

return chain;
}

/**
* @typedef {object} PackagePublishConfig
* @property {'public' | 'restricted'} [access]
* @property {string} [registry]
* @property {string} [tag]
*/

/**
* Obtain an object suitable for assignment onto existing options from `pkg.publishConfig`.
* @param {PackagePublishConfig} publishConfig
* @returns {Omit<PackagePublishConfig, 'tag'> & { defaultTag?: string }}
*/
function publishConfigToOpts(publishConfig) {
const opts = { ...publishConfig };

// npm v7 renamed tag internally
if (publishConfig.tag) {
opts.defaultTag = publishConfig.tag;
delete opts.tag;
}

return opts;
}
1 change: 0 additions & 1 deletion utils/npm-publish/package.json
Expand Up @@ -33,7 +33,6 @@
"dependencies": {
"@lerna/otplease": "file:../../core/otplease",
"@lerna/run-lifecycle": "file:../run-lifecycle",
"figgy-pudding": "^3.5.1",
"fs-extra": "^9.0.1",
"libnpmpublish": "^4.0.0",
"npm-package-arg": "^8.1.0",
Expand Down

0 comments on commit bdc162d

Please sign in to comment.