Manager: allow setup to finish without Blender #104306
@ -15,7 +15,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/rs/zerolog"
|
||||
"projects.blender.org/studio/flamenco/internal/appinfo"
|
||||
"projects.blender.org/studio/flamenco/internal/find_blender"
|
||||
"projects.blender.org/studio/flamenco/internal/manager/config"
|
||||
@ -266,10 +265,9 @@ func (f *Flamenco) SaveSetupAssistantConfig(e echo.Context) error {
|
||||
|
||||
logger = logger.With().Interface("config", setupAssistantCfg).Logger()
|
||||
|
||||
if setupAssistantCfg.StorageLocation == "" ||
|
||||
isBlenderPathCheckResultIncomplete(setupAssistantCfg.BlenderExecutable, logger) {
|
||||
logger.Warn().Msg("setup assistant: configuration is incomplete, unable to accept")
|
||||
return sendAPIError(e, http.StatusBadRequest, "configuration is incomplete")
|
||||
if err := checkSetupAssistantConfig(setupAssistantCfg); err != nil {
|
||||
logger.Warn().Msg("setup assistant: configuration is invalid or incomplete, " + err.Error())
|
||||
abelli marked this conversation as resolved
Outdated
|
||||
return sendAPIError(e, http.StatusBadRequest, "configuration is invalid or incomplete")
|
||||
abelli marked this conversation as resolved
Outdated
Sybren A. Stüvel
commented
It's fine to include the actual error message in the response as well, so that the caller knows what's wrong without checking the Manager log. It's fine to include the actual error message in the response as well, so that the caller knows what's wrong without checking the Manager log.
|
||||
}
|
||||
|
||||
conf := f.config.Get()
|
||||
@ -337,28 +335,32 @@ func commandNeedsQuoting(cmd string) bool {
|
||||
return strings.ContainsAny(cmd, "\n\t;()")
|
||||
}
|
||||
|
||||
func isBlenderPathCheckResultIncomplete(checkResult api.BlenderPathCheckResult, logger zerolog.Logger) bool {
|
||||
switch checkResult.Source {
|
||||
case api.BlenderPathSourceDefault:
|
||||
if !checkResult.IsUsable {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
case api.BlenderPathSourceFileAssociation:
|
||||
if !checkResult.IsUsable ||
|
||||
checkResult.Path == "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
case api.BlenderPathSourceInputPath, api.BlenderPathSourcePathEnvvar:
|
||||
if !checkResult.IsUsable ||
|
||||
checkResult.Path == "" ||
|
||||
checkResult.Input == "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
func checkSetupAssistantConfig(config api.SetupAssistantConfig) error {
|
||||
if config.StorageLocation == "" {
|
||||
return errors.New("'storageLocation' field must not be empty")
|
||||
}
|
||||
|
||||
logger.Warn().Msg("received an unexpected blender path source")
|
||||
return true
|
||||
if !config.BlenderExecutable.IsUsable {
|
||||
abelli marked this conversation as resolved
Outdated
Sybren A. Stüvel
commented
The check for The check for `IsUsable` can be moved out of the `switch` since it's the same for every `case` anyway.
|
||||
return errors.New("sources cannot have the 'is_usable' field set to false")
|
||||
}
|
||||
|
||||
switch config.BlenderExecutable.Source {
|
||||
case api.BlenderPathSourceDefault:
|
||||
return nil
|
||||
|
||||
case api.BlenderPathSourceFileAssociation:
|
||||
if config.BlenderExecutable.Path == "" {
|
||||
return errors.New("'path' field must not be empty while using the 'file_association' source")
|
||||
}
|
||||
|
||||
case api.BlenderPathSourceInputPath, api.BlenderPathSourcePathEnvvar:
|
||||
if config.BlenderExecutable.Path == "" ||
|
||||
config.BlenderExecutable.Input == "" {
|
||||
return errors.New("'path' or 'input' fields must not be empty while using the 'input_path' or 'path_envvar' sources")
|
||||
}
|
||||
default:
|
||||
abelli marked this conversation as resolved
Outdated
Sybren A. Stüvel
commented
Add another Another solution would be to use the Add another `case ""`. That way the dynamically generated error below doesn't just show `"unknown 'source' field value: "` if the `source` field is empty.
Another solution would be to use the `%q` format specifier in the below-suggested call to `fmt.Errorf()`, but that would _always_ put quotes around the value. If that error is then subsequently logged with something like `log.Error().Err(err).Msg("whatever")`, those quotes will get escaped and things will be uglier than necessary. So that's why I think it's nicer to handle the empty string as a special case, and keep the non-empty-string case without quotes.
|
||||
return errors.New("unknown 'source' field value: " + string(config.BlenderExecutable.Source))
|
||||
abelli marked this conversation as resolved
Outdated
Sybren A. Stüvel
commented
This function could return an error instead of a boolean. That error can then not only be used to communicate what is still missing, but also cover this case. That'll avoid the need to pass a logger to the function. This function could return an error instead of a boolean. That error can then not only be used to communicate what is still missing, but also cover this case. That'll avoid the need to pass a logger to the function.
Sybren A. Stüvel
commented
Unfortunately Gitea does not support multiple comments for the same source line. So I'll reply to the previous one, even though at this line number there is now different code.
This should use Unfortunately Gitea does not support multiple comments for the same source line. So I'll reply to the previous one, even though at this line number there is now different code.
```
return errors.New("unknown 'source' field value: " + string(config.BlenderExecutable.Source))
```
This should use `fmt.Errorf()` instead.
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
The work cannot be done, and so this should be logged as an error, not a warning.
I usually log errors as a 'cause' field:
Alternatively, if you want to keep the error message as part of the log message, you could use
.Msgf(...)
instead:%v
is Go's generic "put the thing's value here", and should result in the value oferr.Error()
.