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

Treat bare dollar sign as literal and dont interpolate #16

Merged
merged 4 commits into from
Dec 16, 2024

Conversation

jordandcarter
Copy link
Contributor

@jordandcarter jordandcarter commented Dec 16, 2024

  1. Treat bare $ as literal and don't raise an error trying and failing to interpolate it
  2. Treat identifiers ($<IDENTIFIER>) not starting with a letter or brace as literal and don't raise error.

Copy link
Contributor

@moskyb moskyb left a comment

Choose a reason for hiding this comment

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

looks good! one note, but feel free to merge without

parser.go Outdated
Comment on lines 102 to 106
if strings.HasPrefix(p.input[p.pos:], `$ `) {
p.pos += 2
expr = append(expr, ExpressionItem{Text: `$ `})
continue
}
Copy link
Contributor

Choose a reason for hiding this comment

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

we might wanna check for common non-space whitespace too, the \ns and \rs of the world

parser.go Outdated
Comment on lines 101 to 106
// Ignore empty variable references
if strings.HasPrefix(p.input[p.pos:], `$ `) {
p.pos += 2
expr = append(expr, ExpressionItem{Text: `$ `})
continue
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a bandaid fix for a specific case - arguably we should be treating a $ as a literal if there is no next character, or the next character is anything we don't parse as an expansion later on. Something like:

// If we run into a dollar sign, what we do with it depends on what comes next
if c == '$' {
	if p.pos == len(p.input)-1 {
		// It can't be an expansion.
		p.pos++
		expr = append(expr, ExpressionItem{Text: "$"})
		continue
	}

	if c2 := p.peekRune(); c2 == '{' || unicode.IsLetter(c2) {
		// It's ${ or $something ... probably an expansion!
		expansion, err := p.parseExpansion()
		if err != nil {
			return nil, err
		}
		expr = append(expr, ExpressionItem{Expansion: expansion})
		continue
	}
}

Note, though, that this only doesn't work because peekRune can't peek the rune after the current position...

@jordandcarter jordandcarter force-pushed the ps-215-treat-bare-dollar-sign-as-literal branch from 8cca45e to 4c53760 Compare December 16, 2024 04:13
@jordandcarter
Copy link
Contributor Author

What about this approach?

@jordandcarter jordandcarter force-pushed the ps-215-treat-bare-dollar-sign-as-literal branch from 4c53760 to 28db7ac Compare December 16, 2024 04:17
Copy link
Contributor

@DrJosh9000 DrJosh9000 left a comment

Choose a reason for hiding this comment

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

I like the approach 😄 some minor niggles about the implementation

parser.go Outdated
}

// if not a letter, it's a literal dollar sign
if !unicode.IsLetter(c) && !unicode.IsNumber(c) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think strings starting with numbers aren't considered to be identifiers (scanIdentifier only checks unicode.IsLetter)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I only added IsNumber to avoid this test. Should we raise an error for a number, or just treat as literal? My naive opinion is to treat as literal and not raise.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree, for our purposes (pipeline interpolation) it's a literal - similar to $(...).

parser.go Outdated
Comment on lines 169 to 170
err = fmt.Errorf("Expected expansion to start with $, got %c", c)
return
Copy link
Contributor

Choose a reason for hiding this comment

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

This function is just about too long for naked returns, IMO.

Suggested change
err = fmt.Errorf("Expected expansion to start with $, got %c", c)
return
return nil, false, fmt.Errorf("Expected expansion to start with $, got %c", c)

@jordandcarter
Copy link
Contributor Author

While you were reviewing just now @DrJosh9000 I tried another approach which just returns ExpressionItem instead https://github.com/buildkite/interpolate/compare/ps-215-treat-bare-dollar-sign-as-literal-alternative?expand=1

@DrJosh9000
Copy link
Contributor

https://github.com/buildkite/interpolate/compare/ps-215-treat-bare-dollar-sign-as-literal-alternative?expand=1

That one looks good! I think my comment about identifiers not starting with numbers still applies, but otherwise ✅

Copy link
Contributor

@DrJosh9000 DrJosh9000 left a comment

Choose a reason for hiding this comment

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

LGTM ✅

@jordandcarter jordandcarter merged commit 74a2a5f into main Dec 16, 2024
1 check passed
@jordandcarter jordandcarter deleted the ps-215-treat-bare-dollar-sign-as-literal branch December 16, 2024 21:33
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.

3 participants