Add interactive UI #97
| @@ -2,14 +2,16 @@ | ||
| 'use strict'; | ||
| const meow = require('meow'); | ||
| const updateNotifier = require('update-notifier'); | ||
| +const version = require('./lib/version'); | ||
| +const interactiveui = require('./lib/interactiveui'); |
What do mean exacly with "just call the file and import ui" ?
const ui = require('./lib/interactiveui');this?
| const np = require('./'); | ||
| const cli = meow(` | ||
| Usage | ||
| $ np <version> | ||
| Version can be: | ||
| - patch | minor | major | prepatch | preminor | premajor | prerelease | 1.2.3 | ||
| + ${version.SEMVER_INCREMENTS.join(' | ')} | 1.2.3 | ||
We should have a description here that running just np starts the interactive UI.
| + | ||
| +exports.satisfies = function satisfies(version, range) { | ||
| + return semver.satisfies(version, range); | ||
| +}; |
| @@ -0,0 +1,114 @@ | ||
| +import test from 'ava'; | ||
| +import {SEMVER_INCREMENTS, PRERELEASE_VERSIONS, isValidVersionInput, isPrereleaseVersion, getNewVersion, isVersionGreater, isVersionLower, satisfies} from '../lib/version'; |
| + type: 'list', | ||
| + name: 'version', | ||
| + message: 'Select semver increment or specify new version', | ||
| + choices: version.SEMVER_INCREMENTS.concat([ |
I think we should show what the version would end up being with each increment:
patch (2.3.1)
minor (2.4.0)
major (3.0.0)
And the (2.3.1) should be dimmed with chalk.gray.dim(text).
| + value: null | ||
| + } | ||
| + ]), | ||
| + filter(input) { |
Use inline arrow function.
filter => version.isValidVersionInput(input) ? version.getNewVersion(pkg.version, input) : input,| + }, | ||
| + validate(input) { | ||
| + if (!version.isValidVersionInput(input)) { | ||
| + return 'Please specify a valid semver, e.g. 1.2.3. See http://semver.org/'; |
| + { | ||
| + type: 'list', | ||
| + name: 'tag', | ||
| + message: 'How should this pre-release version be tagged in NPM?', |
| + .then(stdout => { | ||
| + const existingPreleaseTags = stdout.split('\n') | ||
| + .map(line => line.split(':')[0].replace(/^\s|\s$/, '')) | ||
| + .filter(line => line) |
| + return !pkg.private && version.isPrereleaseVersion(answers.version) && !options.tag && !answers.tag; | ||
| + }, | ||
| + validate(input) { | ||
| + if (!input.length) { |
| + }, | ||
| + validate(input) { | ||
| + if (!input.length) { | ||
| + return `Please specify a tag, e.g. next.`; |
return 'Please specify a tag. For example: next';
And generally, don't use template literals when not needed.
| + name: 'confirm', | ||
| + message(answers) { | ||
| + const tag = answers.tag || options.tag; | ||
| + const msg = `Will bump from ${pkg.version} to ${answers.version}${tag ? ` and tag this release in NPM as ${tag}` : ''}. Continue?`; |
|
Can you also document the interactive UI feature in the readme? Could have a new top-level section about it. I think it would be useful to see the current version before the Inquirer questions:
What do you think? |
Could be useful, but necessary if we show the new version after patch, minor and major? Just wondering though :). |
|
@SamVerschueren It gives a clear picture of where you're at without having to calculate backwards. |
I think a gif like in the intro section would be cool. How do you created that?
Makes sense for me.
Private packages are not published to npm, that's why we don't need the "choose your dist-tag" step. |
Yeah. I was planning to create that after this PR. I prefer to do it myself to ensure it's retina and the same style as the existing one. Here's how I do it: sindresorhus/ama#382
Right. I was thinking of private packages, which is a thing, not |
Can you also add the desired instructions about the interactive ui when you do this? I have no clear idea about this |
|
@sindresorhus please have a look again. I've made the requested changes except the instruction things. |
|
Looks great to me. I'm gonna use it for some days to ensure it's working fine and look for possible improvements. @SamVerschueren @kevva @silverwind @scott113341 @unkillbob @developit @Hypercubed Would be awesome if you could try this out and provide some feedback if anything ;) You can install this PR with: Comment your npm username if you want to get added to https://www.npmjs.com/package/sindre-playground to be able to test publishing with a test package. |
|
should perhaps be [version], since it's an optional argument. |
|
What is the difference between prepatch and prerelease? |
|
Please add me. npm-id: ragingwind |
That is a very good question. I don't even know. We copied those from |
Yep, makes sense.
I asked myself the same question a few days ago. I figured out that the option prerelease is basically just a way to increment the last pre release number. When the current version of the package isn't a prerelease (e.g. 1.0.0) it acts like prepatch. Some examples how each option affects the version:
Good catch. The version check is in the wrong order. |
|
Ran this for a couple of my releases and it works like a charm. Great work @zinserjan ! |
|
Works great for me as well. In fact so well I wonder if it could be it's own package. |
| + message: 'How should this pre-release version be tagged in npm?', | ||
| + when: answers => !pkg.private && version.isPrereleaseVersion(answers.version) && !options.tag, | ||
| + choices: () => { | ||
| + return execa.stdout('npm', ['dist-tag', 'ls']) |
Return execa immediately behind the arrow function
choices: () => execa.stdout()
| + choices: () => { | ||
| + return execa.stdout('npm', ['dist-tag', 'ls']) | ||
| + .then(stdout => { | ||
| + const existingPreleaseTags = stdout.split('\n') |
| + .map(line => line.split(':')[0].replace(/^\s|\s$/, '')) | ||
| + .filter(line => line.toLowerCase() !== 'latest'); | ||
| + | ||
| + if (!existingPreleaseTags.length) { |
I would explicitely check for 0
existingPreleaseTags.length === 0
| + message: answers => { | ||
| + const tag = answers.tag || options.tag; | ||
| + const msg = `Will bump from ${oldVersion} to ${answers.version}${tag ? ` and tag this release in npm as ${tag}` : ''}. Continue?`; | ||
| + return msg; |
I think this would be clearer if it was written like this
const tag = answers.tag || options.tag;
const tagPart = tag ? ` and tag this release in npm as ${tag}` : '';
return `Will bump from ${oldVersion} to ${answers.version}${tagPart}. Continue?`;|
Hi @zinserjan , sorry, this is very tangential but are you interested in publishing your work on |
|
@Hypercubed That's too premature. Better to figure out what works and iterate on this here. We can explore what can be extracted as reusable at a later point. |
|
@zinserjan Any chance you could address @SamVerschueren's feedback so we could get this merged? |
|
@sindresorhus @SamVerschueren @Hypercubed I don't see any reason at the moment to publish this under a separate module. When you see a need for this, feel free to do this. I personally don't need this in any other projects. |
@SamVerschueren Any suggestions? |
1 check passed
|
Woot. Landed! Thanks so much for working on this @zinserjan :) |
|
Great job @zinserjan ! |
|
Just fetched and ported to internal tool. Thanks :-) |




This PR adds a interactive ui when np runs without arguments as suggested in #52.
features:
"private": true)Edit(sindresorhus):
You can install this PR with:
$ npm i -g 'zinserjan/np#interactive-ui'and run it with$ np.