Skip to content

SmartJoin incorrectly treats relative paths containing special variable names as special paths - #3022

Open
znnnnnnn-wil wants to merge 3 commits into
go-task:mainfrom
znnnnnnn-wil:fix/3021-literal-special-dir-paths
Open

SmartJoin incorrectly treats relative paths containing special variable names as special paths#3022
znnnnnnn-wil wants to merge 3 commits into
go-task:mainfrom
znnnnnnn-wil:fix/3021-literal-special-dir-paths

Conversation

@znnnnnnn-wil

@znnnnnnn-wil znnnnnnn-wil commented Sep 7, 2026

Copy link
Copy Markdown

Fixes #3021

Description

SmartJoin incorrectly treats ordinary relative paths containing special variable names such as .ROOT_DIR as absolute/special paths, causing them to bypass the base-directory join.

The path should be treated as a normal relative path and joined with base.

From looking at the implementation, this may be caused by isSpecialDir using strings.Contains to detect special variables. As a result, an ordinary directory name containing one of these strings can be matched even when the variable is not actually part of a {{ ... }} template expression.

A small portion of the code and tests was generated with assistance from Codex.

Linux amd64 / Go 1.26.5
go test ./...                                      PASS

golangci-lint 2.13.0
fmt --diff (3 changed files)                       PASS
run --new-from-rev=385e5ad --timeout 5m             0 issues
run --timeout 5m                                  3 pre-existing gci issues:
  errors/error_taskfile_decode.go
  errors/errors.go
  errors/errors_task.go

Checklist

  • I have read and followed the Contribution Guide.
  • I have disclosed the use of any AI-generated content in this pull request per the AI Usage Policy.
  • I fully understand the changes and have hand-written the description (No AI) of this pull request.

@trulede

trulede commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Um, AI wrote the code, correct?
The PR will get rejected in its current state.

@znnnnnnn-wil

Copy link
Copy Markdown
Author

Yes, Codex helped with part of the implementation and tests.

I worked through the issue and the scope of the fix myself, and went over the implementation a few times before opening the PR. I also changed some parts manually after reviewing the generated code.

I'm familiar with the behavior this is trying to preserve — in particular, project.ROOT_DIR/... should still be treated as a normal relative path, while something like {{.ROOT_DIR}}/... should keep the existing special-path behavior.

I ran the tests and lint locally and checked the regression cases before submitting.

Happy to explain any part of the change or adjust it based on feedback.

@trulede

trulede commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Why wouldn't you just do this?

var knownAbsDirs = []string{
	"{{.ROOT_DIR}}",
	"{{.TASKFILE_DIR}}",
	"{{.USER_WORKING_DIR}}",
}

@znnnnnnn-wil

Copy link
Copy Markdown
Author

Yeah, I considered that option too. My main concern was that matching only the exact strings might stop some template forms that currently work, for example {{ .TASKFILE_DIR }}, {{- .USER_WORKING_DIR -}}, or {{.ROOT_DIR | toSlash}}.

That's why I went with matching inside template actions instead. It avoids treating literal paths like project.ROOT_DIR/... as special, while still keeping those existing template variants working.

That said, if only the canonical {{.ROOT_DIR}}, {{.TASKFILE_DIR}}, and {{.USER_WORKING_DIR}} forms are actually meant to be supported here, then yeah, I agree the simpler approach makes more sense. I'm happy to change it.

@trulede

trulede commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Yes, I wondered the same thing, would it matter?

Lets assume it would cause problems, then my approach would be to use a regular expression for each item in knownAbsDirs (rather than the string), and precompile those (so package level vars, precompile for performance) and finally apply the regex list in a tight loop (similar to existing code). It would be easier to understand.

Or a single regex that considers all 3 possibilities. Probably faster again.

@znnnnnnn-wil

Copy link
Copy Markdown
Author

Yeah, that makes sense. A precompiled regex should make this a bit clearer without losing the template variants I was worried about.

I'll update isSpecialDir to use a package-level regex (or a small set of them) and keep the tests covering both literal path names and the existing template forms.

Thanks for the suggestion!

@trulede

trulede commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

@znnnnnnn-wil Looks quite good. You will need to request a review from one of the maintainers (I would suggest @vmaerten).

@znnnnnnn-wil

Copy link
Copy Markdown
Author

@vmaerten, when you have a chance, could you take a look at this PR? trulede suggested requesting your review. Thanks!

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.

SmartJoin incorrectly treats relative paths containing special variable names as special paths

2 participants