Skip to content

Commit 136e062

Browse files
authored
fix: can ignore EEXISTS and exit with 0 (#23)
Signed-off-by: dankeboy36 <[email protected]>
1 parent ebab984 commit 136e062

File tree

7 files changed

+126
-75
lines changed

7 files changed

+126
-75
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Get Arduino Tools (`gat`) is a CLI that helps you easily download various Arduin
99
- [Arduino CLI](https://github.com/arduino/arduino-cli)
1010
- [Arduino Language Server](https://github.com/arduino/arduino-language-server)
1111
- [Arduino Firmware Uploader](https://github.com/arduino/arduino-fwuploader)
12+
- [Arduino Lint](https://github.com/arduino/arduino-lint)
1213
- [`clangd`](https://github.com/arduino/clang-static-binaries)
1314
- [`clang-format`](https://github.com/arduino/clang-static-binaries)
1415

@@ -32,7 +33,7 @@ gat get <tool> <version> [options]
3233

3334
#### Arguments
3435

35-
- `<tool>`: The tool you want to download. Can be one of: `arduino-cli`, `arduino-language-server`, `arduino-fwuploader`, `clangd`, `clang-format`.
36+
- `<tool>`: The tool you want to download. Can be one of: `arduino-cli`, `arduino-language-server`, `arduino-fwuploader`, `arduino-lint`, `clangd`, `clang-format`.
3637
- `<version>`: The version of the tool you want to download.
3738

3839
#### Options
@@ -41,6 +42,7 @@ gat get <tool> <version> [options]
4142
- `-p, --platform <platform>`: Platform (default: current platform).
4243
- `-a, --arch <arch>`: Architecture (default: current architecture).
4344
- `-f, --force`: Force download to overwrite existing files (default: false).
45+
- `--ok-if-exists`: If the tool already exists and is executable, skip download and exit with code 0.
4446
- `--verbose`: Enables verbose output (default: false).
4547
- `--silent`: Disables the progress bar (default: false).
4648

package-lock.json

Lines changed: 51 additions & 61 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cli.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ function parse(args) {
2727
.option('-p, --platform <platform>', 'Platform', process.platform)
2828
.option('-a, --arch <arch>', 'Architecture', process.arch)
2929
.option('-f, --force', 'Force download to overwrite existing files', false)
30+
.option(
31+
'--ok-if-exists',
32+
'If the tool already exists, skip download and exit with code 0',
33+
false
34+
)
3035
.option('--verbose', 'Enables the verbose output', false)
3136
.option('--silent', 'Disables the progress bar', false)
3237
.description('Get an Arduino tool')
@@ -69,8 +74,13 @@ function parse(args) {
6974
} catch (err) {
7075
log('Failed to download tool', err)
7176
console.log(err?.message || err)
72-
if (err.code === 'EEXIST' && options.force !== true) {
73-
return program.error('Use --force to overwrite existing files')
77+
if (err.code === 'EEXIST') {
78+
if (options.okIfExists) {
79+
log('Tool already exists and is executable, skipping download')
80+
return
81+
} else if (options.force !== true) {
82+
return program.error('Use --force to overwrite existing files')
83+
}
7484
}
7585
return program.error(err?.message || err)
7686
}

src/cli.slow-test.js

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,39 +23,50 @@ const clangToolExpectVersion = async (toolPath, expected) => {
2323
}
2424

2525
describe('cli', () => {
26-
/** @type {CliTestParams[]} */
27-
const params = [
28-
{
26+
/** @type {Record<import('./tools').Tool, CliTestParams>} */
27+
const params = {
28+
'arduino-cli': {
2929
tool: 'arduino-cli',
30-
version: '1.1.1',
30+
version: '1.2.2',
3131
expectVersion: arduinoToolExpectVersion,
3232
},
33-
{
33+
'arduino-fwuploader': {
3434
tool: 'arduino-fwuploader',
3535
version: '2.4.1',
3636
expectVersion: arduinoToolExpectVersion,
3737
},
38-
{
38+
'arduino-language-server': {
3939
tool: 'arduino-language-server',
40-
version: '0.7.6',
40+
version: '0.7.7',
4141
expectVersion: async (toolPath) => {
4242
// The Arduino LS requires the CLI and clangd. The assertion expects a failure.
4343
const stdout = await execFile(toolPath, ['version'], true)
4444
expect(stdout).toContain('Path to ArduinoCLI config file must be set')
4545
},
4646
},
47-
{
47+
clangd: {
4848
tool: 'clangd',
4949
version: '14.0.0',
5050
expectVersion: clangToolExpectVersion,
5151
},
52-
{
52+
'clang-format': {
5353
tool: 'clang-format',
5454
version: '14.0.0',
5555
expectVersion: clangToolExpectVersion,
5656
},
57-
]
58-
params.map(({ tool, version, expectVersion }) =>
57+
'arduino-lint': {
58+
tool: 'arduino-lint',
59+
version: '1.3.0',
60+
expectVersion: async (toolPath) => {
61+
// The Arduino Lint requires the CLI to be in a library folder, for example
62+
// _This will automatically detect the project type and check it against the relevant rules._
63+
// https://arduino.github.io/arduino-lint/latest/#getting-started
64+
const stdout = await execFile(toolPath, ['version'], true)
65+
expect(stdout).toContain('PROJECT_PATH argument version does not exist')
66+
},
67+
},
68+
}
69+
Object.values(params).map(({ tool, version, expectVersion }) =>
5970
it(`should get the ${tool}`, async () => {
6071
const { path: tempDirPath } = await tmp.dir({
6172
keep: false,

src/cli.test.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ describe('cli', () => {
5151
silent: false,
5252
verbose: false,
5353
onProgress: expect.any(Function),
54+
okIfExists: false,
5455
})
5556

5657
expect(exitSpy).not.toHaveBeenCalled()
@@ -216,4 +217,39 @@ describe('cli', () => {
216217
expect.objectContaining({ silent: true })
217218
)
218219
})
220+
221+
it('should ignore EEXIST if --ok-if-exists is set', async () => {
222+
jest
223+
.mocked(getTool)
224+
.mockRejectedValueOnce(
225+
Object.assign(new Error('my error'), { code: 'EEXIST' })
226+
)
227+
228+
parse([
229+
'node',
230+
'script.js',
231+
'get',
232+
'arduino-cli',
233+
'1.1.1',
234+
'--ok-if-exists',
235+
])
236+
237+
await waitFor(() => expect(mockLog).toHaveBeenCalledWith('my error'))
238+
239+
expect(exitSpy).not.toHaveBeenCalled()
240+
})
241+
242+
it('should rethrow EEXIST if --ok-if-exists is not but --force is set', async () => {
243+
jest
244+
.mocked(getTool)
245+
.mockRejectedValueOnce(
246+
Object.assign(new Error('my error'), { code: 'EEXIST' })
247+
)
248+
249+
parse(['node', 'script.js', 'get', 'arduino-cli', '1.1.1', '--force'])
250+
251+
await waitFor(() => expect(mockLog).toHaveBeenCalledWith('my error'))
252+
253+
expect(exitSpy).toHaveBeenCalledWith(1)
254+
})
219255
})

src/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const arduinoTools = [
22
'arduino-cli',
33
'arduino-language-server',
44
'arduino-fwuploader',
5+
'arduino-lint',
56
] as const
67
const clangTools = ['clangd', 'clang-format'] as const
78

0 commit comments

Comments
 (0)