Skip to content

Conversation

lihaoyi
Copy link
Member

@lihaoyi lihaoyi commented Feb 5, 2025

This PR allows

val p: os.Path = "/hello/world"
val s: os.SubPath = "hello/world"
val r: os.RelPath = "../hello/world"

This only allows string-literals that are valid absolute/sub/relative-path respectively; passing in invalid paths (e.g. val p: os.Path = "hello/world") or non-literals (e.g. val str = "/hello/world"; val s: os.SubPath = str ) is a compile error

This builds upon @pawelsadlo's work in #297, mostly using segmentsFromStringLiteralValidation unchanged with some light pre/post processing to trim the leading / off of absolute os.Paths and check for leading ..s on os.SubPaths

I'm going to declare bankruptcy on the Expecty issues, as we cannot forever be working around bugs in unrelated libraries. If someone has problems and wants to fix expecty, they can do so, and we don't need to care. If nobody cares enough to fix expecty, we shouldn't care either.

@lihaoyi lihaoyi merged commit 944e33f into main Feb 5, 2025
8 checks passed
@lihaoyi lihaoyi deleted the literal-paths branch February 5, 2025 15:15
lihaoyi added a commit to com-lihaoyi/mill that referenced this pull request Feb 6, 2025
…bpath string literals (#4486)

First step in #4447, by
providing an alternative to the previous `os.Path` APIs.

Effectively this allows us to replace

```scala
def mainScript = Task.Source { millSourcePath / "src/foo.py" }
```

with

```scala
def mainScript = Task.Source { "src/foo.py" }
```

Pulls in com-lihaoyi/os-lib#353 from upstream to
make constructing `os.SubPath`s more ergonomic by eliding the lead
`os.sub /` prefix in the case of literal strings while still maintaining
a degree of safety:

* "outer" paths starting with `..`s and absolute paths starting with `/`
are rejected at compile time
* Only literal strings are converted implicitly, anything non-literal
needs to be an explicit `os.SubPath`


For now we provide this as an alternative to passing in an absolute
`os.Path`, but probably 99% of scenarios should be using this sub-path
API rather than absolute paths since (a) it's more concise and (b) your
sources should be within your `millSourcePath` anyway. I'm not sure we
can get rid of the `os.Path`-taking API entirely, but we can definitely
de-prioritize it and call it `SourcesUnsafe` or something so that anyone
who needs it can use it but most people won't use it accidentally
lihaoyi added a commit to com-lihaoyi/mill that referenced this pull request Feb 6, 2025
…tly from subpath string literals (#4487)

First step in #4447, by
providing an alternative to the previous `os.Path` APIs.

Effectively this allows us to replace

```scala
def mainScript = Task.Source { millSourcePath / "src/foo.py" }
```

with

```scala
def mainScript = Task.Source { "src/foo.py" }
```

Pulls in com-lihaoyi/os-lib#353 from upstream to
make constructing `os.SubPath`s more ergonomic by eliding the lead
`os.sub /` prefix in the case of literal strings while still maintaining
a degree of safety:

* "outer" paths starting with `..`s and absolute paths starting with `/`
are rejected at compile time
* Only literal strings are converted implicitly, anything non-literal
needs to be an explicit `os.SubPath`


For now we provide this as an alternative to passing in an absolute
`os.Path`, but probably 99% of scenarios should be using this sub-path
API rather than absolute paths since (a) it's more concise and (b) your
sources should be within your `millSourcePath` anyway. I'm not sure we
can get rid of the `os.Path`-taking API entirely, but we can definitely
de-prioritize it and call it `SourcesUnsafe` or something so that anyone
who needs it can use it but most people won't use it accidentally
@lefou lefou added this to the 0.11.4 milestone Mar 4, 2025
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.

2 participants