Comparing version 1.4.0 to 1.5.0
{ | ||
"name": "spaceman", | ||
"version": "1.4.0", | ||
"version": "1.5.0", | ||
"description": "Manage monorepo workspaces with a prompt-based CLI", | ||
@@ -5,0 +5,0 @@ "author": "Dave Stewart", |
@@ -124,14 +124,4 @@ # Spaceman | ||
To exclude scripts (for example those starting with `~`) you can add an exclusion filter in `package.json`: | ||
See [Settings](#settings) for configure options. | ||
```json | ||
{ | ||
"spaceman": { | ||
"scripts": { | ||
"exclude": "^~" | ||
} | ||
} | ||
} | ||
``` | ||
## Packages | ||
@@ -254,2 +244,28 @@ | ||
## Settings | ||
Some of Spaceman's tasks can be configured. | ||
To do this, add a `spaceman` section to your `package.json` and include the relevant sections: | ||
```json5 | ||
{ | ||
"spaceman": { | ||
"scripts": { | ||
// regexp to exclude scripts from `run` list, e.g. scripts that start with ~ | ||
"exclude": "^~", | ||
// autocomplete match algorithm; choose between "tight" (default) or "loose" | ||
"match": "loose", | ||
} | ||
} | ||
} | ||
``` | ||
Some information on the `script.match` types: | ||
- `tight`: matches on sequential characters, use spaces to start new match groups, i.e. `cli dev` | ||
- `loose`: matches on any character, i.e. `clde` | ||
## Finally... | ||
@@ -256,0 +272,0 @@ |
@@ -31,16 +31,24 @@ const Fs = require('fs') | ||
function chooseScript (input = {}) { | ||
// make options | ||
const makeOption = (path, name) => { | ||
// helper | ||
const makeChoice = (path, name) => { | ||
const value = `${path} ${name}` | ||
const message = path | ||
? path.replace(/^\//, '').grey + ' ' + name | ||
: name | ||
return { | ||
choice: path | ||
? path.replace(/^\//, '').grey + ' ' + name | ||
: name, | ||
path, | ||
name, | ||
value, | ||
message, | ||
indent: ' ', | ||
data: { | ||
path, | ||
name, | ||
} | ||
} | ||
} | ||
const main = getScripts().map(name => makeOption('', name)) | ||
// make options | ||
const main = getScripts().map(name => makeChoice('', name)) | ||
const other = getWorkspaces() | ||
.reduce((items, workspace) => { | ||
const scripts = getScripts(workspace.path).map(name => makeOption(workspace.path, name)) | ||
const scripts = getScripts(workspace.path).map(name => makeChoice(workspace.path, name)) | ||
items.push(...scripts) | ||
@@ -50,15 +58,24 @@ return items | ||
// settings | ||
const { exclude, match } = getSetting('scripts', {}) | ||
// set up exclusion filter | ||
const exclude = getSetting('scripts.exclude') | ||
const rxExclude = exclude ? new RegExp(String(exclude)) : null | ||
const fnInclude = rxExclude | ||
? choice => !rxExclude.test(choice.name) | ||
? choice => !rxExclude.test(choice.data.name) | ||
: () => true | ||
// set up match algorithm | ||
const suggest = (text, choices) => { | ||
const rx = match === 'loose' | ||
? new RegExp(text.split(/\s+/).map(text => text.split('').join('.*')).join('.*\\b.+')) | ||
: new RegExp(text.replace(/\s+/g, '.*')) | ||
return choices.filter(choice => rx.test(choice.value)) | ||
} | ||
// build items | ||
const items = [...main, ...other].filter(fnInclude) | ||
const choices = [...main, ...other].filter(fnInclude) | ||
// build choices | ||
const choices = items.map(item => item.choice) | ||
// options | ||
const options = { | ||
@@ -68,9 +85,6 @@ type: 'autocomplete', | ||
limit: 10, | ||
suggest (text, choices) { | ||
const rx = new RegExp(text.replace(/\s+/g, '.*')) | ||
return choices.filter(choice => rx.test(choice.name)) | ||
suggest, | ||
result (value) { | ||
return choices.find(item => item.value === value).data | ||
}, | ||
result (choice) { | ||
return items.find(item => item.choice === choice) | ||
}, | ||
} | ||
@@ -77,0 +91,0 @@ return ask('script', 'Script', options, input) |
@@ -19,2 +19,20 @@ function toSentence (value) { | ||
function getProperty (data, path = '', defaults = undefined) { | ||
if (data && typeof path === 'string') { | ||
const keys = path.trim().split('.') | ||
do { | ||
const key = keys.shift() | ||
if (key && data) { | ||
data = data[key] | ||
} | ||
else { | ||
return defaults | ||
} | ||
} while (keys.length) | ||
} | ||
return typeof data === undefined | ||
? defaults | ||
: data | ||
} | ||
function removeItem (arr, item) { | ||
@@ -47,2 +65,3 @@ const index = arr.indexOf(item) | ||
sortObject, | ||
getProperty, | ||
removeItem, | ||
@@ -49,0 +68,0 @@ toArray, |
const { readPackage } = require('./package') | ||
const { getProperty } = require('./index') | ||
@@ -7,19 +8,8 @@ /** | ||
* @param {string} setting | ||
* @param {*} defaults | ||
* @returns {string|{}} | ||
*/ | ||
function getSetting (setting = '') { | ||
function getSetting (setting = '', defaults = undefined) { | ||
let settings = readPackage()?.spaceman || {} | ||
if (settings) { | ||
const keys = setting.split('.') | ||
do { | ||
const key = keys.shift() | ||
if (key && settings) { | ||
settings = settings[key] | ||
} | ||
else { | ||
return undefined | ||
} | ||
} while (keys.length) | ||
} | ||
return settings | ||
return getProperty(settings, setting, defaults) | ||
} | ||
@@ -26,0 +16,0 @@ |
39164
1151
274