Conversation
9dc142a to
1c69b18
Compare
c36db49 to
148542b
Compare
|
@casey this is ready for review |
src/attribute_set.rs
Outdated
| InvertedStatus::Normal | ||
| } | ||
| } | ||
| _ => return None, |
There was a problem hiding this comment.
I think this function should panic if we call it with a non-invertible attribute.
src/recipe.rs
Outdated
| }; | ||
|
|
||
| if cfg!(target_os = "linux") { | ||
| return !(disabled.linux || disabled.unix) |
There was a problem hiding this comment.
Are these unix checks redundant with the ones below? I notice that the other Unix OS's don't have the same checks.
There was a problem hiding this comment.
I think this maybe all gets easier if we have a System enum which represents the current system:
enum System {
Windows,
Linux,
Unix,
...
}
impl System {
fn current() -> &'static [System] {
if cfg(target_os = "linux") {
&[Self::Linux, Self::Unix]
}
}
}
And then we can handle all these checks in the same way.
src/recipe.rs
Outdated
| || (cfg!(target_os = "windows") && windows) | ||
| || (cfg!(unix) && unix) | ||
| || (cfg!(windows) && windows) | ||
| use attribute_set::InvertedStatus; |
There was a problem hiding this comment.
I'm not sure I like introducing inverted status only to turn it back to a bool with matches!. I think it would probably be better to just use a bool the whole way.
src/attribute.rs
Outdated
| Group(StringLiteral<'src>), | ||
| Linux, | ||
| Macos, | ||
| Linux { inverted: bool }, |
There was a problem hiding this comment.
I think we should probably use:
| Linux { inverted: bool }, | |
| Linux { enabled: bool }, |
And invert the meaning of the boolean, to make the downstream code make more sense.
src/attribute.rs
Outdated
| AttributeDiscriminant::Private => Self::Private, | ||
| AttributeDiscriminant::Script => Self::Script({ | ||
| Ok(match (inverted, discriminant) { | ||
| (inverted, AttributeDiscriminant::Linux) => Self::Linux { inverted }, |
There was a problem hiding this comment.
| (inverted, AttributeDiscriminant::Linux) => Self::Linux { inverted }, | |
| (inverted, AttributeDiscriminant::Linux) => Self::Linux { enabled: !inverted }, |
|
|
||
| loop { | ||
| let name = self.parse_name()?; | ||
| let (name, inverted) = { |
There was a problem hiding this comment.
I think this is probably cleaner than using mutable variables:
| let (name, inverted) = { | |
| let (name, inverted) = { | |
| let name = self.parse_name()?; | |
| if name.lexeme() == "not" { | |
| self.expect(ParenL)?; | |
| let name = self.parse_name()?; | |
| (name, true) | |
| } else { | |
| (name, false) | |
| } | |
| } |
There was a problem hiding this comment.
And I think we should actually, since we don't have any invertable variables which aren't system variables, change the argument to Attribute::new to be !inverted, and within Attribute::new it's called enabled.
7d30976 to
78c67e2
Compare
c3f4feb to
1bacd8c
Compare
casey
left a comment
There was a problem hiding this comment.
See comments. This looks great, I like the structure, but we definitely need to do some kind of more extensive testing.
src/recipe.rs
Outdated
| if cfg!(unix) { | ||
| return Unix; | ||
| } | ||
| panic!("No recognized system"); |
There was a problem hiding this comment.
I don't think this can panic. We should have an Unrecognized variant.
src/recipe.rs
Outdated
| panic!("No recognized system"); | ||
| } | ||
|
|
||
| fn enabled(self, enabled: SystemMap, disabled: SystemMap) -> bool { |
There was a problem hiding this comment.
I think we need some kind of more extensive testing for this. It looks right to me, but it strikes me as very fragile, and easy to get wrong when extending..
There was a problem hiding this comment.
Yeah, makes senses - I'm not not entirely happy with the fragility of this code either, but I don't have any ideas off the top of my head for how to make it more robust. Do you have any ideas for how the tests should be architected?
There was a problem hiding this comment.
One idea:
#[test]
fn foo() {
fn case(attributes: &str, active: bool) {
Test::new().justfile(format!("[{attributes}]\nfoo:"))
// assert that foo is or isn't active, depending on attributes.
}
case("macos", cfg!(target_os = "darwin"));
}
One idea for improving the structure would be to try to factor out this pattern:
System::Windows => {
!disabled.windows
&& (enabled.windows
|| !(enabled.macos || enabled.linux || enabled.openbsd || enabled.unix))
}
Maybe with maps:
!disabled[self] && (enabled[self] || !self.others().iter().any(|other| system.enabled()))
src/recipe.rs
Outdated
| && (enabled.windows | ||
| || !(enabled.macos || enabled.linux || enabled.openbsd || enabled.unix)) | ||
| } | ||
| System::MacOS => { |
There was a problem hiding this comment.
On MacOS, and other unix systems, a recipe with [not(unix)] will be enabled. This seems wrong to me.
bfd54da to
8362ffc
Compare
8362ffc to
bfba342
Compare
casey#1895 Swap inverted to enabled Use System type
bfba342 to
b45c20b
Compare
This PR implements a
not()syntax for certain OS-target attributes.Resolves #1895