Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add npm config restore after publish #57

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 35 additions & 13 deletions dist/index.js

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

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

53 changes: 30 additions & 23 deletions src/npm-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,32 @@ import { getNpmEnvironment } from "./npm-env";
* Sets/updates the NPM config based on the options.
* @internal
*/
export async function setNpmConfig(options: NormalizedOptions): Promise<void> {
// Read the current NPM config
let configPath = await getNpmConfigPath(options);
let config = await readNpmConfig(configPath, options);

export async function setUpdatedNpmConfig(
config: string,
configPath: string,
options: NormalizedOptions
): Promise<void> {
// Update the config
config = updateConfig(config, options);

// Save the new config
await writeNpmConfig(configPath, config, options);
await writeNpmConfig(configPath, config, options.debug);
}


/**
* Updates the given NPM config with the specified options.
*/
function updateConfig(config: string, { registry, debug }: NormalizedOptions): string {
function updateConfig(
config: string,
{ registry, debug }: NormalizedOptions
): string {
let authDomain = registry.origin.slice(registry.protocol.length);

let lines = config.split(/\r?\n/);

// Remove any existing lines that set the registry or token
lines = lines.filter((line) =>
!(line.startsWith("registry=") || line.includes("_authToken="))
lines = lines.filter(
(line) => !(line.startsWith("registry=") || line.includes("_authToken="))
);

// Append the new registry and token to the end of the file
Expand All @@ -46,39 +48,42 @@ function updateConfig(config: string, { registry, debug }: NormalizedOptions): s
return config;
}


/**
* Gets the path of the NPM config file.
*/
async function getNpmConfigPath(options: NormalizedOptions): Promise<string> {
export async function getNpmConfigPath(
options: NormalizedOptions
): Promise<string> {
try {
// Get the environment variables to pass to NPM
let env = getNpmEnvironment(options);

options.debug("Running command: npm config get userconfig");

let process = await ezSpawn.async("npm", "config", "get", "userconfig", { env });
let process = await ezSpawn.async("npm", "config", "get", "userconfig", {
env,
});
return process.stdout.trim();
}
catch (error) {
} catch (error) {
throw ono(error, "Unable to determine the NPM config file path.");
}
}


/**
* Reads the NPM config file.
*/
async function readNpmConfig(configPath: string, { debug }: NormalizedOptions): Promise<string> {
export async function readNpmConfig(
configPath: string,
{ debug }: NormalizedOptions
): Promise<string> {
try {
debug(`Reading NPM config from ${configPath}`);

let config = await fs.readFile(configPath, "utf-8");

debug(`OLD NPM CONFIG: \n${config}`);
return config;
}
catch (error) {
} catch (error) {
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
debug("OLD NPM CONFIG: <none>");
return "";
Expand All @@ -88,18 +93,20 @@ async function readNpmConfig(configPath: string, { debug }: NormalizedOptions):
}
}


/**
* Writes the NPM config file.
*/
async function writeNpmConfig(configPath: string, config: string, { debug }: NormalizedOptions): Promise<void> {
export async function writeNpmConfig(
configPath: string,
config: string,
debug: NormalizedOptions["debug"]
): Promise<void> {
try {
debug(`Writing new NPM config to ${configPath}`);

await fs.mkdir(dirname(configPath), { recursive: true });
await fs.writeFile(configPath, config);
}
catch (error) {
} catch (error) {
throw ono(error, `Unable to update the NPM config file: ${configPath}`);
}
}
73 changes: 52 additions & 21 deletions src/npm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import { StdioOptions } from "child_process";
import { dirname, resolve } from "path";
import { SemVer } from "semver";
import { NormalizedOptions } from "./normalize-options";
import { setNpmConfig } from "./npm-config";
import {
getNpmConfigPath,
readNpmConfig,
setUpdatedNpmConfig,
writeNpmConfig,
} from "./npm-config";
import { getNpmEnvironment } from "./npm-env";
import { Manifest } from "./read-manifest";

Expand All @@ -16,17 +21,22 @@ export const npm = {
/**
* Gets the latest published version of the specified package.
*/
async getLatestVersion(name: string, options: NormalizedOptions): Promise<SemVer> {
async getLatestVersion(
name: string,
options: NormalizedOptions
): Promise<SemVer> {
// Update the NPM config with the specified registry and token
await setNpmConfig(options);
const configPath = await getNpmConfigPath(options);
const initialConfig = await readNpmConfig(configPath, options);
// Update the NPM config with the specified registry and token
await setUpdatedNpmConfig(initialConfig, configPath, options);

try {
let command = ["npm", "view"];

if (options.tag === "latest") {
command.push(name);
}
else {
} else {
command.push(`${name}@${options.tag}`);
}

Expand All @@ -36,13 +46,15 @@ export const npm = {
let env = getNpmEnvironment(options);

// Run NPM to get the latest published version of the package
options.debug(`Running command: npm view ${name} version`, { command, env });
options.debug(`Running command: npm view ${name} version`, {
command,
env,
});
let result;

try {
result = await ezSpawn.async(command, { env });
}
catch (err) {
} catch (err) {
// In case ezSpawn.async throws, it still has stdout and stderr properties.
result = err as ezSpawn.ProcessError;
}
Expand All @@ -53,10 +65,11 @@ export const npm = {

// If the package was not previously published, return version 0.0.0.
if ((status === 0 && !version) || error.includes("E404")) {
options.debug(`The latest version of ${name} is at v0.0.0, as it was never published.`);
options.debug(
`The latest version of ${name} is at v0.0.0, as it was never published.`
);
return new SemVer("0.0.0");
}
else if (result instanceof Error) {
} else if (result instanceof Error) {
// NPM failed for some reason
throw result;
}
Expand All @@ -66,19 +79,27 @@ export const npm = {

options.debug(`The latest version of ${name} is at v${semver}`);
return semver;
}
catch (error) {
throw ono(error, `Unable to determine the current version of ${name} on NPM.`);
} catch (error) {
throw ono(
error,
`Unable to determine the current version of ${name} on NPM.`
);
} finally {
await writeNpmConfig(configPath, initialConfig, options.debug);
}
},


/**
* Publishes the specified package to NPM
*/
async publish({ name, version }: Manifest, options: NormalizedOptions): Promise<void> {
async publish(
{ name, version }: Manifest,
options: NormalizedOptions
): Promise<void> {
const configPath = await getNpmConfigPath(options);
const initialConfig = await readNpmConfig(configPath, options);
// Update the NPM config with the specified registry and token
await setNpmConfig(options);
await setUpdatedNpmConfig(initialConfig, configPath, options);

try {
let command = ["npm", "publish"];
Expand All @@ -105,11 +126,21 @@ export const npm = {
let env = getNpmEnvironment(options);

// Run NPM to publish the package
options.debug("Running command: npm publish", { command, stdio, cwd, env });
options.debug("Running command: npm publish", {
command,
stdio,
cwd,
env,
});
await ezSpawn.async(command, { cwd, stdio, env });
}
catch (error) {
throw ono(error, `Unable to publish ${name} v${version} to ${options.registry}.`);
} catch (error) {
throw ono(
error,
`Unable to publish ${name} v${version} to ${options.registry}.`
);
} finally {
// Restore the npm config
await writeNpmConfig(configPath, initialConfig, options.debug);
}
},
};