Skip to content
This repository was archived by the owner on Jun 16, 2021. It is now read-only.

Do not panic on string conversions in yaml unmarshaling. #108

Merged
merged 1 commit into from
Dec 8, 2015

Conversation

imikushin
Copy link
Contributor

Do not panic on string conversions in yaml unmarshaling.

Signed-off-by: Ivan Mikushin i.mikushin@gmail.com

@vdemeester
Copy link
Collaborator

Sounds fair 😉
Does the test testing that it does not panic ? :P

@dnephin
Copy link
Contributor

dnephin commented Nov 23, 2015

If I understand correctly, this will treat true as 'true', which I don't think is correct.

Does it also cast all numbers to strings?

Wouldn't this be better handled by #99 ?

@imikushin
Copy link
Contributor Author

@vdemeester The test does test unmarshaling does not panic.
Try running it w/o the changes to types_yaml.go!

@dnephin It does cast everything to string, instead of raising panics. I was thinking: the input file is text (readable and writable by humans) and the target datatype is string, so why not just use the string representation of the value.

On the other hand, the orthodox docker-compose does issue an error, and winter #99 is coming.
I'll update to return errors instead of throwing panics.

@imikushin
Copy link
Contributor Author

Returning errors on incorrect datatypes now.

@imikushin
Copy link
Contributor Author

@vdemeester @dnephin @ibuildthecloud I believe I've addressed the comments so far.

parts[k] = sv
} else {
return fmt.Errorf("Cannot unmarshal '%v' of type %T into a string value", v, v)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This block (including some of the existing lines) are repeated in quite a few places. Could we make this a function?

func ToStringSlice(value []interface{}) ([]string, error) {
    ...
}

Then many of these can be just:

if s.parts, err = BuildParts(value); err != nil {
    return err
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@dnephin
Copy link
Contributor

dnephin commented Nov 25, 2015

I'm not that familiar with this yaml parser. Why is it necessary that these values are cast to strings? Aren't they already strings? Is it trying to deal with cases where yaml treats them as numbers instead of strings?

@imikushin
Copy link
Contributor Author

Parsed values can be anything: bool, integer, string. Consider this YAML list value, for example:

[1, "sick", list, of, false, assumptions]

Suppose, we have our own data type that uses []string internally. When the parser is unmarshaling the given value and calling UnmarshalYAML(tag string, value interface{}) method, here's what it's putting into the value argument:

[]interface{}{1, "sick", "list", "of", false, "assumptions"}

We've got an int, and a bool along with strings. So we have two options:

  • assert that each of the elements is a string, by using the type assertion v.(string), and return an error otherwise (or throw a panic if we don't explicitly check the assertion is successful)
  • use a string representation of each value, by using fmt.Sprint(v), and BTW this is what is used by the parser itself to unmarshal to []string and what I've been proposing in the first place

Return errors instead.

Signed-off-by: Ivan Mikushin <i.mikushin@gmail.com>
@imikushin
Copy link
Contributor Author

Done again.

@dnephin
Copy link
Contributor

dnephin commented Nov 26, 2015

assert that each of the elements is a string

I think this is what the strict yaml validation should be doing for us.

@imikushin
Copy link
Contributor Author

I think this is what the strict yaml validation should be doing for us.

Schema validation makes sure each element of the []interface{} value is a string.
Two things:

  • throwing panics is not nice when the API suggests an error can be returned
  • We don't have schema validation yet. When we have it, we'll just drop the if !ok {...} part which will become redundant.

So, I propose checking for type casting errors (that's what this code is doing now) and drop these checks when the strict yaml validation is in.
Alternatively, drop them now and face the panics OR coerce all values to strings via fmt.Sprint(v) (my original proposal).

Pick one 🎲

@imikushin
Copy link
Contributor Author

@vdemeester Opinions welcome 😄

@ibuildthecloud
Copy link
Contributor

I'm trying to think what is the correct behavior here. docker-compose doesn't actually blow up if you pass

labels:
  foo: true

The parser succeeds but then the Docker API itself will then blow up with some go marshaling API error. So I kind of lean towards doing the same thing. This change makes our parser more pedantic than docker-compose itself. @dnephin WDYT?

@dnephin
Copy link
Contributor

dnephin commented Dec 1, 2015

I think in 1.5.2, it should give a warning when a boolean is used. Previously we were only warning for booleans in the environment field.

I'm happy with more pedantic, as I think that's the direction that compose is going.

@ibuildthecloud
Copy link
Contributor

@dnephin It's a hard pill to swallow for me that foo: true is not supported. Is there docker-compose issue I can comment on or see more context why you guys have decided to go this route? This just seems like a really bad user experience. The same applies to foo: 1. It seems like simple scalars we can safely convert to a string.

@ibuildthecloud
Copy link
Contributor

@dnephin I've been reading through the yaml spec and understand now the complexities.

@ibuildthecloud
Copy link
Contributor

LGTM

@imikushin
Copy link
Contributor Author

@vdemeester Merge? 😉

@vdemeester
Copy link
Collaborator

@imikushin yes 😝
LGTM 🐼

vdemeester added a commit that referenced this pull request Dec 8, 2015
Do not panic on string conversions in yaml unmarshaling.
@vdemeester vdemeester merged commit 5cad17e into docker:master Dec 8, 2015
@imikushin
Copy link
Contributor Author

Thx!

On Tue, Dec 8, 2015, 14:52 Vincent Demeester notifications@github.com
wrote:

Merged #108 #108.


Reply to this email directly or view it on GitHub
#108 (comment).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants