Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/user/reference/cli/azldev_component.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_component_add.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_component_build.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_component_changed.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_component_diff-sources.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_component_history.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_component_list.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_component_query.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_component_render.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_component_update.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion docs/user/reference/config/overlays.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ Overlays are defined within a component's configuration in your TOML config file

### Spec Overlays

These overlays modify `.spec` files using the structured spec parser, allowing precise targeting of tags and sections.
These overlays modify `.spec` files using the component command's `--spec-editor` option. The default `legacy` editor is line-oriented; `--spec-editor experimental` selects the structural editor, which preserves conditional and section structure.

#### Known Limitations

With the structural editor, content after a conditional wrapper's `%endif` cannot always be statically attributed to a section declared inside that wrapper. A scoped overlay may therefore not reach that content; use a narrowly anchored whole-spec `spec-search-replace` overlay instead.

Sections generated by macros are unavailable to both editors because azldev does not evaluate RPM macros while editing specs.

| Type | Description | Required Fields |
|------|-------------|-----------------|
Expand Down
11 changes: 9 additions & 2 deletions internal/app/azldev/cmds/component/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
)

type ComponentBuildOptions struct {
componentCommandOptions
ComponentFilter components.ComponentFilter

ContinueOnError bool
Expand Down Expand Up @@ -88,7 +89,9 @@ func NewBuildCmd() *cobra.Command {
BuildEnvPolicy: BuildEnvPreserveOnFailure,
}

cmd := &cobra.Command{
var cmd *cobra.Command

cmd = &cobra.Command{
Use: "build",
Short: "Build packages for components",
Long: `Build RPM packages for one or more components using mock.
Expand Down Expand Up @@ -121,6 +124,7 @@ builds can consume.`,
azldev component build --local-repo-with-publish ./base/out -p liba -p libb`,
RunE: azldev.RunFuncWithExtraArgs(func(env *azldev.Env, args []string) (interface{}, error) {
options.ComponentFilter.ComponentNamePatterns = append(options.ComponentFilter.ComponentNamePatterns, args...)
options.SpecEditor = specEditorFromCommand(cmd)

return SelectAndBuildComponents(env, options)
}),
Expand Down Expand Up @@ -280,7 +284,10 @@ func buildComponent(

preparerOpts = append(preparerOpts, sources.WithMockProcessor(mockProcessor))

sourcePreparer, err := sources.NewPreparer(sourceManager, env.FS(), env, env, preparerOpts...)
sourcePreparer, err := sources.NewPreparer(sourceManager, env.FS(), env, env, append(
preparerOpts,
sources.WithSpecEditor(options.specEditorMode()),
)...)
if err != nil {
return ComponentBuildResults{},
fmt.Errorf("failed to create source preparer for component %q:\n%w", component.GetName(), err)
Expand Down
1 change: 1 addition & 0 deletions internal/app/azldev/cmds/component/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Use subcommands to add, list, query, build, and prepare sources for
components defined in the project configuration.`,
}

addSpecEditorOption(cmd)
app.AddTopLevelCommand(cmd)
addOnAppInit(app, cmd)
buildOnAppInit(app, cmd)
Expand Down
9 changes: 7 additions & 2 deletions internal/app/azldev/cmds/component/diffsources.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

// DiffSourcesOptions holds the options for the diff-sources command.
type DiffSourcesOptions struct {
componentCommandOptions
ComponentFilter components.ComponentFilter

OutputFile string
Expand All @@ -36,14 +37,17 @@ func diffSourcesOnAppInit(_ *azldev.App, parentCmd *cobra.Command) {
func NewDiffSourcesCmd() *cobra.Command {
var options DiffSourcesOptions

cmd := &cobra.Command{
var cmd *cobra.Command

cmd = &cobra.Command{
Use: "diff-sources",
Short: "Show the diff that overlays apply to a component's sources",
Long: `Computes a unified diff showing the changes that overlays apply to a
component's sources. Fetches the sources once, copies them, then applies
overlays to the copy and displays the resulting diff between the two trees.`,
RunE: azldev.RunFuncWithExtraArgs(func(env *azldev.Env, args []string) (interface{}, error) {
options.ComponentFilter.ComponentNamePatterns = append(args, options.ComponentFilter.ComponentNamePatterns...)
options.SpecEditor = specEditorFromCommand(cmd)

return DiffComponentSources(env, &options)
}),
Expand Down Expand Up @@ -98,7 +102,8 @@ func DiffComponentSources(env *azldev.Env, options *DiffSourcesOptions) (interfa
}

preparer, err := sources.NewPreparer(sourceManager, env.FS(), env, env,
sources.WithUpstreamProvenance(sources.FedoraDistTag(distro.Ref.Name, distro.Version.ReleaseVer)))
sources.WithUpstreamProvenance(sources.FedoraDistTag(distro.Ref.Name, distro.Version.ReleaseVer)),
sources.WithSpecEditor(options.specEditorMode()))
if err != nil {
return nil, fmt.Errorf("failed to create source preparer:\n%w", err)
}
Expand Down
11 changes: 9 additions & 2 deletions internal/app/azldev/cmds/component/preparesources.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
)

type PrepareSourcesOptions struct {
componentCommandOptions
ComponentFilter components.ComponentFilter

OutputDir string
Expand All @@ -34,7 +35,9 @@ func prepareOnAppInit(_ *azldev.App, sourceCmd *cobra.Command) {
func NewPrepareSourcesCmd() *cobra.Command {
var options PrepareSourcesOptions

cmd := &cobra.Command{
var cmd *cobra.Command

cmd = &cobra.Command{
Use: "prepare-sources",
Aliases: []string{"prep-sources"},
Short: "Prepare buildable sources for components",
Expand All @@ -53,6 +56,7 @@ Only one component may be selected at a time.`,
azldev component prep-sources -p curl -o ./build/work/scratch/curl --skip-overlays --force`,
RunE: azldev.RunFuncWithExtraArgs(func(env *azldev.Env, args []string) (interface{}, error) {
options.ComponentFilter.ComponentNamePatterns = append(args, options.ComponentFilter.ComponentNamePatterns...)
options.SpecEditor = specEditorFromCommand(cmd)

return nil, PrepareComponentSources(env, &options)
}),
Expand Down Expand Up @@ -132,7 +136,10 @@ func PrepareComponentSources(env *azldev.Env, options *PrepareSourcesOptions) er

preparerOpts := buildPreparerOptions(env, distro, options)

preparer, err := sources.NewPreparer(sourceManager, env.FS(), env, env, preparerOpts...)
preparer, err := sources.NewPreparer(sourceManager, env.FS(), env, env, append(
preparerOpts,
sources.WithSpecEditor(options.specEditorMode()),
)...)
if err != nil {
return fmt.Errorf("failed to create source preparer:\n%w", err)
}
Expand Down
21 changes: 15 additions & 6 deletions internal/app/azldev/cmds/component/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/microsoft/azure-linux-dev-tools/internal/app/azldev/core/sources"
"github.com/microsoft/azure-linux-dev-tools/internal/global/opctx"
"github.com/microsoft/azure-linux-dev-tools/internal/providers/sourceproviders"
"github.com/microsoft/azure-linux-dev-tools/internal/rpm/spec"
"github.com/microsoft/azure-linux-dev-tools/internal/utils/dirdiff"
"github.com/microsoft/azure-linux-dev-tools/internal/utils/fileperms"
"github.com/microsoft/azure-linux-dev-tools/internal/utils/fileutils"
Expand All @@ -29,6 +30,7 @@ import (

// RenderOptions holds the options for the render command.
type RenderOptions struct {
componentCommandOptions
ComponentFilter components.ComponentFilter
OutputDir string
OutputDirExplicit bool // True when --output-dir was explicitly passed on the CLI.
Expand Down Expand Up @@ -88,6 +90,7 @@ valid with -a.`,
RunE: azldev.RunFuncWithExtraArgs(func(env *azldev.Env, args []string) (interface{}, error) {
options.ComponentFilter.ComponentNamePatterns = append(args, options.ComponentFilter.ComponentNamePatterns...)
options.OutputDirExplicit = cmd.Flags().Changed("output-dir")
options.SpecEditor = specEditorFromCommand(cmd)

return RenderComponents(env, &options)
}),
Expand Down Expand Up @@ -204,7 +207,7 @@ func RenderComponents(env *azldev.Env, options *RenderOptions) ([]*RenderResult,
results := make([]*RenderResult, len(componentList))

// ── Phase 1: Parallel source preparation ──
prepared := parallelPrepare(env, mockProcessor, componentList, stagingDir, options.OutputDir, results)
prepared := parallelPrepare(env, mockProcessor, componentList, stagingDir, options, results)

// ── Phase 2: Batch mock processing ──
mockResultMap := batchMockProcess(env, mockProcessor, stagingDir, prepared)
Expand Down Expand Up @@ -386,7 +389,7 @@ func parallelPrepare(
mockProcessor *sources.MockProcessor,
comps []components.Component,
stagingDir string,
outputDir string,
options *RenderOptions,
results []*RenderResult,
) []*preparedComponent {
progressEvent := env.StartEvent("Preparing component sources", "count", len(comps))
Expand All @@ -406,7 +409,8 @@ func parallelPrepare(
// workerEnv (captured) is the effective context for this call chain;
// the parmap-supplied ctx is identical and unused here.
//nolint:contextcheck // env carries the ctx
return prepareOneComponent(workerEnv, mockProcessor, comp, stagingDir, outputDir)
return prepareOneComponent(
workerEnv, mockProcessor, comp, stagingDir, options.OutputDir, options.specEditorMode())
},
)

Expand All @@ -418,7 +422,7 @@ func parallelPrepare(
// Worker never started — ctx ended before parmap reached it.
compName := comps[idx].GetName()

compOutputDir, nameErr := components.RenderedSpecDir(outputDir, compName)
compOutputDir, nameErr := components.RenderedSpecDir(options.OutputDir, compName)
if nameErr != nil {
compOutputDir = "(invalid)"
}
Expand Down Expand Up @@ -453,6 +457,7 @@ func prepareOneComponent(
comp components.Component,
stagingDir string,
outputDir string,
specEditor spec.EditorMode,
) prepResult {
componentName := comp.GetName()

Expand All @@ -467,7 +472,7 @@ func prepareOneComponent(
}}
}

prep, err := prepareComponentSources(env, mockProcessor, comp, stagingDir)
prep, err := prepareComponentSources(env, mockProcessor, comp, stagingDir, specEditor)
if err != nil {
slog.Error("Failed to prepare component sources",
"component", componentName, "error", err)
Expand All @@ -493,6 +498,7 @@ func prepareComponentSources(
mockProcessor *sources.MockProcessor,
comp components.Component,
stagingDir string,
specEditor spec.EditorMode,
) (*preparedComponent, error) {
componentName := comp.GetName()

Expand Down Expand Up @@ -531,7 +537,10 @@ func prepareComponentSources(
sources.WithMockProcessor(mockProcessor),
}

preparer, err := sources.NewPreparer(sourceManager, env.FS(), env, env, preparerOpts...)
preparer, err := sources.NewPreparer(sourceManager, env.FS(), env, env, append(
preparerOpts,
sources.WithSpecEditor(specEditor),
)...)
if err != nil {
return nil, fmt.Errorf("creating source preparer for %#q:\n%w", componentName, err)
}
Expand Down
Loading
Loading