Navigation Menu

Skip to content
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

Merged
merged 1 commit into from Nov 18, 2019
Merged

Conversation

ericsciple
Copy link
Contributor

fixes #218

@ericsciple ericsciple changed the title toolrunner should which tool before invoking toolrunner should which tool Nov 15, 2019
@@ -392,6 +393,8 @@ export class ToolRunner extends events.EventEmitter {
* @returns number
*/
async exec(): Promise<number> {
this.toolPath = await io.which(this.toolPath, true)
Copy link
Member

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?

Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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

Copy link
Member

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).

Copy link
Member

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

packages/exec/README.md Outdated Show resolved Hide resolved
name: Build

strategy:
matrix:
Copy link
Contributor Author

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\""
Copy link
Contributor Author

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']);
Copy link
Contributor Author

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 () => {
Copy link
Contributor Author

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 () => {
Copy link
Contributor Author

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 () => {
Copy link
Contributor Author

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
Copy link
Contributor Author

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
Copy link
Contributor Author

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

Copy link
Contributor Author

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}]}\""
Copy link
Contributor Author

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": {
Copy link
Contributor Author

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
Copy link
Collaborator

@thboop thboop Nov 18, 2019

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(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is super clean 🥇

Copy link
Collaborator

@thboop thboop left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean lgtm

@thboop
Copy link
Collaborator

thboop commented Nov 18, 2019

We have existing tests for exec.exec ("full path to executable"), these tests should cover the rest of the cases and fix this bug

@ericsciple ericsciple merged commit 5c89429 into master Nov 18, 2019
@ericsciple ericsciple deleted the users/ericsciple/m161whichcmd branch November 18, 2019 21:20
@@ -1,6 +1,6 @@
{
"name": "@actions/tool-cache",
"version": "1.1.1",
"version": "1.1.2",
Copy link

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:

const powershellPath: string = await io.which('powershell', true)

const tarPath: string = await io.which('tar', true)

const powershellPath = await io.which('powershell')

const unzipPath = await io.which('unzip')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

exec doesn't resolve Windows .cmd/.bat files from the PATH
5 participants