diff --git a/jenkins_jobs/dimensions.py b/jenkins_jobs/dimensions.py
index cd3b865bf..45be299fa 100644
--- a/jenkins_jobs/dimensions.py
+++ b/jenkins_jobs/dimensions.py
@@ -11,12 +11,16 @@
# under the License.
import itertools
+from collections import namedtuple
from .errors import Context, JenkinsJobsException
from .loc_loader import LocList, LocDict
from jenkins_jobs.expander import Expander
+Dimension = namedtuple("Dimension", "axis params")
+
+
def _decode_axis_value(axis, value, key_pos, value_pos):
if not isinstance(value, (list, LocList)):
yield {axis: value}
@@ -59,10 +63,20 @@ def enum_dimensions_params(axes, params, defaults):
except KeyError:
continue # May be, value would be received from an another axis values.
expanded_value = expander.expand(value, params)
- value = list(_decode_axis_value(axis, expanded_value, key_pos, value_pos))
+ value = [
+ Dimension(axis, params)
+ for params in _decode_axis_value(axis, expanded_value, key_pos, value_pos)
+ ]
dim_values.append(value)
- for values in itertools.product(*dim_values):
- yield LocDict.merge(*values)
+ for dimensions in itertools.product(*dim_values):
+ overrides = {} # Axis -> overridden param.
+ for dim in dimensions:
+ for name, value in dim.params.items():
+ if name != dim.axis:
+ overrides[name] = value
+ param_dicts = [d.params for d in dimensions]
+ # Parameter overrides should take precedence over axis values.
+ yield LocDict.merge(*param_dicts, overrides)
def _match_exclude(params, exclude, pos):
diff --git a/tests/yamlparser/job_fixtures/dimension_name_parameter_override.yaml b/tests/yamlparser/job_fixtures/dimension_name_parameter_override.yaml
index fe847f0d8..56d8ddd9d 100644
--- a/tests/yamlparser/job_fixtures/dimension_name_parameter_override.yaml
+++ b/tests/yamlparser/job_fixtures/dimension_name_parameter_override.yaml
@@ -8,7 +8,6 @@
- shell: |
echo {param_1} {param_2}
-
- project:
name: sample-project
param_1:
diff --git a/tests/yamlparser/job_fixtures/dimension_name_parameter_override_2.xml b/tests/yamlparser/job_fixtures/dimension_name_parameter_override_2.xml
new file mode 100644
index 000000000..09636fe66
--- /dev/null
+++ b/tests/yamlparser/job_fixtures/dimension_name_parameter_override_2.xml
@@ -0,0 +1,57 @@
+
+
+
+ <!-- Managed by Jenkins Job Builder -->
+ false
+ false
+ false
+ false
+ true
+
+
+
+
+ echo param_1_key param_1_param_2_value_1
+
+
+
+
+
+
+
+
+ <!-- Managed by Jenkins Job Builder -->
+ false
+ false
+ false
+ false
+ true
+
+
+
+
+ echo param_2_param_1_value_1 param_2_param_2_value_2
+
+
+
+
+
+
+
+
+ <!-- Managed by Jenkins Job Builder -->
+ false
+ false
+ false
+ false
+ true
+
+
+
+
+ echo param_3_key param_2_value
+
+
+
+
+
diff --git a/tests/yamlparser/job_fixtures/dimension_name_parameter_override_2.yaml b/tests/yamlparser/job_fixtures/dimension_name_parameter_override_2.yaml
new file mode 100644
index 000000000..8c08bfdb5
--- /dev/null
+++ b/tests/yamlparser/job_fixtures/dimension_name_parameter_override_2.yaml
@@ -0,0 +1,20 @@
+# If a parameter with the same name as dimension name specified, it's value
+# should be used as dimension parameter value.
+
+- job-template:
+ name: job-{param_1}-{param_2}
+ builders:
+ - shell: echo {param_1} {param_2}
+
+- project:
+ name: sample-project
+ param_1:
+ - param_1_key:
+ param_2: param_1_param_2_value_1
+ - param_2_key:
+ param_1: param_2_param_1_value_1
+ param_2: param_2_param_2_value_2
+ - param_3_key
+ param_2: param_2_value
+ jobs:
+ - job-{param_1}-{param_2}
diff --git a/tests/yamlparser/job_fixtures/regression-2010883.xml b/tests/yamlparser/job_fixtures/regression-2010883.xml
new file mode 100644
index 000000000..fd24fa78a
--- /dev/null
+++ b/tests/yamlparser/job_fixtures/regression-2010883.xml
@@ -0,0 +1,76 @@
+
+
+
+ <!-- Managed by Jenkins Job Builder -->
+ false
+ false
+ false
+ false
+ true
+
+
+
+
+ echo The prod orchard has apple trees
+
+
+
+
+
+
+
+
+ <!-- Managed by Jenkins Job Builder -->
+ false
+ false
+ false
+ false
+ true
+
+
+
+
+ echo The qa orchard has apple trees
+
+
+
+
+
+
+
+
+ <!-- Managed by Jenkins Job Builder -->
+ false
+ false
+ false
+ false
+ true
+
+
+
+
+ echo The sandbox orchard has cherry trees
+
+
+
+
+
+
+
+
+ <!-- Managed by Jenkins Job Builder -->
+ false
+ false
+ false
+ false
+ true
+
+
+
+
+ echo The sandbox orchard has orange trees
+
+
+
+
+
diff --git a/tests/yamlparser/job_fixtures/regression-2010883.yaml b/tests/yamlparser/job_fixtures/regression-2010883.yaml
new file mode 100644
index 000000000..2bfe02462
--- /dev/null
+++ b/tests/yamlparser/job_fixtures/regression-2010883.yaml
@@ -0,0 +1,17 @@
+ - job-template:
+ name: '{environment}-{fruit}-orchard'
+ builders:
+ - shell: 'echo The {environment} orchard has {fruit} trees'
+
+ - project:
+ name: 'Fruit orchard'
+ environment:
+ - sandbox:
+ fruit: 'orange'
+ - sandbox:
+ fruit: 'cherry'
+ - qa
+ - prod
+ fruit: apple
+ jobs:
+ - '{environment}-{fruit}-orchard'