Create beautiful CLI interfaces via easy and logical to-implement task lists that feel alive and interactive.
You can find the documentation source code in here.
You can find the examples here.
NodeJS Task List derived from the best! Create beautiful CLI interfaces via easy and logical to implement task lists that feel alive and interactive.
License: MIT License
This is a issue from Listr original but affect this version too: SamVerschueren/listr#150
I'm currently using this function inspired by (copied from) the prompt method:
function createCustomPrompt(task, Prompt, options) {
task.prompt = true;
let buffer = Buffer.alloc(64);
const outputStream = through((data) => {
buffer += data;
// eslint-disable-next-line no-control-regex
const deleteMultiLineRegexp = new RegExp(/.*(\u001b\[[0-9]*G|\u0007).*/m); 12
if (deleteMultiLineRegexp.test(buffer.toString())) {
buffer = Buffer.alloc(64);
} else {
task.output = buffer.toString();
}
});
Object.assign(options, { stdout: outputStream });
return new Prompt(options);
}
With for example the enquirer-editor like this:
import EditorPrompt from 'enquirer-editor';
import { Manager } from 'listr2';
const manager = new Manager();
manager.add({
title: 'Editor',
task: async (_, task) => {
const prompt = createCustomPrompt(task, EditorPrompt, { type: 'editor', message: 'Please Fill' });
const message = await prompt.run();
}
})
manager.runAll();
This works quite well, I was just wondering, @cenk1cenk2 do you think there's a way to incorporate this into listr2 somehow?
Or maybe make the prompt
method from TaskWrapper
more versatile to accept custom prompt classes?
Running lint-staged (using listr2 2.0.1 https://github.com/okonet/lint-staged/blob/master/package.json#L41) fails when running with the following stack:
husky > pre-commit (node v13.3.0)
internal/modules/cjs/loader.js:621
throw e;
^
Error: No valid exports main found for 'project/node_modules/listr2/node_modules/uuid'
at resolveExportsTarget (internal/modules/cjs/loader.js:618:9)
at applyExports (internal/modules/cjs/loader.js:499:14)
at resolveExports (internal/modules/cjs/loader.js:548:12)
at Function.Module._findPath (internal/modules/cjs/loader.js:650:22)
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:948:27)
at Function.Module._load (internal/modules/cjs/loader.js:854:27)
at Module.require (internal/modules/cjs/loader.js:1023:19)
at require (internal/modules/cjs/helpers.js:72:18)
at Object.<anonymous> (project/node_modules/listr2/dist/lib/task.js:9:16)
at Module._compile (internal/modules/cjs/loader.js:1128:30) {
code: 'MODULE_NOT_FOUND'
}
husky > pre-commit hook failed (add --no-verify to bypass)
I've tried removing node_modules
and package-lock and re-installing but no luck π
Hello,
we're in the process of migrating lint-staged to Listr2, but I have some question regarding test output assertion.
The orginal Listr's verbose renderer printed [started]
and [completed]
strings, while Listr2 uses fancy symbols like β―
and β
. These symbols are different on each platform, though, so testing in a CI environment is a bit difficult.
You can see the progress in the PR lint-staged/lint-staged#852 and how the assertions fail on our Windows tests: https://ci.appveyor.com/project/okonet/lint-staged/builds/32413566/job/qyae7t039cckykre
There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.
Error type: Cannot find preset's package (github>whitesource/merge-confidence:beta)
I'm currently using Listr2 to run a set of subtasks, and I wanted to know if there's a way to change the title of the parent, on succesful completion. For eg. in the snippet below, I'd like to change Uploading
to Uploaded
once all the subtasks are done.
// `uploadTasks` -> an array of ListrTask objects
new Listr([
title: "Uploading some docs",
task: async (_, task) => task.newListr(uploadTasks, listrOptions);
]});
I'm not sure if I'm missing something here, but since task.newListr
returns a Listr
object, and not a Promise
, I cannot update the task.title
from there. Would be great if you could let me know of a way to do this. Thanks!
The error message is replaced with 'Cancelled the prompt' when a task is to be marked as failed by the developer but a prompt was used in it.
Maybe there could be a task.fail
method instead to distinguish between exceptions thrown from internal packages (if that is the concern) and custom exceptions (signalling a task has failed because of whatever the user put in).
It would be really helpful to have the elpasedTime
option in the verbose renderer to display how much time tasks took.
Hi there! π
First of all, thanks for your contribution of listr2
to the community! This is a great library, and saves a bunch of boilerplate!
I am a bit confused with listr2's behavior of truncating and removing empty lines in my errors. The content and the formatting that I'm writing in the errors is important, and I would like it to stay the same.
See the error in the source code and the formatting in the terminal. The first line of the error is truncated and the empty line is removed:
Here are our options:
{
exitOnError: false,
rendererOptions: { collapseErrors: false },
concurrent: 5,
}
It seems like this could also be a default for listr2
, but maybe there's a reason why that's not a good idea.
cc @Josehower
Awesome work on bringing old listr back to life!
One small nuance that is pretty annoying though: currently listr2 does not have support for multi-step enquirer prompts. It would be amazing, if this feature could be added.
{
title: "Configure",
task: async (ctx, task) => {
ctx.input = await task.prompt([
{
type: 'input',
name: 'name',
message: 'What is your name?'
},
{
type: 'input',
name: 'username',
message: 'What is your username?'
}
]);
},
}
I wanted to leave a trace here about a promising PR in the enquirer
repo regarding TypeScript definitions (enquirer/enquirer#307).
I understand that the typings provided by listr2
are an internal reproduction of Enquirer's typings, although they are incomplete. Hopefully once the above PR is merged and published, the custom typings in listr2
can be removed!
Thanks for all the hard work on this great package btw! I love the developer experience here π
Hello.
I am trying since a while to determine how I am supposed to create tests for the prompts. Using Enquirer
directly, I can use its events, but using Listr
, I don't have access to the underlying Enquirer
object.
Is there currently any way to test prompts? Thanks!
EDIT - I think the ability to pass an instance of Enquirer
, the same as logger
, to a Listr
object, would solve the issue, because we would be able to pass a fake Enquirer
object, hence, to test it.
Hey π
I've got a download stream with on('progress')
event:
{
title: 'Download task',
task: () => {
const stream = downloadStream(videoUrl)
.on('progress', ({ num }, totalSegments, bytes) => {
// send to listr
})
stream.pipe(fs.createWriteStream('videofile.mp4'))
return stream
}
}
If I use above code, chunks of downloaded data will be shown in console. I'd love to show message from progress
event.
I don't have enough knowledge with streams, I've tried some ideas but didn't succeed. Is it somehow possible?
This issue provides visibility into Renovate updates and their statuses. Learn more
These updates are awaiting their schedule. Click on a checkbox to get an update now.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
simple-git-hooks
, ts-node
, tsconfig-paths
, tsup
, typedoc
, typedoc-plugin-markdown
, typescript
)@cenk1cenk2/cz-cc
, @cenk1cenk2/eslint-config
)@types/jest
, eslint
, jest
, jest-mock-process
, lint-staged
, prettier
, ts-jest
)@types/wrap-ansi
, tsconfig-paths
, tsup
)@types/jest
, jest
, lint-staged
, ts-jest
)These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.
docker-compose.yml
cenk1cenk2/node-fnm latest
.drone.yml
node current-alpine
node current-alpine
node current-alpine
node current-alpine
node current-alpine
cenk1cenk2/drone-semantic-release no version found
plugins/downstream no version found
.github/workflows/nodejs.yml
actions/checkout v2
actions/setup-node v2
actions/checkout v2
actions/setup-node v2
actions/checkout v2
actions/setup-node v2
.github/workflows/semantic-release.yml
actions/checkout v2
cycjimmy/semantic-release-action v2.7.0
.github/workflows/sync.yml
actions/checkout v2
TreTuna/sync-branches 1.4.0
.github/workflows/test-coverage.yml
actions/checkout v2
actions/setup-node v2
codecov/codecov-action v2
package.json
cli-truncate ^2.1.0
colorette ^2.0.16
log-update ^4.0.0
p-map ^4.0.0
rfdc ^1.3.0
rxjs ^7.5.5
through ^2.3.8
wrap-ansi ^7.0.0
@cenk1cenk2/cz-cc ^1.4.11
@cenk1cenk2/eslint-config 2.5.5
@types/clone ^2.1.1
@types/jest ^27.4.0
@types/node ^17.0.14
@types/through ^0.0.30
@types/wrap-ansi ^3.0.0
delay ^5.0.0
enquirer ^2.3.6
eslint ^8.8.0
jest ^27.4.7
jest-mock-process ^1.4.1
lint-staged ^12.3.2
prettier ^2.5.1
rimraf ^3.0.2
simple-git-hooks ^2.7.0
ts-jest ^27.1.3
ts-node ^10.4.0
tsconfig-paths ^3.12.0
tsup 5.11.13
typedoc ^0.22.11
typedoc-plugin-markdown ^3.11.12
typescript ^4.6.0-dev.20220131
enquirer >= 2.3.0 < 3
node >=12
.nvmrc
node 16
When using the default renderer, and the following options
Renderer options:
concurrent: false,
rendererOptions: {
collapse: false,
showSubtasks: true
}
Task options:
persistentOutput: true,
exitOnError: true,
bottomBar: Infinity
When an error is throw by a task, the output that it previously posted to the bottom bar is cleared, even though output from previous successful tasks are preserved.
Is there a way to preserve output even if an error is thrown?
If not, perhaps a task option for preserveOutputOnError
can be added?
First run the following exactly as is, then uncomment line 14 and re-run it:
const { Listr } = require('Listr2');
const tasks = new Listr([
{
title: 'Demo of edge case',
task: async (ctx, task) => {
console.log('I thought I was losing my mind.')
console.log('Turns out that I\'m not losing it (yet), it\'s just an edge case.')
console.log('Specifically, when the task includes:')
console.log('options: {\n\tpersistentOutput: true\n}')
console.log('and the Listr options include:')
console.log('{\n\trendererOptions: { collapse: false }\n}')
console.error('Then the last displayable line of either a console.log or console.error (and presumably, their other variations, e.g. console.warn, console.table, etc) is overwritten')
// console.log('unless the last line ends with a \\n\n')
},
options: {
persistentOutput: true
}
},
], {
rendererOptions: { collapse: false }
});
tasks.run()
.then(() => { })
.catch(() => { });
I've tried to simply run
and await
the inner Listr
instance, but then the UI breaks.
new Listr([/* ... */, {
title: 'Some task with inner list',
task: async (_, task) => {
try {
await task.newListr([/* some tasks, one of them might fail */], {
concurrent: true
}).run();
task.title += ' (success)';
} catch (err) {
task.title += ' (failed)';
// plus some cleanup logic, to restore state of things before
// the whole process started
}
}
}], {
exitOnError: false,
});
The repository with code producing above: https://github.com/erykpiast/listr2-callback
When executing Listr2 on Windows 10 with PowerShell there are some lines that are duplicated.
Here is the code
const tasks = new Listr<any>([
{
title: 'Task1',
task: () => jenkins.executeJobAndWaitForResultAsync(job)
},
{
title: 'Task2',
task: () => jenkins.executeJobAndWaitForResultAsync(job2)
},
], {concurrent: false});
tasks.run().catch((err) => {
console.error(err);
});
In one of my use cases, I would like the user to press a key if they want to interrupt the current task, otherwise continue on.
For example, I have an enquirer prompt that is something like the following Press any key to abort, otherwise continuing in 10 seconds...
However, when I skip the task while the prompt is active, the task get skipped but the prompt is still active in the background.
If I try to cancel the prompt, I always get hit with an error so that too exits the pipeline
enquirer.on("prompt", async prompt => {
await delay(10000);
prompt.cancel();
});
Lastly, if I try to skip the prompt with the built in skip function (which accepts a Promise<boolean>
type), the prompt disappears into the background but is still active until it gets skipped
const status = await task.prompt({
name: "continue",
type: "input",
message: `Press any key to abort, continuing in 10 seconds otherwise`,
skip: async () => {
await delay(10000);
return true;
}
});
What would be the appropriate approach for this pattern? I can make a contribution for it as well
No error message from the prompts are catched.
This issue contains a list of Renovate updates and their statuses.
These updates are awaiting their schedule. Click on a checkbox to ignore the schedule.
@types/jest
, @types/node
)These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
Using the following example:
const setupTasks = new Listr({
title: 'Root Task',
task: (ctx, task): Listr =>
task.newListr(
[
{
options: { persistentOutput: true },
title: 'Sub task 1',
task: async (subCtx, subTask): Promise<void> => {
await CommonUtils.delay(2000);
subTask.output = 'PASSED: success message goes here';
return Promise.resolve();
}
},
{
options: { persistentOutput: true },
title: 'Sub task 2',
task: async (subCtx, subTask): Promise<void> => {
await CommonUtils.delay(1500);
subTask.output = 'FAILED: A very long error message goes here that should wrap but does not. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi auctor felis velit, sed imperdiet nisi venenatis nec. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris viverra lacus id lacus lobortis facilisis. Vivamus eu nisl eget lectus euismod ornare a vitae ex. Aliquam congue ultrices dictum. Mauris pretium quam nec nisl rutrum, et ornare dui viverra. Nulla pharetra faucibus ante, sed tempor sem pretium vel. Aliquam convallis ligula eu ex tristique ullamcorper. Morbi sollicitudin mauris tellus, in egestas sapien pharetra ac.';
return Promise.reject(new Error());
}
},
{
options: { persistentOutput: true },
title: 'Sub task 3',
task: async (subCtx, subTask): Promise<void> => {
await CommonUtils.delay(1000);
subTask.output = 'FAILED: Another long error message that should wrap but does not. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi auctor felis velit, sed imperdiet nisi venenatis nec. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris viverra lacus id lacus lobortis facilisis. Vivamus eu nisl eget lectus euismod ornare a vitae ex. Aliquam congue ultrices dictum. Mauris pretium quam nec nisl rutrum, et ornare dui viverra. Nulla pharetra faucibus ante, sed tempor sem pretium vel. Aliquam convallis ligula eu ex tristique ullamcorper. Morbi sollicitudin mauris tellus, in egestas sapien pharetra ac.';
return Promise.reject(new Error());
}
}
],
{ concurrent: true, exitOnError: false, rendererOptions: { collapse: false, collapseErrors: false, formatOutput: 'wrap' } }
)
});
try {
await setupTasks.run();
} catch (error) {
console.log(error);
}
Listr2 generates the following:
But formatOutput: 'wrap'
was set for rendererOptions
so shouldn't the output messages be wrapped instead of truncated?
The latest version 2.6.0 of listr2 is not being replicated in npm - https://replicate.npmjs.com/listr2. It shows the latest version as 2.5.1. I just thought you should know
I have raised this with npm support but so far they all they have said is it can take a few hours to replicate, but this was published 11 days ago and counting
Since I am mirroring npm from replicate.npmjs.com, build processes are failing because other packages are relying on this version.
The original listr package displays the message from eg. skip underneath the task name.
Listr2 replaces the title with the message:
This leads to a bit of confusion, since the message is in the middle of task names and feels out of place. I didn't find an option to disable this. Is it possible for the renderer to print the skip messages indented and underneath:
I currently use this snippet to achieve this:
manager.add({
title: 'Bump version',
task: () => {
if (shouldSkip === true) {
return new Listr({
title: "Doesn't matter",
task: (_, task) => task.skip('Version has been already changed')
}, { collapse: false })
}
return '...!'
}
});
I have some tasks in my list that are ok to fail, and some that are not. I thought I could pass the exitOnError: false
option to a task, but it appears that that option can only be passed while calling run
.
This doesn't work, when encountering the error list exits
const listr = new Listr(
[
{
title: 'Allow fail',
task: () => {
throw new Error();
},
options: { exitOnError: false },
},
];
As a workaround
const listr = new Listr(
[
{
title: 'Allow fail',
task: (ctx, task) => {
return task.newListr(
[
{
task: () => {
throw new Error();
},
},
],
{ exitOnError: false }
);
},
},
]
this works as desired, but is inconvenient. Is there another way?
I am trying to do a row of prompts and want one prompt to be skipped or of type text. The simplest solution for this is to use an if-statement with a previous prompt's response value, but the ctx does not contain the previous just the current prompt.
ctx.version = await task.prompt([
{
type: 'select',
name: 'version',
message: 'New version',
choices
},
{
// prev contains only current prompt not from select version
type: (prev) => (prev == 'custom' ? 'text' : null),
name: 'version',
message: 'Version',
validate: validator,
},
])
How can I use this with Ink ?
and when running on git bash, spinner is showing only line, it not showing rotating dots link in demo, and symbols are very small, is there a way to customize it ?
Hey!
It would be very nice if listr2 would also have enquirer support just as the first version did. Currently it's possible to execute async commands and wait for them to complete, however streaming the output from them does not seem to be possible.
Example:
{
title: "List files",
task: (ctx) => {
return execa.command(" ls -lah . && sleep 10 && ls -lah .");
}
}
The command will execute successfully, however the output will not be streamed. I tried a bunch of different variations as well, but none were successful. The output is not being streamed to the console.
Help here would be much appreciated!
Isolate renderer options.
@cenk1cenk2 I want to extract the rendering options to their own key as well. Shortly after I did it like it is now, I already had regret that I did it this way. So that would definitely be an improvement.
Originally posted by @SamVerschueren in SamVerschueren/listr#143 (comment)
When trying to integrate Enquirer prompts for the first time It took some digging in your code to figure out how to get number prompts to work.
In your code you export a Numeral
type.
But in the enquirer docs they have a Markdown heading for a Numeral
type (which is maybe where you got your naming from?) but the actual thing they export is a NumberPrompt
:
https://github.com/enquirer/enquirer#numeral-prompt
I don't know why they have this confusion either.
Is it possible to help clear up the confusion to make this more discoverable? Or make Number
an alias of Numeral
? Perhaps also document here which types Listr2
works with?
https://listr2.kilic.dev/general-usage/user-input
Thanks!
I'm creating a CLI to collect benchmarks, and I want to run a set of tasks n times. However, I don't want to create a new task for each one as n could be as high as 100.
Instead, I want to use one task that repeats it's sub-task n times, and updates the output message to Iteration ${i}
.
An API like this where I can insert/run arbitrary Listr instances dynamically at run-time:
const listr = new Listr<Options>([
{
title: 'Benchmarking',
async task(context, task) {
for (let i = 0; i < 10; i++) {
task.output = `Iteration ${i}`;
// Run arbitrary listr instances as a sub-task
await task.run(task.newListr([
{
title: 'Task A',
task() { ... }
},
{
title: 'Task B',
task() { ... }
},
{
title: 'Task C',
task() { ... }
}
]));
}
}
},
...
]);
When using Listr2 in a TypeScript project I am getting the following TSC error when using v3.3.0:
../../node_modules/listr2/dist/lib/task-wrapper.d.ts:27:5 - error TS2416: Property 'run' in type 'TaskWrapper<Ctx, Renderer>' is not assignable to the same property in base type 'ListrTaskWrapper<Ctx, Renderer>'.
Type '(ctx: Ctx) => Promise<void>' is not assignable to type '(ctx?: Ctx | undefined, task?: ListrTaskWrapper<Ctx, Renderer> | undefined) => Promise<void>'.
Types of parameters 'ctx' and 'ctx' are incompatible.
Type 'Ctx | undefined' is not assignable to type 'Ctx'.
'Ctx' could be instantiated with an arbitrary type which could be unrelated to 'Ctx | undefined'.
Type 'undefined' is not assignable to type 'Ctx'.
'Ctx' could be instantiated with an arbitrary type which could be unrelated to 'undefined'.
27 run(ctx: Ctx): Promise<void>;
It compiles fine with the previous v3.2.3.
This is a a big thank you for your efforts in developing this!
I was struggling to integrate listr
in my company's publishing pipeline since it required custom inputs and then I came across listr2
. Simply Awesome! Worked perfectly and the types are a huge bonus too. Not to mention the fast responses with fixing stray issues and bugs, I encountered along the way.
Just wanted to extend my thanks for this effort.
I hope more projects can benefit from your effort and this package in the future β€οΈ
Feel free to close this issue once you read it π
(if possible, leave it unlocked for other people to leave their own thank you's in the future π)
Hi, I am using Listr2 in a project and getting a bunch of errorrs from the declaration files that this library exports.
tsc -v Version 4.0.2
here is my tsconfig
{
"compilerOptions": {
"composite": true,
"declaration": true,
"declarationMap": true,
"importHelpers": true,
"module": "commonjs",
"strict": true,
"target": "es2017",
"esModuleInterop": true,
"lib": ["ESNext", "dom"],
"sourceMap": true,
"moduleResolution": "node",
"noImplicitReturns": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"pretty": true
},
"exclude": [
"node_modules",
"**/*.test.ts"
],
"include": [
"src/**/*"
]
}
running tsc -b emits the errors below
@typerpc/cli: The type 'readonly ListrTaskObject<any, ListrRendererFactory>[]' is 'readonly' and cannot be assigned to the mutable type 'ListrTaskObject<any, typeof DefaultRenderer>[]'.
@typerpc/cli: ../../node_modules/listr2/dist/renderer/default.renderer.d.ts(30,45): error TS2344: Type 'typeof DefaultRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/renderer/default.renderer.d.ts(31,47): error TS2344: Type 'typeof DefaultRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/renderer/default.renderer.d.ts(32,44): error TS2344: Type 'typeof DefaultRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/renderer/default.renderer.d.ts(33,52): error TS2344: Type 'typeof DefaultRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/renderer/default.renderer.d.ts(34,41): error TS2344: Type 'typeof DefaultRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/renderer/default.renderer.d.ts(35,44): error TS2344: Type 'typeof DefaultRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/renderer/silent.renderer.d.ts(3,33): error TS2344: Type 'typeof SilentRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: Types of parameters 'tasks' and 'tasks' are incompatible.
@typerpc/cli: The type 'readonly ListrTaskObject<any, ListrRendererFactory>[]' is 'readonly' and cannot be assigned to the mutable type 'ListrTaskObject<any, typeof SilentRenderer>[]'.
@typerpc/cli: ../../node_modules/listr2/dist/renderer/silent.renderer.d.ts(8,45): error TS2344: Type 'typeof SilentRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/renderer/verbose.renderer.d.ts(4,33): error TS2344: Type 'typeof VerboseRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: Types of parameters 'tasks' and 'tasks' are incompatible.
@typerpc/cli: The type 'readonly ListrTaskObject<any, ListrRendererFactory>[]' is 'readonly' and cannot be assigned to the mutable type 'ListrTaskObject<any, typeof VerboseRenderer>[]'.
@typerpc/cli: ../../node_modules/listr2/dist/renderer/verbose.renderer.d.ts(15,45): error TS2344: Type 'typeof VerboseRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/interfaces/listr.interface.d.ts(18,22): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer | (Renderer extends "verbose" ? typeof VerboseRenderer : Renderer extends "silent" ? typeof SilentRenderer : Renderer extends ListrRendererFactory ? Renderer : never)' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'ListrRendererFactory | typeof DefaultRenderer | typeof VerboseRenderer | typeof SilentRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/interfaces/listr.interface.d.ts(19,48): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/interfaces/listr.interface.d.ts(21,31): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/interfaces/listr.interface.d.ts(21,99): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/interfaces/listr.interface.d.ts(109,33): error TS2344: Type 'typeof ListrBaseRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: Types of parameters 'tasks' and 'tasks' are incompatible.
@typerpc/cli: The type 'readonly ListrTaskObject<any, ListrRendererFactory>[]' is 'readonly' and cannot be assigned to the mutable type 'ListrTaskObject<any, typeof ListrBaseRenderer>[]'.
@typerpc/cli: ../../node_modules/listr2/dist/interfaces/listr.interface.d.ts(111,45): error TS2344: Type 'typeof ListrBaseRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/listr.d.ts(4,26): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer | (Renderer extends "verbose" ? typeof VerboseRenderer : Renderer extends "silent" ? typeof SilentRenderer : Renderer extends ListrRendererFactory ? Renderer : never)' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'ListrRendererFactory | typeof DefaultRenderer | typeof VerboseRenderer | typeof SilentRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/listr.d.ts(4,85): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/listr.d.ts(6,22): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/listr.d.ts(13,38): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/listr.d.ts(13,97): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/listr.d.ts(14,30): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/listr.d.ts(14,89): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/manager.d.ts(9,54): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer | (Renderer extends "verbose" ? typeof VerboseRenderer : Renderer extends "silent" ? typeof SilentRenderer : Renderer extends ListrRendererFactory ? Renderer : never)' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'ListrRendererFactory | typeof DefaultRenderer | typeof VerboseRenderer | typeof SilentRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/manager.d.ts(9,143): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/manager.d.ts(11,177): error TS2344: Type 'ListrGetRendererClassFromValue<InjectRenderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer | (InjectRenderer extends "verbose" ? typeof VerboseRenderer : InjectRenderer extends "silent" ? typeof SilentRenderer : InjectRenderer extends ListrRendererFactory ? InjectRenderer : never)' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'ListrRendererFactory | typeof DefaultRenderer | typeof VerboseRenderer | typeof SilentRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/manager.d.ts(12,57): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/manager.d.ts(12,146): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/manager.d.ts(12,304): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/manager.d.ts(12,378): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/manager.d.ts(13,54): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: The type 'readonly ListrTaskObject<any, ListrRendererFactory>[]' is 'readonly' and cannot be assigned to the mutable type 'ListrTaskObject<any, typeof DefaultRenderer>[]'.
@typerpc/cli: ../../node_modules/listr2/dist/renderer/default.renderer.d.ts(30,45): error TS2344: Type 'typeof DefaultRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/renderer/default.renderer.d.ts(31,47): error TS2344: Type 'typeof DefaultRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/renderer/default.renderer.d.ts(32,44): error TS2344: Type 'typeof DefaultRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/renderer/default.renderer.d.ts(33,52): error TS2344: Type 'typeof DefaultRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/renderer/default.renderer.d.ts(34,41): error TS2344: Type 'typeof DefaultRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/renderer/default.renderer.d.ts(35,44): error TS2344: Type 'typeof DefaultRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/renderer/silent.renderer.d.ts(3,33): error TS2344: Type 'typeof SilentRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: Types of parameters 'tasks' and 'tasks' are incompatible.
@typerpc/cli: The type 'readonly ListrTaskObject<any, ListrRendererFactory>[]' is 'readonly' and cannot be assigned to the mutable type 'ListrTaskObject<any, typeof SilentRenderer>[]'.
@typerpc/cli: ../../node_modules/listr2/dist/renderer/silent.renderer.d.ts(8,45): error TS2344: Type 'typeof SilentRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/renderer/verbose.renderer.d.ts(4,33): error TS2344: Type 'typeof VerboseRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: Types of parameters 'tasks' and 'tasks' are incompatible.
@typerpc/cli: The type 'readonly ListrTaskObject<any, ListrRendererFactory>[]' is 'readonly' and cannot be assigned to the mutable type 'ListrTaskObject<any, typeof VerboseRenderer>[]'.
@typerpc/cli: ../../node_modules/listr2/dist/renderer/verbose.renderer.d.ts(15,45): error TS2344: Type 'typeof VerboseRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/interfaces/listr.interface.d.ts(18,22): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer | (Renderer extends "verbose" ? typeof VerboseRenderer : Renderer extends "silent" ? typeof SilentRenderer : Renderer extends ListrRendererFactory ? Renderer : never)' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'ListrRendererFactory | typeof DefaultRenderer | typeof VerboseRenderer | typeof SilentRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/interfaces/listr.interface.d.ts(19,48): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/interfaces/listr.interface.d.ts(21,31): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/interfaces/listr.interface.d.ts(21,99): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/interfaces/listr.interface.d.ts(109,33): error TS2344: Type 'typeof ListrBaseRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: Types of parameters 'tasks' and 'tasks' are incompatible.
@typerpc/cli: The type 'readonly ListrTaskObject<any, ListrRendererFactory>[]' is 'readonly' and cannot be assigned to the mutable type 'ListrTaskObject<any, typeof ListrBaseRenderer>[]'.
@typerpc/cli: ../../node_modules/listr2/dist/interfaces/listr.interface.d.ts(111,45): error TS2344: Type 'typeof ListrBaseRenderer' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/listr.d.ts(4,26): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer | (Renderer extends "verbose" ? typeof VerboseRenderer : Renderer extends "silent" ? typeof SilentRenderer : Renderer extends ListrRendererFactory ? Renderer : never)' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'ListrRendererFactory | typeof DefaultRenderer | typeof VerboseRenderer | typeof SilentRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/listr.d.ts(4,85): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/listr.d.ts(6,22): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/listr.d.ts(13,38): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/listr.d.ts(13,97): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/listr.d.ts(14,30): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/listr.d.ts(14,89): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/manager.d.ts(9,54): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer | (Renderer extends "verbose" ? typeof VerboseRenderer : Renderer extends "silent" ? typeof SilentRenderer : Renderer extends ListrRendererFactory ? Renderer : never)' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'ListrRendererFactory | typeof DefaultRenderer | typeof VerboseRenderer | typeof SilentRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/manager.d.ts(9,143): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/manager.d.ts(11,177): error TS2344: Type 'ListrGetRendererClassFromValue<InjectRenderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer | (InjectRenderer extends "verbose" ? typeof VerboseRenderer : InjectRenderer extends "silent" ? typeof SilentRenderer : InjectRenderer extends ListrRendererFactory ? InjectRenderer : never)' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'ListrRendererFactory | typeof DefaultRenderer | typeof VerboseRenderer | typeof SilentRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: Type 'typeof DefaultRenderer' is not assignable to type 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/manager.d.ts(12,57): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/manager.d.ts(12,146): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/manager.d.ts(12,304): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/manager.d.ts(12,378): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
@typerpc/cli: ../../node_modules/listr2/dist/manager.d.ts(13,54): error TS2344: Type 'ListrGetRendererClassFromValue<Renderer>' does not satisfy the constraint 'ListrRendererFactory'.
For example,
async function main (): Promise<void> {
await new Listr([
{
task: (ctx, task) => { // line #4
return (
execa.command(`xyz -y`)
.then(()=> // do something)
.catch((err: any) => {
// e.g. the user doesn't have `xyz` installed or accessible
if (err.code === 'ENOENT') {
npm install xyz // <---- address specific error
task.retry(1) // <---- rerun the current task, e.g. the
// task starting on line 4 of this
// example;
// to avoid infinite loops, pass a
// maximum number of retries, e.g. `1`;
// should probably default to `1`
}
}))
}
], {}
).run()
}
Hi,
First of all, thanks for maintaining this project π !
As part of one of my tasks, I'd like to execute npm init svelte@next -y
. The challenge I run into is that the npm init
script is interactive and displays a number of prompts.
My task currently looks like this:
const initWebApp = (ctx: Ctx, task: WebstoneTask) => {
ctx.webAppDir = `${ctx.appDir}/services/web`;
fs.removeSync(`${ctx.webAppDir}/.keep`);
const svelteSubprocess = execa("npm init -y svelte@next", {
cwd: ctx.webAppDir,
shell: true,
stdio: "inherit",
});
// svelteSubprocess.stdout.pipe(task.stdout())
return svelteSubprocess;
};
If I comment out the line above the return
statement, the task fails with TypeError: Cannot read property pipe of null
, which makes sense. The subprocess then executes, but any tasks defined afterwards fail, which also makes sense.
Is it possible to capture a user's input to that subprocess and once the subprocess completed, continue with the next task in my list?
According to the docs:
// it will collect all the errors encountered if { exitOnError: false } is set as an option
// elsewise it will throw the first error encountered as expected
In practice:
new Listr(
[
{
title: 'fail',
task: () => {
throw new Error('fail');
},
},
],
{ exitOnError: false }
)
.run()
.catch((e) => console.error('in catch', e))
If exitOnError: false
is set, the catch
is never triggered.
The new version 1.3.5
throws the following error on running:
'string' and 'indent' should be strings
/abc/node_modules/indent-string/index.js:6 throw new TypeError('`string` and `indent` should be strings'); ^TypeError:
string
andindent
should be strings
at Object.module.exports [as default] (/abc/node_modules/indent-string/index.js:6:9)
at MultiLineRenderer.formatString (/abc/node_modules/listr2/dist/renderer/default.renderer.js:125:42)
at MultiLineRenderer.multiLineRenderer (/abc/node_modules/listr2/dist/renderer/default.renderer.js:51:38)
at MultiLineRenderer.multiLineRenderer (/abc/node_modules/listr2/dist/renderer/default.renderer.js:81:48)
at Timeout._onTimeout (/abc/node_modules/listr2/dist/renderer/default.renderer.js:25:39)
at listOnTimeout (internal/timers.js:536:17)
at processTimers (internal/timers.js:480:7)
It was reported in lint-staged/lint-staged#870 that using Node.js version 13.6.0 listr2 fails to a nanoid import. The issue affects lint-staged because of the semver range allowing [email protected]
to be installed. I assume this error is similar to #25
In Listr, rejected promises and thrown errors are displayed in the list, but they remain uncaught. Listr2 appears to have fixed the issue by handling errors; however, tasks that return a rejected promise are removed from the task list, and thrown errors overwrite the task title.
This example on Repl.it demonstrates the described behavior.
Having task titles overwritten by default is a poor design choice from a UX perspective, be it from errors or skipping.
overwriteTitles
key to rendererOptions
, that controls this behavior.'Custom Renderers' documentations says that user have to do following:
import { ListrRenderer, ListrTaskObject } from 'listr2
but actual result is:
> require('listr2')
{ Listr: [Function: Listr],
Manager: [Function: Manager],
ListrError: [Function: ListrError],
PromptError: [Function: PromptError],
Logger: [Function: Logger],
logLevels:
{ silent: 'silent',
fail: 'fail',
skip: 'skip',
success: 'success',
data: 'data',
start: 'start',
title: 'title' },
newPrompt: [Function: newPrompt],
createPrompt: [Function: createPrompt] }
Can you fix it, please? It will allow users to create custom loggers and etc.
alpha
branch failed. π¨I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.
You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. Iβm sure you can resolve this πͺ.
Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.
Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the alpha
branch. You can also manually restart the failed CI job that runs semantic-release.
If you are not sure how to resolve this, here is some links that can help you:
If those donβt help, or if this issue is reporting something you think isnβt right, you can always ask the humans behind semantic-release.
The npm token configured in the NPM_TOKEN
environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/
.
If you are using Two-Factor Authentication, make configure the auth-only
level is supported. semantic-release cannot publish with the default auth-and-writes
level.
Please make sure to set the NPM_TOKEN
environment variable in your CI with the exact value of the npm token.
Good luck with your project β¨
Your semantic-release bot π¦π
Hi, we notice the rxjs
upgrade in version 3.8.3
, this could leading to some reference error if other modules import rxjs@6
. A breaking change is recommended if you guys need to upgrade rxjs
to 7.
Run types are not proper.
I have the following sample code:
const setupTasks = new Listr({
title: 'Root Task',
task: (ctx, task): Listr =>
task.newListr(
[
{
options: { persistentOutput: true },
title: 'Sub task 1',
task: async (subCtx, subTask): Promise<void> => {
await delay(3000);
subTask.output = 'Output for sub task 1';
return Promise.resolve();
}
},
{
options: { persistentOutput: true },
title: 'Sub task 2',
task: async (subCtx, subTask): Promise<void> => {
await delay(2000);
subTask.output = 'Error message for sub task 2';
return Promise.reject();
}
},
{
options: { persistentOutput: true },
title: 'Sub task 3',
task: async (subCtx, subTask): Promise<void> => {
await delay(1000);
subTask.output = 'Error message for sub task 3';
return Promise.reject();
}
}
],
{ concurrent: true, exitOnError: false, rendererOptions: { collapse: false, collapseErrors: false } }
)
});
try {
await setupTasks.run();
} catch (error) {
console.log(error);
}
When I run this sample, I see that Listr prints the output twice as tasks progress:
Is there a way to work around this issue to have the result printed only once?
If a subtask throws an error in concurrent mode the renderer stops animating the rest of the subtasks. No error is printed and listr2 fails silently. Not sure if I have to use manager.indent
for this to work.
const manager = new Manager();
manager.add({
title: 'Do stuff',
task: async () => {
return new Listr([
{ title: 'Task 1', task: async () => { throw new Error('FAIL') } },
{ title: 'Task 2', task: async () => { await delay(1000); return true; } }
], { concurrent: true })
}
});
manager.runAll().catch(() => null);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.