Skip to content

Commit

Permalink
feat: Adding extra arguments to execution (#24)
Browse files Browse the repository at this point in the history
* feat: Adding extra arguments to execution

* Allow extra args from tasks.json

* Update README to include how to set Extra Arguments
  • Loading branch information
carlos-algms authored May 11, 2022
1 parent 6a8105e commit c11d208
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 75 deletions.
7 changes: 6 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@
"preLaunchTask": "Compile Test",
"env": {
"NODE_ENV": "test"
}
},
"skipFiles": [
"<node_internals>/**",
"internal/**",
"**/Visual Studio Code.app/**"
]
}
]
}
53 changes: 51 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Run `make` tasks and targets from VS Code command picker or via tasks menu.
- Tasks-View listing all available targets
- Multiple workspaces ready!
- **NEW**: Set the executable path to your `make` command
- **NEW**: Add extra arguments to the `make` execution command

### Running from the command picker:

Expand All @@ -22,10 +23,58 @@ Run `make` tasks and targets from VS Code command picker or via tasks menu.

![command picker](images/task-tree.gif)

### Adding extra arguments/flags to the `make` execution command

The setting `make-task-provider.extraArguments` can be set with an array of strings with extra arguments which will be added to the `make` command.

```json
"make-task-provider.extraArguments": [
"--always-make",
"--ignore-errors"
]
```

Extra arguments will be appended to the `make` command as follows:

```text
[make bin path] -f [makefile path] [...extra arguments] [target name]
```

For example, If the target `build` is triggered, it will be executed as:

```shell
$ make -f ./Makefile --always-make --ignore-errors build
```

It is also possible to customize flags to a single target by using VSCode task customization:

On your project's `tasks.json`, set the following:

```json
{
"version": "2.0.0",
"tasks": [
{
"type": "make",
"targetName": "build",
"makeFileRelativePath": "Makefile",
"problemMatcher": [],
"label": "make: build with extra args",
"args": [
"--always-make",
"--ignore-errors"
]
}
]
}
```

If `make-task-provider.extraArguments` is set along with `args` in the tasks.json,
**ALL** the extra arguments will be added to the `make` command.

---

**PS:** This extension is **NOT** a re-implementation of `make`,
so you need to have `make` executables available on your system.
**PS:** This extension is **NOT** a re-implementation of `make`, so you must have `make` executables available on your system.

If `make` is not on your `PATH`, you can customize the executable path individually based on your operating system:

Expand Down
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
"makeFileRelativePath": {
"type": "string",
"description": "Relative path to the Makefile containing your targets to be executed"
},
"args": {
"type": "array",
"description": "Arguments to pass to the make target as: make {...args} {target}"
}
}
}
Expand Down Expand Up @@ -164,6 +168,12 @@
"open"
],
"markdownDescription": "The action to trigger when clicking on a target on the targets list: `open` or `run`, the default is `run`."
},
"make-task-provider.extraArguments": {
"scope": "resource",
"type": "array",
"default": [],
"markdownDescription": "Additional flags to be added to the run command like: `make {...extraFlags} {target}`"
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/Tasks/MakefileTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export interface MakefileTaskDefinition extends vscode.TaskDefinition {
* The relative path to the Makefile containing the Target task
*/
makeFileRelativePath: string;

/**
* Extra arguments to be passed to the make command
*/
args?: string[];
}

export interface MakefileTask extends vscode.Task {
Expand Down
47 changes: 46 additions & 1 deletion src/Tasks/createMakefileTask.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import path from 'path';
import sinon from 'sinon';
import vscode from 'vscode';

import { TYPE } from '../shared/constants';
Expand Down Expand Up @@ -35,7 +36,7 @@ describe('Create Makefile tasks', () => {
},
'task.definition',
);
expect(task.scope).to.equal(workspace, 'task.source');
expect(task.scope).to.equal(workspace, 'task.scope');

// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const { execution }: { execution: vscode.ShellExecution } = <any>task;
Expand All @@ -54,4 +55,48 @@ describe('Create Makefile tasks', () => {
const task = createMakefileTask(fakeDefinition, workspace, makefileUri);
expect(task.definition).to.equal(fakeDefinition);
});

it('should pass extra arguments when defined on settings', () => {
const extraArgsMock = ['--extra-arg', '-B'];
const getConfigurationMocked = sinon.stub(vscode.workspace, 'getConfiguration');

getConfigurationMocked.onFirstCall().callThrough();
getConfigurationMocked.onSecondCall().returns({
get: () => extraArgsMock,
} as any);
getConfigurationMocked.callThrough();

const name = 'test_with_args';
const task = createMakefileTask(name, workspace, makefileUri);

// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const { execution }: { execution: vscode.ShellExecution } = <any>task;
expect(execution.command).to.equal('make');
expect(execution.args).to.deep.equal(['-f', 'Makefile', ...extraArgsMock, name]);
});

it('should merge extra arguments from settings and tasks.json', () => {
const extraArgsMock = ['--extra-unique', '-B'];
const getConfigurationMocked = sinon.stub(vscode.workspace, 'getConfiguration');

getConfigurationMocked.onFirstCall().callThrough();
getConfigurationMocked.onSecondCall().returns({
get: () => extraArgsMock,
} as any);
getConfigurationMocked.callThrough();

const name = 'test_with_args_merged';
const fakeDefinition = {
type: TYPE,
targetName: name,
makeFileRelativePath: 'Makefile',
args: ['--extra-arg', '-B'],
};

const task = createMakefileTask(fakeDefinition, workspace, makefileUri);
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const { execution }: { execution: vscode.ShellExecution } = <any>task;

expect(execution.args).to.deep.equal(['-f', 'Makefile', ...extraArgsMock, '--extra-arg', name]);
});
});
8 changes: 5 additions & 3 deletions src/Tasks/createMakefileTask.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'path';
import vscode from 'vscode';

import { getMakeExecutablePath } from '../shared/config';
import { getExtraArguments, getMakeExecutablePath } from '../shared/config';
import { TYPE } from '../shared/constants';
import { getFileRelativePath } from '../shared/workspaceFiles';

Expand Down Expand Up @@ -40,22 +40,24 @@ export function createMakefileTask(
makefileUri: vscode.Uri,
): MakefileTask {
const definition = getDefinition(nameOrDefinition, makefileUri.fsPath, folder.uri.fsPath);
const { targetName, makeFileRelativePath } = definition;
const { targetName, makeFileRelativePath, args = [] } = definition;

const cwd = path.dirname(makefileUri.fsPath);
const makefile = path.basename(makeFileRelativePath);

const options: vscode.ShellExecutionOptions = { cwd };
// TODO: check performance degradation here
const makeBin = getMakeExecutablePath(folder);
const extraArguments = getExtraArguments(folder);
const uniqueArgs = Array.from(new Set([...extraArguments, ...args]));

const task = <MakefileTask>(
new vscode.Task(
definition,
folder,
targetName,
TYPE,
new vscode.ShellExecution(makeBin, ['-f', makefile, targetName], options),
new vscode.ShellExecution(makeBin, ['-f', makefile, ...uniqueArgs, targetName], options),
[],
)
);
Expand Down
1 change: 1 addition & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export function activate(context: vscode.ExtensionContext): void {
vscode.workspace.onDidChangeConfiguration((e) => {
const shouldRefresh =
e.affectsConfiguration(CONFIG_KEYS.autoDetect) ||
e.affectsConfiguration(CONFIG_KEYS.extraArguments) ||
e.affectsConfiguration(CONFIG_KEYS.makeExecutable);

if (shouldRefresh) {
Expand Down
5 changes: 5 additions & 0 deletions src/shared/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const CONFIG_KEYS = {
makefileNames: `${APP_NAME}.makefileNames`,
makeExecutable: `${APP_NAME}.${getUserPlatformKey() ?? 'unix.makeExecutable'}`,
telemetry: `${APP_NAME}.telemetry`,
extraArguments: `${APP_NAME}.extraArguments`,
};

export const COMMANDS = {
Expand Down Expand Up @@ -99,3 +100,7 @@ export function getUserPlatformKey(): string | null {
export function getTargetsExplorerClickAction(scope?: vscode.ConfigurationScope): 'run' | 'open' {
return getFolderConfig(scope).get<'run' | 'open'>('targetsExplorerClickAction', 'run');
}

export function getExtraArguments(scope?: vscode.ConfigurationScope): string[] {
return getFolderConfig(scope).get<string[]>('extraArguments', []);
}
38 changes: 0 additions & 38 deletions src/shared/exec.ts

This file was deleted.

30 changes: 0 additions & 30 deletions src/shared/exists.ts

This file was deleted.

0 comments on commit c11d208

Please sign in to comment.