mirror of https://github.com/docker/docs.git
Add support for more advanced ${xxx:...} syntax
Just ${xxx:+...} and ${xxx:-...} for now Signed-off-by: Doug Davis <dug@us.ibm.com>
This commit is contained in:
parent
7dd79dcc7b
commit
39908fc6d9
|
@ -157,7 +157,40 @@ func (sw *shellWord) processDollar() (string, error) {
|
||||||
sw.next()
|
sw.next()
|
||||||
return sw.getEnv(name), nil
|
return sw.getEnv(name), nil
|
||||||
}
|
}
|
||||||
return "", fmt.Errorf("Unsupported ${} substitution: %s", sw.word)
|
if ch == ':' {
|
||||||
|
// Special ${xx:...} format processing
|
||||||
|
// Yes it allows for recursive $'s in the ... spot
|
||||||
|
|
||||||
|
sw.next() // skip over :
|
||||||
|
modifier := sw.next()
|
||||||
|
|
||||||
|
word, err := sw.processStopOn('}')
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grab the current value of the variable in question so we
|
||||||
|
// can use to to determine what to do based on the modifier
|
||||||
|
newValue := sw.getEnv(name)
|
||||||
|
|
||||||
|
switch modifier {
|
||||||
|
case '+':
|
||||||
|
if newValue != "" {
|
||||||
|
newValue = word
|
||||||
|
}
|
||||||
|
return newValue, nil
|
||||||
|
|
||||||
|
case '-':
|
||||||
|
if newValue == "" {
|
||||||
|
newValue = word
|
||||||
|
}
|
||||||
|
return newValue, nil
|
||||||
|
|
||||||
|
default:
|
||||||
|
return "", fmt.Errorf("Unsupported modifier (%c) in substitution: %s", modifier, sw.word)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("Missing ':' in substitution: %s", sw.word)
|
||||||
}
|
}
|
||||||
// $xxx case
|
// $xxx case
|
||||||
name := sw.processName()
|
name := sw.processName()
|
||||||
|
|
|
@ -30,6 +30,17 @@ he${hi} | he
|
||||||
he${hi}xx | hexx
|
he${hi}xx | hexx
|
||||||
he${PWD} | he/home
|
he${PWD} | he/home
|
||||||
he${.} | error
|
he${.} | error
|
||||||
|
he${XXX:-000}xx | he000xx
|
||||||
|
he${PWD:-000}xx | he/homexx
|
||||||
|
he${XXX:-$PWD}xx | he/homexx
|
||||||
|
he${XXX:-${PWD:-yyy}}xx | he/homexx
|
||||||
|
he${XXX:-${YYY:-yyy}}xx | heyyyxx
|
||||||
|
he${XXX:YYY} | error
|
||||||
|
he${XXX:+${PWD}}xx | hexx
|
||||||
|
he${PWD:+${XXX}}xx | hexx
|
||||||
|
he${PWD:+${SHELL}}xx | hebashxx
|
||||||
|
he${XXX:+000}xx | hexx
|
||||||
|
he${PWD:+000}xx | he000xx
|
||||||
'he${XX}' | he${XX}
|
'he${XX}' | he${XX}
|
||||||
"he${PWD}" | he/home
|
"he${PWD}" | he/home
|
||||||
"he'$PWD'" | he'/home'
|
"he'$PWD'" | he'/home'
|
||||||
|
@ -41,3 +52,7 @@ he\$PWD | he$PWD
|
||||||
"he\$PWD" | he$PWD
|
"he\$PWD" | he$PWD
|
||||||
'he\$PWD' | he\$PWD
|
'he\$PWD' | he\$PWD
|
||||||
he${PWD | error
|
he${PWD | error
|
||||||
|
he${PWD:=000}xx | error
|
||||||
|
he${PWD:+${PWD}:}xx | he/home:xx
|
||||||
|
he${XXX:-\$PWD:}xx | he$PWD:xx
|
||||||
|
he${XXX:-\${PWD}z}xx | he${PWDz}xx
|
||||||
|
|
|
@ -113,18 +113,30 @@ images.
|
||||||
> replacement at the time. After 1.3 this behavior will be preserved and
|
> replacement at the time. After 1.3 this behavior will be preserved and
|
||||||
> canonical.
|
> canonical.
|
||||||
|
|
||||||
Environment variables (declared with [the `ENV` statement](#env)) can also be used in
|
Environment variables (declared with [the `ENV` statement](#env)) can also be
|
||||||
certain instructions as variables to be interpreted by the `Dockerfile`. Escapes
|
used in certain instructions as variables to be interpreted by the
|
||||||
are also handled for including variable-like syntax into a statement literally.
|
`Dockerfile`. Escapes are also handled for including variable-like syntax
|
||||||
|
into a statement literally.
|
||||||
|
|
||||||
Environment variables are notated in the `Dockerfile` either with
|
Environment variables are notated in the `Dockerfile` either with
|
||||||
`$variable_name` or `${variable_name}`. They are treated equivalently and the
|
`$variable_name` or `${variable_name}`. They are treated equivalently and the
|
||||||
brace syntax is typically used to address issues with variable names with no
|
brace syntax is typically used to address issues with variable names with no
|
||||||
whitespace, like `${foo}_bar`.
|
whitespace, like `${foo}_bar`.
|
||||||
|
|
||||||
|
The `${variable_name}` syntax also supports a few of the standard `bash`
|
||||||
|
modifiers as specified below:
|
||||||
|
|
||||||
|
* `${variable:-word}` indicates that if `variable` is set then the result
|
||||||
|
will be that value. If `variable` is not set then `word` will be the result.
|
||||||
|
* `${variable:+word}` indiates that if `variable` is set then `word` will be
|
||||||
|
the result, otherwise the result is the empty string.
|
||||||
|
|
||||||
|
In all cases, `word` can be any string, including additional environment
|
||||||
|
variables.
|
||||||
|
|
||||||
Escaping is possible by adding a `\` before the variable: `\$foo` or `\${foo}`,
|
Escaping is possible by adding a `\` before the variable: `\$foo` or `\${foo}`,
|
||||||
for example, will translate to `$foo` and `${foo}` literals respectively.
|
for example, will translate to `$foo` and `${foo}` literals respectively.
|
||||||
|
|
||||||
Example (parsed representation is displayed after the `#`):
|
Example (parsed representation is displayed after the `#`):
|
||||||
|
|
||||||
FROM busybox
|
FROM busybox
|
||||||
|
|
|
@ -214,13 +214,19 @@ func TestBuildEnvironmentReplacementAddCopy(t *testing.T) {
|
||||||
ENV baz foo
|
ENV baz foo
|
||||||
ENV quux bar
|
ENV quux bar
|
||||||
ENV dot .
|
ENV dot .
|
||||||
|
ENV fee fff
|
||||||
|
ENV gee ggg
|
||||||
|
|
||||||
ADD ${baz} ${dot}
|
ADD ${baz} ${dot}
|
||||||
COPY ${quux} ${dot}
|
COPY ${quux} ${dot}
|
||||||
|
ADD ${zzz:-${fee}} ${dot}
|
||||||
|
COPY ${zzz:-${gee}} ${dot}
|
||||||
`,
|
`,
|
||||||
map[string]string{
|
map[string]string{
|
||||||
"foo": "test1",
|
"foo": "test1",
|
||||||
"bar": "test2",
|
"bar": "test2",
|
||||||
|
"fff": "test3",
|
||||||
|
"ggg": "test4",
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -286,6 +292,11 @@ func TestBuildEnvironmentReplacementEnv(t *testing.T) {
|
||||||
if parts[1] != "zzz" {
|
if parts[1] != "zzz" {
|
||||||
t.Fatalf("%s should be 'foo' but instead its %q", parts[0], parts[1])
|
t.Fatalf("%s should be 'foo' but instead its %q", parts[0], parts[1])
|
||||||
}
|
}
|
||||||
|
} else if strings.HasPrefix(parts[0], "env") {
|
||||||
|
envCount++
|
||||||
|
if parts[1] != "foo" {
|
||||||
|
t.Fatalf("%s should be 'foo' but instead its %q", parts[0], parts[1])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4069,6 +4080,27 @@ RUN [ "$abc" = "'foo'" ]
|
||||||
ENV abc \"foo\"
|
ENV abc \"foo\"
|
||||||
RUN [ "$abc" = '"foo"' ]
|
RUN [ "$abc" = '"foo"' ]
|
||||||
|
|
||||||
|
ENV abc=ABC
|
||||||
|
RUN [ "$abc" = "ABC" ]
|
||||||
|
ENV def=${abc:-DEF}
|
||||||
|
RUN [ "$def" = "ABC" ]
|
||||||
|
ENV def=${ccc:-DEF}
|
||||||
|
RUN [ "$def" = "DEF" ]
|
||||||
|
ENV def=${ccc:-${def}xx}
|
||||||
|
RUN [ "$def" = "DEFxx" ]
|
||||||
|
ENV def=${def:+ALT}
|
||||||
|
RUN [ "$def" = "ALT" ]
|
||||||
|
ENV def=${def:+${abc}:}
|
||||||
|
RUN [ "$def" = "ABC:" ]
|
||||||
|
ENV def=${ccc:-\$abc:}
|
||||||
|
RUN [ "$def" = '$abc:' ]
|
||||||
|
ENV def=${ccc:-\${abc}:}
|
||||||
|
RUN [ "$def" = '${abc:}' ]
|
||||||
|
ENV mypath=${mypath:+$mypath:}/home
|
||||||
|
RUN [ "$mypath" = '/home' ]
|
||||||
|
ENV mypath=${mypath:+$mypath:}/away
|
||||||
|
RUN [ "$mypath" = '/home:/away' ]
|
||||||
|
|
||||||
ENV e1=bar
|
ENV e1=bar
|
||||||
ENV e2=$e1
|
ENV e2=$e1
|
||||||
ENV e3=$e11
|
ENV e3=$e11
|
||||||
|
|
Loading…
Reference in New Issue