Skip to content

Conversation

0xrusowsky
Copy link
Contributor

@0xrusowsky 0xrusowsky commented Aug 12, 2025

Motivation

refs:

Solution

This PR introduces a new field extends which allows for foundry.toml to inherit a base config from another toml file. Effectively extending its base config for the active profile.

Relevant considerations:

  • Collisions are resolved with the following precedence: BASE (inherited toml file) < LOCAL (foundry.toml) < ENV
  • Inherited files can have any arbitrary name, the only requirement is to provide a relative path form the foundry.toml
  • Each profile can inherit from a different file
  • Inheritance is effectively applied when the selected profile in foundry.toml has configured extends + the inherited file has some config for the selected profile
  • Configurable merge strategy:
/// Strategy for extending configuration from a base file.
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum ExtendStrategy {
    /// Uses `admerge` figment strategy.
    /// Arrays are concatenated (base elements + local elements).
    /// Other values are replaced (local values override base values).
    ExtendArrays,

    /// Uses `merge` figment strategy.
    /// Arrays are replaced entirely (local arrays replace base arrays).
    /// Other values are replaced (local values override base values).
    ReplaceArrays,

    /// Throws an error if any of the keys in the inherited toml file are also in `foundry.toml`.
    NoCollision,
}

@0xrusowsky 0xrusowsky marked this pull request as ready for review August 12, 2025 14:27
@0xrusowsky 0xrusowsky marked this pull request as draft August 12, 2025 14:29
@0xrusowsky
Copy link
Contributor Author

@mattsse would make sense to give users the ability to decide on the inheritance strategy? imo it could be useful to pick between admerge (extends arrays) and merge (replaces arrays”.

if u agree with the suggestion, i thought we could expose these 2 inheritance modes: "extend-arrays" or "replace-arrays"

wdyt? 🤔

@grandizzy
Copy link
Collaborator

Collisions are resolved with the following precedence: BASE (inherited toml file) < LOCAL (foundry.toml) < ENV

should we automatically resolve conflicts or just error and let dev change setup?

@0xrusowsky
Copy link
Contributor Author

0xrusowsky commented Aug 12, 2025

personally i think that resolving is fine, as imo makes sense for foundry.toml to still have precedence, since its the top-level file in the repo. But it's not a strong opinion, so if u prefer to error, we could also do that @grandizzy

maybe building on top of what i proposed to @mattsse above, we could have a strategy config (i.e. "no-collisions"), which prevents extending and which panics if there are key collisions? could be the default and if they see that it panics, they can change the merge strategy

@0xrusowsky 0xrusowsky requested a review from mattsse August 12, 2025 16:18
@0xrusowsky 0xrusowsky marked this pull request as ready for review August 12, 2025 16:21
@grandizzy
Copy link
Collaborator

personally i think that resolving is fine, as imo makes sense for foundry.toml to still have precedence, since its the top-level file in the repo. But it's not a strong opinion, so if u prefer to error, we could also do that @grandizzy

I don't have a strong opinion but would also like to avoid any misunderstanding, what do other think? @mattsse @DaniPopes @yash-atreya pls chime in

maybe building on top of what i proposed to @mattsse above, we could have a strategy config (i.e. "no-collisions"), which prevents extending and which panics if there are key collisions? could be the default and if they see that it panics, they can change the merge strategy

@0xrusowsky
Copy link
Contributor Author

went ahead and updated the PR with support for 3 strategies as mentioned above:

/// Strategy for extending configuration from a base file.
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum ExtendStrategy {
    /// Uses `admerge` figment strategy.
    /// Arrays are concatenated (base elements + local elements).
    /// Other values are replaced (local values override base values).
    ExtendArrays,

    /// Uses `merge` figment strategy.
    /// Arrays are replaced entirely (local arrays replace base arrays).
    /// Other values are replaced (local values override base values).
    ReplaceArrays,

    /// Throws an error if any of the keys in the inherited toml file are also in `foundry.toml`.
    NoCollision,
}

i currently have extend-arrays as default cause this way i didn't have to update thte tests. But if people like the approach, i can make no-collision the default one

Copy link
Contributor

@onbjerg onbjerg left a comment

Choose a reason for hiding this comment

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

lil nit

Co-authored-by: onbjerg <onbjerg@users.noreply.github.com>
@0xrusowsky 0xrusowsky requested a review from onbjerg August 13, 2025 09:03
Copy link
Member

@mattsse mattsse left a comment

Choose a reason for hiding this comment

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

makes sense

@0xrusowsky 0xrusowsky merged commit 8b7db3a into master Aug 13, 2025
42 of 44 checks passed
@0xrusowsky 0xrusowsky deleted the rusowsky/toml-inheritance branch August 13, 2025 11:50
@github-project-automation github-project-automation bot moved this to Done in Foundry Aug 13, 2025
@0xrusowsky 0xrusowsky self-assigned this Aug 13, 2025
@0xrusowsky 0xrusowsky added this to the v1.4.0 milestone Aug 13, 2025
@grandizzy grandizzy moved this from Done to Completed in Foundry Aug 18, 2025
MerkleBoy pushed a commit to MerkleBoy/foundry that referenced this pull request Sep 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Completed

Development

Successfully merging this pull request may close these issues.

4 participants