Skip to content

Commit 19616b8

Browse files
committed
Add namespacing
1 parent fd058ff commit 19616b8

File tree

11 files changed

+126
-54
lines changed

11 files changed

+126
-54
lines changed

docs/user/reference/config/components.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ A component definition tells azldev where to find the spec file, how to customiz
99
| Field | TOML Key | Type | Required | Description |
1010
|-------|----------|------|----------|-------------|
1111
| Spec source | `spec` | [SpecSource](#spec-source) | No | Where to find the spec file for this component. Inherited from distro defaults if not specified. |
12-
| Release calculation | `release-calculation` | string | No | Controls how the Release tag is managed during rendering. `"auto"` (default) = auto-bump; `"manual"` = skip all automatic Release manipulation |
12+
| Release config | `release` | [ReleaseConfig](#release-configuration) | No | Controls how the Release tag is managed during rendering |
1313
| Overlays | `overlays` | array of [Overlay](overlays.md) | No | Modifications to apply to the spec and/or source files |
1414
| Build config | `build` | [BuildConfig](#build-configuration) | No | Build-time options (macros, conditionals, check config) |
1515
| Source files | `source-files` | array of [SourceFileReference](#source-file-references) | No | Additional source files to download for this component |
@@ -98,6 +98,21 @@ spec = { type = "local", path = "azurelinux-release.spec" }
9898

9999
The `path` is relative to the config file that defines the component. Local spec files and any associated source files should be placed alongside the component's `.comp.toml` file.
100100

101+
## Release Configuration
102+
103+
The `[components.<name>.release]` section controls how azldev manages the Release tag during rendering.
104+
105+
| Field | TOML Key | Type | Required | Description |
106+
|-------|----------|------|----------|-------------|
107+
| Calculation | `calculation` | string | No | `"auto"` (default) = auto-bump; `"manual"` = skip all automatic Release manipulation |
108+
109+
Most components use auto mode (the default) and need no release configuration. Set `calculation = "manual"` for components that manage their own release numbering, such as kernel:
110+
111+
```toml
112+
[components.kernel.release]
113+
calculation = "manual"
114+
```
115+
101116
## Build Configuration
102117

103118
The `[components.<name>.build]` section controls build-time options for a component.

internal/app/azldev/core/components/resolver.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,8 +463,8 @@ func (r *Resolver) createComponentFromConfig(componentConfig *projectconfig.Comp
463463
componentConfig.Name, err)
464464
}
465465

466-
if componentConfig.ReleaseCalculation == "" {
467-
componentConfig.ReleaseCalculation = projectconfig.ReleaseCalculationAuto
466+
if componentConfig.Release.Calculation == "" {
467+
componentConfig.Release.Calculation = projectconfig.ReleaseCalculationAuto
468468
}
469469

470470
return &resolvedComponent{

internal/app/azldev/core/components/resolver_test.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ func setupTestSpec(t *testing.T, testEnv *testutils.TestEnv, path string) projec
3636
SourceType: projectconfig.SpecSourceTypeLocal,
3737
Path: path,
3838
},
39-
ReleaseCalculation: projectconfig.ReleaseCalculationAuto,
39+
Release: projectconfig.ReleaseConfig{
40+
Calculation: projectconfig.ReleaseCalculationAuto,
41+
},
4042
}
4143
}
4244

@@ -45,8 +47,10 @@ func addTestComponentToConfig(t *testing.T, env *testutils.TestEnv) projectconfi
4547
t.Helper()
4648

4749
component := projectconfig.ComponentConfig{
48-
Name: "test-component",
49-
ReleaseCalculation: projectconfig.ReleaseCalculationAuto,
50+
Name: "test-component",
51+
Release: projectconfig.ReleaseConfig{
52+
Calculation: projectconfig.ReleaseCalculationAuto,
53+
},
5054
}
5155

5256
env.Config.Components[component.Name] = component
@@ -246,7 +250,9 @@ func TestFindAllComponents_MergesComponentPresentBySpecAndConfig(t *testing.T) {
246250
SourceType: projectconfig.SpecSourceTypeLocal,
247251
Path: testSpecPath,
248252
},
249-
ReleaseCalculation: projectconfig.ReleaseCalculationAuto,
253+
Release: projectconfig.ReleaseConfig{
254+
Calculation: projectconfig.ReleaseCalculationAuto,
255+
},
250256
}
251257

252258
// Find!

internal/app/azldev/core/sources/release.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,16 +96,16 @@ func BumpStaticRelease(releaseValue string, commitCount int) (string, error) {
9696
// already resolves the release number from git history.
9797
//
9898
// When the Release tag uses a non-standard value (not %autorelease and not a leading
99-
// integer, e.g. %{pkg_release}), the component must set release-calculation to
99+
// integer, e.g. %{pkg_release}), the component must set release.calculation to
100100
// "manual", and likely define an explicit overlay that sets the Release tag.
101-
// If a non-standard Release is found and release-calculation is not "manual",
101+
// If a non-standard Release is found and release.calculation is not "manual",
102102
// an error is returned.
103103
func (p *sourcePreparerImpl) tryBumpStaticRelease(
104104
component components.Component,
105105
sourcesDirPath string,
106106
commitCount int,
107107
) error {
108-
if component.GetConfig().ReleaseCalculation == projectconfig.ReleaseCalculationManual {
108+
if component.GetConfig().Release.Calculation == projectconfig.ReleaseCalculationManual {
109109
slog.Debug("Component uses manual release calculation; skipping static release bump",
110110
"component", component.GetName())
111111

@@ -133,10 +133,10 @@ func (p *sourcePreparerImpl) tryBumpStaticRelease(
133133
newRelease, err := BumpStaticRelease(releaseValue, commitCount)
134134
if err != nil {
135135
// The Release tag does not start with an integer (e.g. %{pkg_release})
136-
// and the user did not set release-calculation to "manual".
136+
// and the user did not set release.calculation to "manual".
137137
return fmt.Errorf(
138138
"component %#q has a non-standard Release tag value %#q that cannot be auto-bumped; "+
139-
"set 'release-calculation = \"manual\"' in the component configuration "+
139+
"set 'release.calculation = \"manual\"' in the component configuration "+
140140
"and add a \"spec-set-tag\" overlay for the Release tag if needed:\n%w",
141141
component.GetName(), releaseValue, err)
142142
}

internal/app/azldev/core/sources/release_internal_test.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ func TestTryBumpStaticRelease_ManualSkips(t *testing.T) {
5353
preparer := newTestPreparer(memFS)
5454

5555
comp := mockComponent(ctrl, "kernel", &projectconfig.ComponentConfig{
56-
ReleaseCalculation: projectconfig.ReleaseCalculationManual,
56+
Release: projectconfig.ReleaseConfig{
57+
Calculation: projectconfig.ReleaseCalculationManual,
58+
},
5759
})
5860

5961
// No spec file needed — should skip before reading anything.
@@ -69,7 +71,9 @@ func TestTryBumpStaticRelease_AutoreleaseSkips(t *testing.T) {
6971
writeTestSpec(t, memFS, "test-pkg", "%autorelease")
7072

7173
comp := mockComponent(ctrl, "test-pkg", &projectconfig.ComponentConfig{
72-
ReleaseCalculation: projectconfig.ReleaseCalculationAuto,
74+
Release: projectconfig.ReleaseConfig{
75+
Calculation: projectconfig.ReleaseCalculationAuto,
76+
},
7377
})
7478

7579
err := preparer.tryBumpStaticRelease(comp, filepath.Join(testSourcesDir, "test-pkg"), 3)
@@ -84,7 +88,9 @@ func TestTryBumpStaticRelease_StaticBumps(t *testing.T) {
8488
writeTestSpec(t, memFS, "test-pkg", "1%{?dist}")
8589

8690
comp := mockComponent(ctrl, "test-pkg", &projectconfig.ComponentConfig{
87-
ReleaseCalculation: projectconfig.ReleaseCalculationAuto,
91+
Release: projectconfig.ReleaseConfig{
92+
Calculation: projectconfig.ReleaseCalculationAuto,
93+
},
8894
})
8995

9096
err := preparer.tryBumpStaticRelease(comp, filepath.Join(testSourcesDir, "test-pkg"), 3)
@@ -105,13 +111,15 @@ func TestTryBumpStaticRelease_NonStandardErrorsWithoutManual(t *testing.T) {
105111
writeTestSpec(t, memFS, "kernel", "%{pkg_release}")
106112

107113
comp := mockComponent(ctrl, "kernel", &projectconfig.ComponentConfig{
108-
ReleaseCalculation: projectconfig.ReleaseCalculationAuto,
114+
Release: projectconfig.ReleaseConfig{
115+
Calculation: projectconfig.ReleaseCalculationAuto,
116+
},
109117
})
110118

111119
err := preparer.tryBumpStaticRelease(comp, filepath.Join(testSourcesDir, "kernel"), 3)
112120
require.Error(t, err)
113121
assert.Contains(t, err.Error(), "cannot be auto-bumped")
114-
assert.Contains(t, err.Error(), "release-calculation")
122+
assert.Contains(t, err.Error(), "release.calculation")
115123
}
116124

117125
func TestTryBumpStaticRelease_NonStandardSucceedsWithManual(t *testing.T) {
@@ -122,7 +130,9 @@ func TestTryBumpStaticRelease_NonStandardSucceedsWithManual(t *testing.T) {
122130
writeTestSpec(t, memFS, "kernel", "%{pkg_release}")
123131

124132
comp := mockComponent(ctrl, "kernel", &projectconfig.ComponentConfig{
125-
ReleaseCalculation: projectconfig.ReleaseCalculationManual,
133+
Release: projectconfig.ReleaseConfig{
134+
Calculation: projectconfig.ReleaseCalculationManual,
135+
},
126136
})
127137

128138
err := preparer.tryBumpStaticRelease(comp, filepath.Join(testSourcesDir, "kernel"), 3)

internal/projectconfig/component.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,12 @@ const (
122122
ReleaseCalculationManual ReleaseCalculation = "manual"
123123
)
124124

125+
// ReleaseConfig holds release-related configuration for a component.
126+
type ReleaseConfig struct {
127+
// Calculation controls how the Release tag is managed during rendering.
128+
Calculation ReleaseCalculation `toml:"calculation,omitempty" json:"calculation,omitempty" validate:"omitempty,oneof=auto manual" jsonschema:"enum=auto,enum=manual,default=auto,title=Release calculation,description=Controls how the Release tag is managed during rendering. Empty or omitted means auto."`
129+
}
130+
125131
// Defines a component.
126132
type ComponentConfig struct {
127133
// The component's name; not actually present in serialized files.
@@ -139,10 +145,8 @@ type ComponentConfig struct {
139145
// Where to get its spec and adjacent files from.
140146
Spec SpecSource `toml:"spec,omitempty" json:"spec,omitempty" jsonschema:"title=Spec,description=Identifies where to find the spec for this component"`
141147

142-
// ReleaseCalculation controls how the Release tag is managed during rendering.
143-
// Defaults to auto (empty). Set to "manual" for components that manage their own
144-
// release numbering (e.g. kernel).
145-
ReleaseCalculation ReleaseCalculation `toml:"release-calculation,omitempty" json:"releaseCalculation,omitempty" validate:"omitempty,oneof=auto manual" jsonschema:"enum=auto,enum=manual,title=Release calculation,description=Controls how the Release tag is managed during rendering. Empty or omitted means auto."`
148+
// Release configuration for this component.
149+
Release ReleaseConfig `toml:"release,omitempty" json:"release,omitempty" table:"-" jsonschema:"title=Release configuration,description=Configuration for how the Release tag is managed during rendering."`
146150

147151
// Overlays to apply to sources after they've been acquired. May mutate the spec as well as sources.
148152
Overlays []ComponentOverlay `toml:"overlays,omitempty" json:"overlays,omitempty" table:"-" jsonschema:"title=Overlays,description=Overlays to apply to this component's spec and/or sources"`
@@ -192,7 +196,7 @@ func (c *ComponentConfig) WithAbsolutePaths(referenceDir string) *ComponentConfi
192196
Name: c.Name,
193197
SourceConfigFile: c.SourceConfigFile,
194198
RenderedSpecDir: c.RenderedSpecDir,
195-
ReleaseCalculation: c.ReleaseCalculation,
199+
Release: c.Release,
196200
Spec: deep.MustCopy(c.Spec),
197201
Build: deep.MustCopy(c.Build),
198202
SourceFiles: deep.MustCopy(c.SourceFiles),

internal/projectconfig/component_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -216,20 +216,20 @@ func TestReleaseCalculationValidation(t *testing.T) {
216216
validate := validator.New()
217217

218218
// Empty (omitted) is valid — resolved to "auto" by the component resolver.
219-
require.NoError(t, validate.Struct(&projectconfig.ComponentConfig{}))
219+
require.NoError(t, validate.Struct(&projectconfig.ReleaseConfig{}))
220220

221221
// Explicit "auto" is valid.
222-
require.NoError(t, validate.Struct(&projectconfig.ComponentConfig{
223-
ReleaseCalculation: projectconfig.ReleaseCalculationAuto,
222+
require.NoError(t, validate.Struct(&projectconfig.ReleaseConfig{
223+
Calculation: projectconfig.ReleaseCalculationAuto,
224224
}))
225225

226226
// Explicit "manual" is valid.
227-
require.NoError(t, validate.Struct(&projectconfig.ComponentConfig{
228-
ReleaseCalculation: projectconfig.ReleaseCalculationManual,
227+
require.NoError(t, validate.Struct(&projectconfig.ReleaseConfig{
228+
Calculation: projectconfig.ReleaseCalculationManual,
229229
}))
230230

231231
// Invalid value is rejected.
232-
require.Error(t, validate.Struct(&projectconfig.ComponentConfig{
233-
ReleaseCalculation: "manaul",
232+
require.Error(t, validate.Struct(&projectconfig.ReleaseConfig{
233+
Calculation: "manaul",
234234
}))
235235
}

internal/projectconfig/fingerprint_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ func TestAllFingerprintedFieldsHaveDecision(t *testing.T) {
3232
reflect.TypeFor[projectconfig.SpecSource](),
3333
reflect.TypeFor[projectconfig.DistroReference](),
3434
reflect.TypeFor[projectconfig.SourceFileReference](),
35+
reflect.TypeFor[projectconfig.ReleaseConfig](),
3536
}
3637

3738
// Maps "StructName.FieldName" for every field that should carry a

scenario/__snapshots__/TestSnapshotsContainer_config_generate-schema_stdout_1.snap

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,10 @@
106106
"title": "Spec",
107107
"description": "Identifies where to find the spec for this component"
108108
},
109-
"release-calculation": {
110-
"type": "string",
111-
"enum": [
112-
"auto",
113-
"manual"
114-
],
115-
"title": "Release calculation",
116-
"description": "Controls how the Release tag is managed during rendering. Empty or omitted means auto."
109+
"release": {
110+
"$ref": "#/$defs/ReleaseConfig",
111+
"title": "Release configuration",
112+
"description": "Configuration for how the Release tag is managed during rendering."
117113
},
118114
"overlays": {
119115
"items": {
@@ -660,6 +656,22 @@
660656
"additionalProperties": false,
661657
"type": "object"
662658
},
659+
"ReleaseConfig": {
660+
"properties": {
661+
"calculation": {
662+
"type": "string",
663+
"enum": [
664+
"auto",
665+
"manual"
666+
],
667+
"title": "Release calculation",
668+
"description": "Controls how the Release tag is managed during rendering. Empty or omitted means auto.",
669+
"default": "auto"
670+
}
671+
},
672+
"additionalProperties": false,
673+
"type": "object"
674+
},
663675
"SourceFileReference": {
664676
"properties": {
665677
"filename": {

scenario/__snapshots__/TestSnapshots_config_generate-schema_stdout_1.snap

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,10 @@
106106
"title": "Spec",
107107
"description": "Identifies where to find the spec for this component"
108108
},
109-
"release-calculation": {
110-
"type": "string",
111-
"enum": [
112-
"auto",
113-
"manual"
114-
],
115-
"title": "Release calculation",
116-
"description": "Controls how the Release tag is managed during rendering. Empty or omitted means auto."
109+
"release": {
110+
"$ref": "#/$defs/ReleaseConfig",
111+
"title": "Release configuration",
112+
"description": "Configuration for how the Release tag is managed during rendering."
117113
},
118114
"overlays": {
119115
"items": {
@@ -660,6 +656,22 @@
660656
"additionalProperties": false,
661657
"type": "object"
662658
},
659+
"ReleaseConfig": {
660+
"properties": {
661+
"calculation": {
662+
"type": "string",
663+
"enum": [
664+
"auto",
665+
"manual"
666+
],
667+
"title": "Release calculation",
668+
"description": "Controls how the Release tag is managed during rendering. Empty or omitted means auto.",
669+
"default": "auto"
670+
}
671+
},
672+
"additionalProperties": false,
673+
"type": "object"
674+
},
663675
"SourceFileReference": {
664676
"properties": {
665677
"filename": {

0 commit comments

Comments
 (0)