#@MB mind renaming `plan` to `PLAN` in
1 messages ยท Page 1 of 1 (latest)
starting thread here
FWIW I tried to repro in v0.18.12 and I wasn't able to do it. Here's my repro:
type Hello struct{}
type Task string
const (
Plan Task = "plan"
Apply Task = "apply"
)
func (m *Hello) Test(ctx context.Context, task Task) (string, error) {
return dag.Container().From("alpine").WithExec([]string{"echo", string(task)}).Stdout(ctx)
}
both dagger call test --task plan and dagger call test --task PLAN work in this case
I've got three enums. If I leave two in var and move one enum's entries to const I get panic: failed to unmarshal parent object: unknown enum value "" no matter lower or upper case input for that parameter
Moving one enum at a time and testing further...
Ok it's just that enum. The other two work fine. The only difference I can see is that enum has entries in proper case, the other two have entries in all capitals
Ruled out:
- The struct attribute having the same name as the enum type by changing the name of the struct attr
- The function having a default value for that enum parameter by removing the default value
- Casing by changing the casing of both the enum keys and values
Trace for --help: https://dagger.cloud/mjb/traces/d96a30364f5ed526495ca332e95c7407
Trace for erroring command: https://dagger.cloud/mjb/traces/f62e28f047db7346629aa4223f9389d0
Perhaps you can spot what I can't?
Ok @junior furnace the problem is storing an enum on the module struct. I have this:
type ServiceDeployer struct {
...
Command TerraformCommand
}
and the enum:
type TerraformCommand string
const (
Plan TerraformCommand = "plan"
Apply TerraformCommand = "apply
)
then in a method later on I accept a parameter of type TerraformCommand and assign it to the struct:
m.Command = command
Removing that (and replacing that m.Command = command with Plan) and the method completes
Yeah that's it. Removed it from the struct, moved the --command parameter to the methods that actually use it, added a default and it's working. User will have to repeat the --command on a few methods but that's fine to progress with
Leads me onto my next question. Writing a Dagger test module for a module that uses enum parameters... How do I provide those enum inputs in tests?
Seems like dagger.<module-name><enum-name> can convert it. My editor doesn't think that has been defined, but the test submodule is running.
Solved again, a round of dagger develop and dagger install .. did it... Think this one is done!
@wanton hare I'm still trying to repro your error without success. I've modified my code above like this:
type Hello struct {
Task Task
}
type Task string
const (
Plan Task = "plan"
Apply Task = "apply"
)
func (m *Hello) Test(ctx context.Context, task Task) (string, error) {
m.Task = task
return dag.Container().From("alpine").WithExec([]string{"echo", string(task)}).Stdout(ctx)
}
and I can still call dagger call test --task PLAN without any issues
if you manage to find the time would you be able to help me trying to repro in this tiny example?
also tried this:
type Hello struct {
Task Task
}
type Task string
const (
Plan Task = "plan"
Apply Task = "apply"
)
func (m *Hello) WithTask(task Task) *Hello {
m.Task = task
return m
}
func (m *Hello) Test(ctx context.Context) (string, error) {
return dag.Container().From("alpine").WithExec([]string{"echo", string(m.Task)}).Stdout(ctx)
}
and calling dagger call with-task --task plan test was not able to repro either
Add another struct attribute (doesn't matter what it's called or the value), then add another method that returns an instance if that struct but doesn't set the Task and that's probably it. I have two methods: WithCredentials is called first and doesn't set the struct attribute that was erroring (this is probably why it couldn't unmarshall "", struct was being created with no value for that attribute), then a second method WithConfig that set the struct attribute.
type Hello struct {
Task Task
Word string
}
dagger call method-that-sets-Word --word "goodbye" method-that-sets-Task --task plan
The trace link should explain this better than I have, but that's almost certainly the problem I encountered. Instance of struct created by the first method without the enum value, so "", which fails
ok, now I was able to repro. Checking if this is fixed in main but I haven't seen any issues about it. ๐
we'll make a release of the engine this week so we'll make sure to fix that
cc @trail pulsar we should fix it before the next release
If that just turns out to be a constraint or design decision that's also fine. I also haven't actually tried setting a default value for a struct attribute, might be an option?
@wanton hare also found a workaround which actually makes sense. If you make the enum field in the struct of type *Task in my example, that will work
this whole thing basically translates to Go's default values and some checks that we do from our side to verify that the enum is correctly set. So when you add another function and the enum is set to its default value ("" for the underlying string type), that's when you get the error.
TBH I don't really think this need fixing. Having said that, probably a caveat that we should probably document
fix what, sorry?
@trail pulsar default values in Go at least using enums yield some very confusing errors
let me get you the last full repro I have
what's the error?
type Hello struct {
Task Task
Word string
}
type Task string
const (
Plan Task = "plan"
Apply Task = "apply"
)
func (m *Hello) WithTask(task Task) *Hello {
m.Task = task
return m
}
func (m *Hello) WithWord(word string) *Hello {
m.Word = word
return m
}
func (m *Hello) Test(ctx context.Context) (string, error) {
return dag.Container().From("alpine").WithExec([]string{"echo", string(m.Task)}).Stdout(ctx)
}
^ if you call dagger call with-word --word "foo" with-task --task plan test you'll get
! failed to collect IDs: failed to convert field "Task": *core.ModuleEnumType.ConvertFromSDKResult:
invalid enum value "" for "HelloTask": invalid enum member "" for HelloTask
given that the Task field in the struct will be set to Go's underlying default value ("") which will trigger the error above
I think so...?
edit: wait.. I thought you said is a regression
not sure ๐ค
๐
okay, i think this has always been the behavior
honestly, i also think it's expected. error could be better, yes, but i don't really think we should let it be valid
yeah.. kind of make sense. That's why I mentioned I think nothing needs fixing here. Specially if changing Task to *Task addresses the underlying issue. Which again.. should be the correct way to handle it