Skip to content

Commit

Permalink
Merge pull request #71 from hdorgeval/pr-npx
Browse files Browse the repository at this point in the history
Be able to run publish-please with npx
  • Loading branch information
hdorgeval authored Jul 16, 2018
2 parents 54b7342 + 816ab12 commit 4974dbe
Show file tree
Hide file tree
Showing 19 changed files with 995 additions and 85 deletions.
5 changes: 4 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ node_js:
- '8'
- '9'
- '10'


before_install:
- if [[ `node -v` = v6* ]]; then npm i -g npx; fi
- npx --version
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [3.2.0] - 2018-07-15
### Added
- be able to run publish-please with npx

## [3.1.1] - 2018-07-01
### Fixed
- gracefully handle prepublish vs prepublishOnly script on all node versions
Expand Down
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ There are numerous ways to "shoot yourself in the foot" using `npm publish`. The
- Get release summary and publishing confirmation.
- Configure publishing using built-in configuration wizard.

## Getting started
## Getting started ( [or use npx directly](#Running-publish-please-with-npx) )

Setup process of *publish-please* is quite trivial - just run
```shell
npm install --save-dev publish-please
Expand Down Expand Up @@ -92,6 +93,24 @@ package
*.tgz
```

## Running publish-please with npx

You can execute publish-please directly with npx:
* **Publish in a dry-run mode**
```sh
npx publish-please --dry-run
```

* **Safely publish to the npm registry**
```sh
npx publish-please
```

* **Setup a configuration file in order to customise the publishing workflow**
```sh
npx publish-please config
```

## Sensitive information audit
**Important note:** tool provides some very basic sensitive data check. Do not rely on it fully. Always perform manual checks for the
sensitive data in your packages.
Expand Down
5 changes: 5 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ environment:
install:
- ps: Install-Product node $env:nodejs_version
- set PATH=%APPDATA%\npm;%PATH%
- ps: >-
if ($env:nodejs_version -eq "6") {
npm i -g npx
}
- npm install
matrix:
fast_finish: false
Expand All @@ -15,6 +19,7 @@ shallow_clone: true
test_script:
- node --version
- npm --version
- npx --version
- npm test
cache:
- '%APPDATA%\npm-cache'
14 changes: 14 additions & 0 deletions lib/post-install.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,21 @@
const fileExists = require('fs').existsSync;
const pathJoin = require('path').join;

function isNpxInstall() {
try {
const getNpmArgs = require('./utils/get-npm-args');
const npmArgs = getNpmArgs(process.env);
return npmArgs.npx ? true : false;
} catch (error) {
return false;
}
}

(function postInstall(currentDir) {
if (isNpxInstall()) {
return;
}

const jsFile = pathJoin(currentDir || __dirname, 'init.js');
if (fileExists(jsFile)) {
const initConfiguration = require(jsFile);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "publish-please",
"version": "3.1.1",
"version": "3.2.0",
"description": "Safe and highly functional replacement for `npm publish`.",
"main": "./lib/index.js",
"bin": {
Expand Down
34 changes: 31 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,48 @@
'use strict';

const getNpmArgs = require('./utils/get-npm-args');
const getNpxArgs = require('./utils/get-npx-args');

module.exports = function() {
if (process.argv.indexOf('guard') > -1) {
return require('./guard')(process.env);
}
const npmArgs = getNpmArgs(process.env);
if (npmArgs && npmArgs['config']) {

if (shouldRunConfigurationWizard()) {
const config = require('./config');
return config.configurePublishPlease.inCurrentProject();
}

if (npmArgs && npmArgs['--dry-run']) {
if (shouldRunInDryMode()) {
return require('./publish/dry-run-workflow')();
}

return require('./publish/publish-workflow')();
};

function shouldRunInDryMode() {
const npmArgs = getNpmArgs(process.env);
if (npmArgs && npmArgs['--dry-run']) {
return true;
}

const npxArgs = getNpxArgs(process);
if (npxArgs && npxArgs['--dry-run']) {
return true;
}

return false;
}

function shouldRunConfigurationWizard() {
const npmArgs = getNpmArgs(process.env);
if (npmArgs && npmArgs['config']) {
return true;
}

const npxArgs = getNpxArgs(process);
if (npxArgs && npxArgs['config']) {
return true;
}
return false;
}
14 changes: 14 additions & 0 deletions src/post-install.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,21 @@
const fileExists = require('fs').existsSync;
const pathJoin = require('path').join;

function isNpxInstall() {
try {
const getNpmArgs = require('./utils/get-npm-args');
const npmArgs = getNpmArgs(process.env);
return npmArgs.npx ? true : false;
} catch (error) {
return false;
}
}

(function postInstall(currentDir) {
if (isNpxInstall()) {
return;
}

const jsFile = pathJoin(currentDir || __dirname, 'init.js');
if (fileExists(jsFile)) {
const initConfiguration = require(jsFile);
Expand Down
3 changes: 3 additions & 0 deletions src/prevent-global-install.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const NO_GLOBAL_INSTALL_MESSAGE = `
module.exports = function preventGlobalInstall() {
const getNpmArgs = require('./utils/get-npm-args');
const npmArgs = getNpmArgs(process.env);
if (npmArgs.npx) {
return;
}
if (npmArgs['--global']) {
reportNoGlobalInstall();
process.exit(1);
Expand Down
26 changes: 26 additions & 0 deletions src/utils/fluent-syntax.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';

module.exports.arg = function(input) {
return {
is: (predicate) => {
return predicate(input);
},
};
};

module.exports.npmCommand = function(args) {
const isValidArgs = args && args.cooked && Array.isArray(args.cooked);
return {
hasArg: (arg) => {
return isValidArgs
? args.cooked.filter((a) => a === arg).length > 0
: false;
},
hasArgThatContains: (substring) => {
/* prettier-ignore */
return isValidArgs
? args.cooked.filter((a) => a && a.includes(substring)).length > 0
: false;
},
};
};
78 changes: 46 additions & 32 deletions src/utils/get-npm-args.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,58 @@
'use strict';
const pathSeparator = require('path').sep;
const npmCommand = require('./fluent-syntax').npmCommand;
const arg = require('./fluent-syntax').arg;

// NOTE: the following code was partially adopted from https://github.com/iarna/in-publish
module.exports = function getNpmArgs(processEnv) {
if (arg(processEnv).is(notValid)) {
return {};
}
const npmArgs = {};
if (processEnv && processEnv['npm_config_argv']) {
try {
const args = JSON.parse(processEnv['npm_config_argv']);
npmArgs.install =
npmCommand(args).hasArg('install') ||
npmCommand(args).hasArg('i');
npmArgs.publish = npmCommand(args).hasArg('publish');
npmArgs.runScript = npmCommand(args).hasArg('run');
npmArgs['--save-dev'] = npmCommand(args).hasArg('--save-dev');
npmArgs['--save'] = npmCommand(args).hasArg('--save');
npmArgs['--global'] = npmCommand(args).hasArg('--global');
npmArgs['--dry-run'] = npmCommand(args).hasArg('--dry-run');
npmArgs['config'] = npmCommand(args).hasArg('config');
// prettier-ignore
npmArgs['--with-publish-please'] = npmCommand(args).hasArg('--with-publish-please');
} catch (err) {
console.warn(
"[Publish-please] Cannot parse property 'npm_config_argv' in process.env "
);
// prettier-ignore
console.warn(
`[Publish-please] process.env['npm_config_argv']= '${processEnv['npm_config_argv']}'`
try {
const args = JSON.parse(processEnv['npm_config_argv']);
npmArgs.install =
npmCommand(args).hasArg('install') || npmCommand(args).hasArg('i');
npmArgs.publish = npmCommand(args).hasArg('publish');
npmArgs.runScript = npmCommand(args).hasArg('run');
npmArgs['--save-dev'] = npmCommand(args).hasArg('--save-dev');
npmArgs['--save'] = npmCommand(args).hasArg('--save');
npmArgs['--global'] = npmCommand(args).hasArg('--global');
npmArgs['--dry-run'] = npmCommand(args).hasArg('--dry-run');
npmArgs['config'] = npmCommand(args).hasArg('config');
npmArgs.npx =
npmCommand(args).hasArg('--prefix') &&
npmCommand(args).hasArgThatContains(
`${pathSeparator}_npx${pathSeparator}`
);
}
// prettier-ignore
npmArgs['--with-publish-please'] = npmCommand(args).hasArg('--with-publish-please');
} catch (err) {
console.error(
"[Publish-please] Cannot parse property 'npm_config_argv' in process.env "
);
// prettier-ignore
console.error(
`[Publish-please] process.env['npm_config_argv']= '${processEnv['npm_config_argv']}'`
);
console.error(`[Publish-please] ${err.message}`);
}

return npmArgs;
};

function npmCommand(args) {
const isValidArgs = args && args.cooked && Array.isArray(args.cooked);
return {
hasArg: (arg) => {
return isValidArgs
? args.cooked.filter((a) => a === arg).length > 0
: false;
},
};
function notValid(processEnv) {
if (processEnv === null || processEnv === undefined) {
return true;
}

if (processEnv['npm_config_argv'] === undefined) {
return true;
}

if (processEnv['npm_config_argv'] === 'undefined') {
return true;
}

return false;
}
37 changes: 37 additions & 0 deletions src/utils/get-npx-args.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'use strict';
const pathSeparator = require('path').sep;

module.exports = function getNpxArgs(process) {
const npxArgs = {};

const args = process && process.argv ? process.argv : [];

npxArgs['--dry-run'] =
npxCommand(args).hasArg('--dry-run') &&
npxCommand(args).hasArgThatContains(
`${pathSeparator}_npx${pathSeparator}`
);
npxArgs['config'] =
npxCommand(args).hasArg('config') &&
npxCommand(args).hasArgThatContains(
`${pathSeparator}_npx${pathSeparator}`
);
return npxArgs;
};

function npxCommand(args) {
const isValidArgs = args && Array.isArray(args);
return {
hasArg: (arg) => {
return isValidArgs
? args.filter((a) => a === arg).length > 0
: false;
},
hasArgThatContains: (substring) => {
/* prettier-ignore */
return isValidArgs ?
args.filter((a) => a && a.includes(substring)).length > 0 :
false;
},
};
}
Loading

0 comments on commit 4974dbe

Please sign in to comment.