-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
toolrunner should which tool #220
Conversation
708b724
to
99befb3
Compare
@@ -392,6 +393,8 @@ export class ToolRunner extends events.EventEmitter { | |||
* @returns number | |||
*/ | |||
async exec(): Promise<number> { | |||
this.toolPath = await io.which(this.toolPath, true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a breaking change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my intention was that it doesnt break anything
for example which
returns the path if it is already rooted and executable.
however, now that you got me thinking about it more, i think there are some edge cases wrt relative pathing.... i'll add code to handle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok i added the code above to root unrooted paths that contain relative pathing
in addition to checking the PATH, the which function also handles checking rooted paths
now the changes shouldnt be a breaking change. hard to imagine it would have practically broken anyone, but i'd rather cover edge cases to be on the safe side. Also now the changes align better with the default behavior of spawn
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'll add unit tests tomorrow for the unrooted-relative-pathing cases
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it's not a breaking change. It's additive. If you were passing in a fully qualified path, which will not changing anything. It will however add the ability to just pass in a tool name and it just works (as well as fixing some other issues and bugs).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bryanmacfarlane Originally it was breaking, exec of a relative path would no longer work if we automatically which
. That should be fixed now with @ericsciple's latest change
70e0eef
to
a5c2be2
Compare
name: Build | ||
|
||
strategy: | ||
matrix: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
leverage matrix instead of duplicate 3 times
@@ -9,8 +9,7 @@ | |||
"format-check": "prettier --check packages/**/*.ts", | |||
"lint": "eslint packages/**/*.ts", | |||
"new-package": "scripts/create-package", | |||
"test": "jest", | |||
"test-ci": "jest --testPathIgnorePatterns=\"<rootDir>/packages/exec/__tests__/exec.test.ts\"" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we dont need this command anymore, this was to skip the failing tests on windows
const pythonPath: string = await io.which('python', true) | ||
|
||
await exec.exec(`"${pythonPath}"`, ['main.py']); | ||
await exec.exec('"/path/to/my-tool"', ['arg1']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the previous example did the exact opposite of the description :(
@@ -121,6 +121,38 @@ describe('@actions/exec', () => { | |||
} | |||
}) | |||
|
|||
it('Runs exec successfully with command from PATH', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
coverage for existing functionality
@@ -418,6 +450,134 @@ describe('@actions/exec', () => { | |||
fs.unlinkSync(semaphorePath) | |||
}) | |||
|
|||
it('Exec roots relative tool path using unrooted options.cwd', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tests to make sure we're not breaking existing behavior
also this confirms that extensions are resolved on windows, which the previous code did not do (but should have done)
@@ -572,6 +732,42 @@ describe('@actions/exec', () => { | |||
) | |||
}) | |||
|
|||
it('execs .cmd from path (Windows)', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here is the test related to the bug fix.
toolrunner should which the tool before attempting to invoke. otherwise simple commands like npm --version
fail on windows (ENOENT) because npm
resolves to npm.cmd
and node doesnt find it.
let exitCode: number | ||
let command: string | ||
if (IS_WINDOWS) { | ||
command = './print-args-cmd' // let ToolRunner resolve the extension |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note, without extension, toolrunner should resolve the extension
@@ -0,0 +1,12 @@ | |||
@echo off |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the naming of these script files is a little bit weird, but it's related to the conventions set forth by the existing test case scripts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i just copied one of the existing cmd files (but it had spaces in the path, and i didnt want that)
this script basically just echoes the args, e.g.
arg[0]: "hello"
arg[1]: "world"
|
||
# echo each element | ||
for (( i=0;i<$ELEMENTS;i++)); do | ||
echo "args[$i]: \"${args[${i}]}\"" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same deal here, this script just echos the args
@@ -32,7 +32,7 @@ | |||
"bugs": { | |||
"url": "https://github.com/actions/toolkit/issues" | |||
}, | |||
"devDependencies": { | |||
"dependencies": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to call io.which
and also some other io helpers
let exitCode: number | ||
let command: string | ||
if (IS_WINDOWS) { | ||
command = './print-args-cmd' // let ToolRunner resolve the extension |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding a \
test for windows
(IS_WINDOWS && this.toolPath.includes('\\'))) | ||
) { | ||
// prefer options.cwd if it is specified, however options.cwd may also need to be rooted | ||
this.toolPath = path.resolve( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is super clean 🥇
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clean lgtm
We have existing tests for exec.exec ("full path to executable"), these tests should cover the rest of the cases and fix this bug |
@@ -1,6 +1,6 @@ | |||
{ | |||
"name": "@actions/tool-cache", | |||
"version": "1.1.1", | |||
"version": "1.1.2", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The version of tool-cache
was bumped, even though it seems that none of the files in packages/tool-cache
was changed. Is this expected?
Should it mean to reflect that tool-cache
is updated to use this new feature of exec
, I'd expect files such as packages/tool-cache/src/tool-cache.ts
to be modified:
toolkit/packages/tool-cache/src/tool-cache.ts
Line 175 in 5c89429
const powershellPath: string = await io.which('powershell', true) |
toolkit/packages/tool-cache/src/tool-cache.ts
Line 203 in 5c89429
const tarPath: string = await io.which('tar', true) |
toolkit/packages/tool-cache/src/tool-cache.ts
Line 239 in 5c89429
const powershellPath = await io.which('powershell') |
toolkit/packages/tool-cache/src/tool-cache.ts
Line 254 in 5c89429
const unzipPath = await io.which('unzip') |
fixes #218