diff --git a/.gitignore b/.gitignore index dbe16ed..03661b3 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ node_modules .vscode-test/ *.vsix .task +test-workspace/.vscode diff --git a/CHANGELOG.md b/CHANGELOG.md index ba1709e..0a915d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,17 +3,28 @@ ## Unreleased - Improve error handling in when Taskfiles contain errors (#25 by @pd93). -- Added a new command: `Task: Show Debug Panel` to show the Task debug panel (#25 by @pd93). +- Added a new command: `Task: Show Debug Panel` to show the Task debug panel + (#25 by @pd93). - Added the ability to sort tasks in the tree view (#20 by @pd93). - - Configurable via `task.tree.sort` setting (values: `"default"` (default), `"alphanumeric"` or `"none"`). -- Added a cancel/timeout to file watcher to improve performance when making lots of file changes (#35 by @pd93). - - For example, `git stash pop` of a lot of `.yml` files would cause a huge lag spike as multiple update calls were made. -- This extension is now also published on the [Open VSX Registry](https://open-vsx.org/extension/task/vscode-task) (#26, #46 by @pd93). + - Configurable via `task.tree.sort` setting (values: `"default"` (default), + `"alphanumeric"` or `"none"`). +- Added a cancel/timeout to file watcher to improve performance when making lots + of file changes (#35 by @pd93). + - For example, `git stash pop` of a lot of `.yml` files would cause a huge lag + spike as multiple update calls were made. +- Allow commands to be run from last active terminal instead of the output panel + (#12, #43 by @pd93). + - Configurable via `task.outputTo` setting (values: `output` (default) or + `terminal`). +- This extension is now also published on the + [Open VSX Registry](https://open-vsx.org/extension/task/vscode-task) (#26, #46 + by @pd93). - This means you can now install it in [VSCodeium](https://vscodium.com/). ## v0.1.1 - 2021-03-27 -- Fixed some installations (e.g. Brew) not detecting the Task version correctly (#13, #14 by @pd93). +- Fixed some installations (e.g. Brew) not detecting the Task version correctly + (#13, #14 by @pd93). ## v0.1.0 - 2023-03-26 @@ -26,12 +37,15 @@ - Ability to initialize a Taskfile in the current workspace. - If no Taskfile is detected a button will appear in the sidebar. - Refresh on save. - - Configurable via `task.updateOn` setting (values: `"save"` (default) or `"manual"`). + - Configurable via `task.updateOn` setting (values: `"save"` (default) or + `"manual"`). - Toggle tree nesting on/off - - Configurable via `task.tree.nesting` setting (values: `true` (default) or `false`). + - Configurable via `task.tree.nesting` setting (values: `true` (default) or + `false`). - Change the path to the Task binary. - Can also be set to the name of a binary in your `$PATH`. - Configurable via `task.path` setting (defaults to `"task"`). - Version checks on startup. - - Configurable via `task.checkForUpdates` setting (values: `true` (default) or `false`). + - Configurable via `task.checkForUpdates` setting (values: `true` (default) or + `false`). - Sidebar icon provided by @drite93. diff --git a/README.md b/README.md index e9a467e..fa1b710 100644 --- a/README.md +++ b/README.md @@ -37,10 +37,11 @@ ## Configuration -| Setting | Type | Allowed Values | Default | Description | -| ----------------- | --------- | --------------------------------- | ----------- | ----------------------------------------------------------------------- | -| `updateOn` | `string` | `"manual"`, `"save"` | `"save"` | When the list of tasks should be updated. | -| `path` | `string` | | `"task"` | Path to the Task binary. Can also the name of a binary in your `$PATH`. | -| `checkForUpdates` | `boolean` | | `true` | Check if there is a newer version of Task on startup. | -| `tree.nesting` | `boolean` | | `true` | Whether to nest tasks by their namespace in the tree view. | -| `tree.sort` | `sort` | `default`, `alphanumeric`, `none` | `"default"` | The order in which to display tasks in the tree view. | +| Setting | Type | Allowed Values | Default | Description | +| ----------------- | --------- | --------------------------------- | ----------- | -------------------------------------------------------------------------------------------- | +| `updateOn` | `string` | `"manual"`, `"save"` | `"save"` | When the list of tasks should be updated. | +| `path` | `string` | | `"task"` | Path to the Task binary. Can also the name of a binary in your `$PATH`. | +| `outputTo` | `string` | `"output"`, `"terminal"` | `"output"` | Where to print the output of tasks. Note that the output panel does not support ANSI colors. | +| `checkForUpdates` | `boolean` | | `true` | Check if there is a newer version of Task on startup. | +| `tree.nesting` | `boolean` | | `true` | Whether to nest tasks by their namespace in the tree view. | +| `tree.sort` | `sort` | `default`, `alphanumeric`, `none` | `"default"` | The order in which to display tasks in the tree view. | diff --git a/package.json b/package.json index 2200c4e..7f1bacb 100644 --- a/package.json +++ b/package.json @@ -258,6 +258,15 @@ "default": "task", "description": "Path to the Task binary. Can also the name of a binary in your `$PATH`." }, + "outputTo": { + "type": "string", + "enum": [ + "output", + "terminal" + ], + "default": "output", + "description": "Where to print the output of tasks. Note that the output panel does not support ANSI colors." + }, "checkForUpdates": { "type": "boolean", "default": true, @@ -305,6 +314,7 @@ "@types/glob": "^8.1.0", "@types/mocha": "^10.0.1", "@types/node": "18.x", + "@types/strip-ansi": "3.0.0", "@types/vscode": "^1.76.0", "@typescript-eslint/eslint-plugin": "^5.59.1", "@typescript-eslint/parser": "^5.59.0", @@ -320,6 +330,7 @@ "dependencies": { "@octokit/types": "^9.0.0", "octokit": "^2.0.14", - "semver": "^7.3.8" + "semver": "^7.3.8", + "strip-ansi": "6.0.1" } } diff --git a/src/services/taskfile.ts b/src/services/taskfile.ts index 68ce753..2c6a1bc 100644 --- a/src/services/taskfile.ts +++ b/src/services/taskfile.ts @@ -7,6 +7,7 @@ import * as semver from 'semver'; import { log, settings } from '../utils'; import { Octokit } from 'octokit'; import { Endpoints } from "@octokit/types"; +import stripAnsi = require('strip-ansi'); const octokit = new Octokit(); type ReleaseRequest = Endpoints["GET /repos/{owner}/{repo}/releases/latest"]["parameters"]; @@ -225,37 +226,49 @@ class TaskfileService { } public async runTask(taskName: string, dir?: string): Promise { - return await new Promise((resolve) => { + if (settings.outputTo === "terminal") { log.info(`Running task: "${taskName}" in: "${dir}"`); + var terminal: vscode.Terminal; + if (vscode.window.activeTerminal !== undefined) { + terminal = vscode.window.activeTerminal; + } else { + terminal = vscode.window.createTerminal("Task"); + } + terminal.show(); + terminal.sendText(this.command(taskName)); + } else { + return await new Promise((resolve) => { + log.info(`Running task: "${taskName}" in: "${dir}"`); + + // Spawn a child process + let child = cp.spawn(this.command(), [taskName], { cwd: dir }); + + // Open the output + TaskfileService.outputChannel.clear(); + TaskfileService.outputChannel.show(); + + // Listen for stderr + child.stderr.setEncoding('utf8'); + child.stderr.on("data", data => { + TaskfileService.outputChannel.append(stripAnsi(data.toString())); + }); - // Spawn a child process - let child = cp.spawn(this.command(), [taskName], { cwd: dir }); - - // Clear the output channel and show it - TaskfileService.outputChannel.clear(); - TaskfileService.outputChannel.show(); - - // Listen for stderr - child.stderr.setEncoding('utf8'); - child.stderr.on("data", data => { - TaskfileService.outputChannel.append(data.toString()); - }); - - // Listen for stdout - child.stdout.setEncoding('utf8'); - child.stdout.on("data", data => { - TaskfileService.outputChannel.append(data.toString()); - }); + // Listen for stdout + child.stdout.setEncoding('utf8'); + child.stdout.on("data", data => { + TaskfileService.outputChannel.append(stripAnsi(data.toString())); + }); - // When the task finishes, print the exit code and resolve the promise - child.on('close', code => { - log.info(`Task completed with code ${code}`); - TaskfileService.outputChannel.append(`task: completed with code ${code}\n`); - this.lastTaskName = taskName; - this.lastTaskDir = dir; - return resolve(); + // When the task finishes, print the exit code and resolve the promise + child.on('close', code => { + log.info(`Task completed with code ${code}`); + TaskfileService.outputChannel.append(`task: completed with code ${code}\n`); + this.lastTaskName = taskName; + this.lastTaskDir = dir; + return resolve(); + }); }); - }); + } } public async goToDefinition(task: models.Task, preview: boolean = false): Promise { diff --git a/src/utils/settings.ts b/src/utils/settings.ts index 3c200b4..805fd6b 100644 --- a/src/utils/settings.ts +++ b/src/utils/settings.ts @@ -5,6 +5,7 @@ class Settings { private static _instance: Settings; public updateOn!: string; public path!: string; + public outputTo!: string; public checkForUpdates!: boolean; public treeNesting!: boolean; public treeSort!: string; @@ -27,6 +28,7 @@ class Settings { // Set the properties this.updateOn = config.get("updateOn") ?? "change"; this.path = config.get("path") ?? "task"; + this.outputTo = config.get("outputTo") ?? "output"; this.checkForUpdates = config.get("checkForUpdates") ?? true; this.treeNesting = config.get("tree.nesting") ?? true; this.treeSort = config.get("tree.sort") ?? "default"; diff --git a/test-workspace/Taskfile.yml b/test-workspace/Taskfile.yml index 853082a..2c0eb14 100644 --- a/test-workspace/Taskfile.yml +++ b/test-workspace/Taskfile.yml @@ -36,3 +36,10 @@ tasks: desc: Namespaced task that is defined in the root file cmds: - task: hello + + task-prints-color: + cmds: + - echo -e "Prints in {{.RED}}red{{.NC}}" + vars: + RED: \033[1;31m + NC: \033[0m diff --git a/yarn.lock b/yarn.lock index 5e3cc19..f3e2b28 100644 --- a/yarn.lock +++ b/yarn.lock @@ -469,6 +469,11 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.13.tgz#da4bfd73f49bd541d28920ab0e2bf0ee80f71c91" integrity sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw== +"@types/strip-ansi@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/strip-ansi/-/strip-ansi-3.0.0.tgz#9b63d453a6b54aa849182207711a08be8eea48ae" + integrity sha512-wVhzc+WJ/JNdV25MeaK0skxGdbdOFeqYv1sqY8yPXbsshZ0XwSbWWwfKzj836cPW+e+PpqUNvKoiac9ZqCdyRQ== + "@types/vscode@^1.76.0": version "1.76.0" resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.76.0.tgz#967c0fbe09921818bbf201f1cbcb81b981c6249c" @@ -2305,7 +2310,7 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==