Skip to content

Inconsistent relative path behavior between config include and other fields #15769

@loynoir

Description

@loynoir

Problem

reproduce

$ tree -a /tmp/example
/tmp/example
├── bar
│   ├── .cargo
│   │   └── config.toml
│   ├── Cargo.toml
│   └── src
│       └── lib.rs
├── foo
│   ├── .cargo
│   │   └── config.toml
│   ├── Cargo.toml
│   └── src
│       └── lib.rs
└── rust-toolchain.toml

7 directories, 7 files

actual

When write isomorphic relative path string, compile fail

/tmp/example/bar/.cargo/config.toml

include = ["../foo/.cargo/config.toml"]

[build]
target-dir = "../foo/target"
$ cargo -Zconfig-include build
error: could not load Cargo configuration

Caused by:
  failed to load config include `../foo/.cargo/config.toml` from `/tmp/reproduce/bar/.cargo/config.toml`

Caused by:
  failed to read configuration file `/tmp/reproduce/bar/.cargo/../foo/.cargo/config.toml`

Caused by:
  No such file or directory (os error 2)

When not write isomorphic relative path string, compile OK

/tmp/example/bar/.cargo/config.toml

include = ["../../foo/.cargo/config.toml"]

[build]
target-dir = "../foo/target"
$ cargo -Zconfig-include build
cargo -Zconfig-include build
   Compiling bar v0.1.0 (/tmp/example/bar)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.06s

conclusion pseduo code

There are three types of relative path.

And already two types in used.

struct ConfigDirRelativePath<T>(T);

struct RuntimeCwdRelativePath<T>(T);

struct CargoDirRelativePath<T>(T);

type IncludePath<T> = ConfigDirRelativePath<T>;

type TargetDir<T> = CargoDirRelativePath<T>;

relative path chaotic in editor completion and validation

.cargo/config.toml is located in .cargo/.

But target-dir is not relative to .cargo/.

Thus, cannot benefit from modern editor relative path completion, but need to turn off file not found validation.

relative path chaotic in debug

$ cd /tmp/example/bar
$ cargo -Zconfig-include -Zunstable-options config get --format json-value build.target-dir
"../foo/target"

cargo config get output relative path.

But, I think most real world use case would need absolute path.

Proposed Solution

expected

Cargo config path design should decrease memory burden.

Use should not remember

  • which key its path is relative to ${PROJECT_DIR}/.cargo

  • which key its path is relative to ${PROJECT_DIR}

  • which key its path is relative to runtime cwd

There are three types of relative path.

I would suggest

  • ${PROJECT_DIR}/.cargo.config.toml

Thus

  • three types of relative path are basically same.

And to avoid chaotic

  • cargo config path should support template string
include = ["${CONFIG_DIR}/foo/.cargo/config.toml"]

[build]
target-dir = "${CARGO_DIR}/foo/target"

[XXX]
XXX = "${RUNTIME_CWD}/XXX"

pseduo code

// struct ConfigDirRelativePath<T>(T);

// struct RuntimeCwdRelativePath<T>(T);

// struct CargoDirRelativePath<T>(T);

struct CargoDirRelativeTemplatePath<T>(T);

struct AbsolutePath<T>(T);

type IncludePath<T> = CargoDirRelativeTemplatePath<T>;

type TargetDir<T> = CargoDirRelativeTemplatePath<T>;

type CargoConfigDumpPath<T> = AbsolutePath<T>;

Notes

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-feature-requestCategory: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`S-triageStatus: This issue is waiting on initial triage.Z-config-includeNightly: `include` config key

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions