Skip to content

Commit 3eb2d88

Browse files
authored
feat: add json support to config dump --format (#405)
* add json support to config dump * switch json marshalling to camelCase * make config dump command work as root * add comments explaining why we allow dump to be run as root
1 parent 808cbd3 commit 3eb2d88

15 files changed

Lines changed: 109 additions & 88 deletions

File tree

.golangci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ linters:
163163
tagliatelle:
164164
case:
165165
rules:
166-
json: goPascal
166+
json: camel
167167

168168
varnamelen:
169169
ignore-decls:

internal/app/azldev/cmds/component/build.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ type ComponentBuildOptions struct {
3333
// ComponentBuildResults summarizes the results of building a single component.
3434
type ComponentBuildResults struct {
3535
// Names of the component that was built.
36-
ComponentName string `json:"ComponentName"`
36+
ComponentName string `json:"componentName"`
3737

3838
// Absolute paths to any source RPMs built by the operation.
39-
SRPMPaths []string `json:"SrpmPaths" table:"SRPM Paths"`
39+
SRPMPaths []string `json:"srpmPaths" table:"SRPM Paths"`
4040

4141
// Absolute paths to any RPMs built by the operation.
42-
RPMPaths []string `json:"RpmPaths" table:"RPM Paths"`
42+
RPMPaths []string `json:"rpmPaths" table:"RPM Paths"`
4343
}
4444

4545
func buildOnAppInit(_ *azldev.App, parent *cobra.Command) {

internal/app/azldev/cmds/config/dump.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package config
55

66
import (
7+
"encoding/json"
78
"fmt"
89

910
"github.com/gim-home/azldev-preview/internal/app/azldev"
@@ -16,6 +17,7 @@ type configDumpFormat string
1617

1718
const (
1819
ConfigDumpFormatTOML configDumpFormat = "toml"
20+
ConfigDumpFormatJSON configDumpFormat = "json"
1921
)
2022

2123
// Assert that ConfigDumpFormat implements the [pflag.Value] interface.
@@ -30,6 +32,8 @@ func (f *configDumpFormat) Set(value string) error {
3032
switch value {
3133
case "toml":
3234
*f = ConfigDumpFormatTOML
35+
case "json":
36+
*f = ConfigDumpFormatJSON
3337
default:
3438
return fmt.Errorf("unsupported format: %#q", value)
3539
}
@@ -63,9 +67,15 @@ func newDumpCmd() *cobra.Command {
6367

6468
return "", nil
6569
}),
70+
// Allowing 'config dump' to be run as root for two reasons:
71+
// 1. It doesn't modify anything -- even as root it's safe.
72+
// 2. There are container-based scenarios where the default user is root.
73+
Annotations: map[string]string{
74+
azldev.CommandAnnotationRootOK: "true",
75+
},
6676
}
6777

68-
cmd.Flags().VarP(&configDumpFormat, "format", "f", "Output format")
78+
cmd.Flags().VarP(&configDumpFormat, "format", "f", "Output format {json, toml}")
6979

7080
azldev.ExportAsMCPTool(cmd)
7181

@@ -81,6 +91,13 @@ func DumpConfig(env *azldev.Env, format configDumpFormat) (string, error) {
8191
}
8292

8393
return string(tomlBytes), nil
94+
case ConfigDumpFormatJSON:
95+
jsonBytes, err := json.MarshalIndent(env.Config(), "", " ")
96+
if err != nil {
97+
return "", fmt.Errorf("failed to serialize config to JSON:\n%w", err)
98+
}
99+
100+
return string(jsonBytes), nil
84101
default:
85102
return "", fmt.Errorf("unsupported format: %#q", format)
86103
}

internal/app/azldev/cmds/config/dump_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,8 @@ func TestDumpConfig(t *testing.T) {
4747
configText, err := config.DumpConfig(env, config.ConfigDumpFormatTOML)
4848
require.NoError(t, err)
4949
require.NotEmpty(t, configText)
50+
51+
configText, err = config.DumpConfig(env, config.ConfigDumpFormatJSON)
52+
require.NoError(t, err)
53+
require.NotEmpty(t, configText)
5054
}

internal/app/azldev/cmds/version/version.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ func OnAppInit(app *azldev.App) {
1717

1818
// VersionInfo represents the version information structure.
1919
type VersionInfo struct {
20-
Version string `json:"Version"`
21-
GitCommit string `json:"GitCommit"`
22-
GoVersion string `json:"GoVersion"`
23-
Platform string `json:"Platform"`
24-
Compiler string `json:"Compiler"`
25-
BuildDate string `json:"BuildDate"`
26-
CommitDate string `json:"CommitDate"`
27-
DirtyBuild bool `json:"DirtyBuild"`
20+
Version string `json:"version"`
21+
GitCommit string `json:"gitCommit"`
22+
GoVersion string `json:"goVersion"`
23+
Platform string `json:"platform"`
24+
Compiler string `json:"compiler"`
25+
BuildDate string `json:"buildDate"`
26+
CommitDate string `json:"commitDate"`
27+
DirtyBuild bool `json:"dirtyBuild"`
2828
}
2929

3030
// NewVersionCmd creates a custom version command that respects the global -O flag.

internal/app/azldev/cmds/version/version_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ func TestVersionCmd_JSONOutput(t *testing.T) {
4141

4242
// Verify JSON output
4343
output := reportOutput.String()
44-
assert.Contains(t, output, `"Version"`)
45-
assert.Contains(t, output, `"GitCommit"`)
46-
assert.Contains(t, output, `"GoVersion"`)
47-
assert.Contains(t, output, `"Platform"`)
48-
assert.Contains(t, output, `"Compiler"`)
49-
assert.Contains(t, output, `"BuildDate"`)
50-
assert.Contains(t, output, `"CommitDate"`)
51-
assert.Contains(t, output, `"DirtyBuild"`)
44+
assert.Contains(t, output, `"version"`)
45+
assert.Contains(t, output, `"gitCommit"`)
46+
assert.Contains(t, output, `"goVersion"`)
47+
assert.Contains(t, output, `"platform"`)
48+
assert.Contains(t, output, `"compiler"`)
49+
assert.Contains(t, output, `"buildDate"`)
50+
assert.Contains(t, output, `"commitDate"`)
51+
assert.Contains(t, output, `"dirtyBuild"`)
5252
}
5353

5454
func TestGetVersionInfo(t *testing.T) {

internal/buildenv/buildenv.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,25 +110,25 @@ func (f *EnvType) Type() string {
110110
// BuildEnvInfo is a simple data structure that contains information about a [BuildEnv].
111111
type BuildEnvInfo struct {
112112
// Name is the human-readable name moniker for the build environment.
113-
Name string `json:"Name"`
113+
Name string `json:"name"`
114114

115115
// UserCreated indicates whether the build environment was created on behalf of a direct user request.
116116
// If this is false, the build environment was created automatically as part of a larger operation.
117-
UserCreated bool `json:"UserCreated"`
117+
UserCreated bool `json:"userCreated"`
118118

119119
// Type is the type of build environment. This is used to determine which technology can be used
120120
// to interact with the build environment.
121-
Type EnvType `json:"Type"`
121+
Type EnvType `json:"type"`
122122

123123
// CreationTime is the time when the build environment was created. This can be useful for users to
124124
// better understanding their environments.
125-
CreationTime time.Time `json:"CreationTime"`
125+
CreationTime time.Time `json:"creationTime"`
126126

127127
// Dir is the directory under which the build environment's files are stored.
128-
Dir string `json:"Dir"`
128+
Dir string `json:"dir"`
129129

130130
// Description optionally provides a human-readable description of the environment's purpose.
131-
Description string `json:"Description"`
131+
Description string `json:"description"`
132132
}
133133

134134
func (i *BuildEnvInfo) Serialize() (data []byte, err error) {

internal/projectconfig/build.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ package projectconfig
77
// or prepare the sources for a component are out of scope.
88
type ComponentBuildConfig struct {
99
// Which features should be enabled via `with` options to the builder.
10-
With []string `toml:"with,omitempty" json:",omitempty" jsonschema:"title=With options,description='with' options to pass to the builder."`
10+
With []string `toml:"with,omitempty" json:"with,omitempty" jsonschema:"title=With options,description='with' options to pass to the builder."`
1111
// Which features should be disabled via `without` options to the builder.
12-
Without []string `toml:"without,omitempty" json:",omitempty" jsonschema:"title=Without options,description='without' options to pass to the builder."`
12+
Without []string `toml:"without,omitempty" json:"without,omitempty" jsonschema:"title=Without options,description='without' options to pass to the builder."`
1313
// Macro definitions.
14-
Defines map[string]string `toml:"defines,omitempty" json:",omitempty" jsonschema:"title=Macro definitions,description=Macro definitions to pass to the builder."`
14+
Defines map[string]string `toml:"defines,omitempty" json:"defines,omitempty" jsonschema:"title=Macro definitions,description=Macro definitions to pass to the builder."`
1515
}

internal/projectconfig/component.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,21 @@ const (
4343
// Origin represents a single source location with its type and configuration.
4444
type Origin struct {
4545
// Type of source: "url", "github", "local", "blobstore"
46-
Type OriginType `toml:"Type" json:"Type"`
46+
Type OriginType `toml:"Type" json:"type"`
4747

4848
// Location - interpretation depends on Type:
4949
// - "url": the full URL
5050
// - "local": relative or absolute path
51-
Location string `toml:"Location,omitempty" json:"Location,omitempty"`
51+
Location string `toml:"Location,omitempty" json:"location,omitempty"`
5252

5353
// Optional: Script for generated files
54-
Script string `toml:"Script,omitempty" json:"Script,omitempty"`
54+
Script string `toml:"Script,omitempty" json:"script,omitempty"`
5555

5656
// Optional: Additional arguments specific to the origin type
5757
// Examples:
5858
// - GitHub: {"release": "v1.2.3", "asset": "foo.tar.gz"}
5959
// - Generated: {"arg1": "value1", "arg2": "value2"} (passed as --arg1=value1)
60-
Args []string `toml:"Args,omitempty" json:"Args,omitempty"`
60+
Args []string `toml:"Args,omitempty" json:"args,omitempty"`
6161
}
6262

6363
// SourceFileReference encapsulates a reference to a specific source file artifact.
@@ -69,13 +69,13 @@ type SourceFileReference struct {
6969
Filename string `toml:"-" json:"-"`
7070

7171
// Hash of the source file, expressed as a hex string.
72-
Hash string `toml:"Hash,omitempty" json:"Hash,omitempty"`
72+
Hash string `toml:"Hash,omitempty" json:"hash,omitempty"`
7373

7474
// Type of hash used by `Hash` (if present).
75-
HashType fileutils.HashType `toml:"HashType,omitempty" json:"HashType,omitempty"`
75+
HashType fileutils.HashType `toml:"HashType,omitempty" json:"hashType,omitempty"`
7676

7777
// Ordered list of source origins to try in priority order
78-
Origins []Origin `toml:"Origins,omitempty" json:"Origins,omitempty"`
78+
Origins []Origin `toml:"Origins,omitempty" json:"origins,omitempty"`
7979
}
8080

8181
// Defines a component group. Component groups are logical groupings of components (see [ComponentConfig]).
@@ -84,9 +84,9 @@ type SourceFileReference struct {
8484
// component may belong to multiple groups, and components need not belong to any group.
8585
type ComponentGroupConfig struct {
8686
// List of glob patterns specifying raw spec files that define components.
87-
SpecPathPatterns []string `toml:"specs,omitempty" validate:"dive,required" jsonschema:"title=Spec path patterns,description=List of glob patterns identifying local specs for components in this group,example=SPECS/**/.spec"`
87+
SpecPathPatterns []string `toml:"specs,omitempty" json:"specs,omitempty" validate:"dive,required" jsonschema:"title=Spec path patterns,description=List of glob patterns identifying local specs for components in this group,example=SPECS/**/.spec"`
8888
// List of glob patterns specifying files to specifically ignore from spec selection.
89-
ExcludedPathPatterns []string `toml:"excluded-paths,omitempty" jsonschema:"title=Excluded path patterns,description=List of glob patterns identifying local paths to exclude from spec selection,example=build/**"`
89+
ExcludedPathPatterns []string `toml:"excluded-paths,omitempty" json:"excludedPaths,omitempty" jsonschema:"title=Excluded path patterns,description=List of glob patterns identifying local paths to exclude from spec selection,example=build/**"`
9090
}
9191

9292
// Returns a copy of the component group config with relative file paths converted to absolute
@@ -114,20 +114,20 @@ func (g ComponentGroupConfig) WithAbsolutePaths(referenceDir string) ComponentGr
114114
// Defines a component.
115115
type ComponentConfig struct {
116116
// The component's name; not actually present in serialized files.
117-
Name string `toml:"-" table:",sortkey"`
117+
Name string `toml:"-" json:"-" table:",sortkey"`
118118

119119
// Reference to the source config file that this definition came from; not present
120120
// in serialized files.
121121
SourceConfigFile *ConfigFile `toml:"-" json:"-" table:"-"`
122122

123123
// Where to get its spec and adjacent files from.
124-
Spec SpecSource `toml:"spec,omitempty" json:",omitempty" jsonschema:"title=Spec,description=Identifies where to find the spec for this component"`
124+
Spec SpecSource `toml:"spec,omitempty" json:"spec,omitempty" jsonschema:"title=Spec,description=Identifies where to find the spec for this component"`
125125

126126
// Overlays to apply to sources after they've been acquired. May mutate the spec as well as sources.
127-
Overlays []ComponentOverlay `toml:"overlays,omitempty" json:",omitempty" table:"-" jsonschema:"title=Overlays,description=Overlays to apply to this component's spec and/or sources"`
127+
Overlays []ComponentOverlay `toml:"overlays,omitempty" json:"overlays,omitempty" table:"-" jsonschema:"title=Overlays,description=Overlays to apply to this component's spec and/or sources"`
128128

129129
// Configuration for building the component.
130-
Build ComponentBuildConfig `toml:"build,omitempty" json:",omitempty" table:"-" jsonschema:"title=Build configuration,description=Configuration for building the component"`
130+
Build ComponentBuildConfig `toml:"build,omitempty" json:"build,omitempty" table:"-" jsonschema:"title=Build configuration,description=Configuration for building the component"`
131131
}
132132

133133
// Mutates the component config, updating it with overrides present in other.

internal/projectconfig/distro.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ import (
1212
// Encapsulates a reference to a version of a distro.
1313
type DistroReference struct {
1414
// Name of the referenced distro.
15-
Name string `toml:"name" jsonschema:"required,title=Name,description=Name of the referenced distro"`
15+
Name string `toml:"name" json:"name,omitempty" jsonschema:"required,title=Name,description=Name of the referenced distro"`
1616
// Version of the referenced distro.
17-
Version string `toml:"version,omitempty" json:",omitempty" jsonschema:"title=Version,description=Version of the referenced distro"`
17+
Version string `toml:"version,omitempty" json:"version,omitempty" jsonschema:"title=Version,description=Version of the referenced distro"`
1818
}
1919

2020
// Implements the [Stringer] interface for [DistroReference].
@@ -35,47 +35,47 @@ func (r *DistroReference) String() string {
3535
// Defines a distro that components may be built for/against.
3636
type DistroDefinition struct {
3737
// Human-readable description of the distro.
38-
Description string `toml:"description,omitempty" jsonschema:"title=Description,description=Human readable description"`
38+
Description string `toml:"description,omitempty" json:"description,omitempty" jsonschema:"title=Description,description=Human readable description"`
3939

4040
// Optionally provides a default version to use for this distro when one is not explicitly specified.
41-
DefaultVersion string `toml:"default-version,omitempty" jsonschema:"title=Default version,description=Default version for this distro"`
41+
DefaultVersion string `toml:"default-version,omitempty" json:"defaultVersion,omitempty" jsonschema:"title=Default version,description=Default version for this distro"`
4242

4343
// The base URI of this distro's dist-git spec source repository.
44-
DistGitBaseURI string `toml:"dist-git-base-uri,omitempty" jsonschema:"format=uri,title=Dist-git base URI,description=Base URI for the dist-git repository for this distro"`
44+
DistGitBaseURI string `toml:"dist-git-base-uri,omitempty" json:"distGitBaseUri,omitempty" jsonschema:"format=uri,title=Dist-git base URI,description=Base URI for the dist-git repository for this distro"`
4545

4646
// The base URI of this distro's lookaside cache for source archives.
47-
LookasideBaseURI string `toml:"lookaside-base-uri,omitempty" jsonschema:"format=uri,title=Lookaside base URI,description=Base URI for lookaside cache for this distro"`
47+
LookasideBaseURI string `toml:"lookaside-base-uri,omitempty" json:"lookasideBaseUri,omitempty" jsonschema:"format=uri,title=Lookaside base URI,description=Base URI for lookaside cache for this distro"`
4848

4949
// Published artifact information
50-
PackageRepositories []PackageRepository `toml:"repos,omitempty" jsonschema:"title=Package Repositories,description=List of package repository definitions"`
50+
PackageRepositories []PackageRepository `toml:"repos,omitempty" json:"repos,omitempty" jsonschema:"title=Package Repositories,description=List of package repository definitions"`
5151

5252
// Versions: maps version => definition
53-
Versions map[string]DistroVersionDefinition `toml:"versions,omitempty" jsonschema:"title=Versions,description=Mapping of distro version definitions"`
53+
Versions map[string]DistroVersionDefinition `toml:"versions,omitempty" json:"versions,omitempty" jsonschema:"title=Versions,description=Mapping of distro version definitions"`
5454
}
5555

5656
// Defines how to access the published repository for a distro.
5757
type PackageRepository struct {
58-
BaseURI string `toml:"base-uri" jsonschema:"required,title=Base URI,description=Base URI for the repository"`
58+
BaseURI string `toml:"base-uri" json:"baseUri" jsonschema:"required,title=Base URI,description=Base URI for the repository"`
5959
}
6060

6161
// Defines a specific version of a distro.
6262
type DistroVersionDefinition struct {
6363
// Human-readable description of this version
64-
Description string `toml:"description,omitempty" jsonschema:"title=Description,description=Human readable description of the distro version"`
64+
Description string `toml:"description,omitempty" json:"description,omitempty" jsonschema:"title=Description,description=Human readable description of the distro version"`
6565

6666
// Formal `releasever` for this version.
67-
ReleaseVer string `toml:"release-ver" jsonschema:"title=Release version,description=Formal releasever string"`
67+
ReleaseVer string `toml:"release-ver" json:"releaseVer,omitempty" jsonschema:"title=Release version,description=Formal releasever string"`
6868

6969
// Dist-git branch for this version (if applicable)
70-
DistGitBranch string `toml:"dist-git-branch,omitempty" jsonschema:"title=Dist-git branch,description=Branch in the dist-git repository for this version"`
70+
DistGitBranch string `toml:"dist-git-branch,omitempty" json:"distGitBranch,omitempty" jsonschema:"title=Dist-git branch,description=Branch in the dist-git repository for this version"`
7171

7272
// Default config for components.
73-
DefaultComponentConfig ComponentConfig `toml:"default-component-config,omitempty" jsonschema:"title=Default component config,description=Default component config inherited by all components built for this distro"`
73+
DefaultComponentConfig ComponentConfig `toml:"default-component-config,omitempty" json:"defaultComponentConfig,omitempty" jsonschema:"title=Default component config,description=Default component config inherited by all components built for this distro"`
7474

7575
// Path to mock configuration file for this project (if one exists).
76-
MockConfigPath string `toml:"mock-config,omitempty" validate:"omitempty,filepath" jsonschema:"title=Mock config file,description=Path to the mock config file for this version"`
77-
MockConfigPathX86_64 string `toml:"mock-config-x86_64,omitempty" validate:"omitempty,filepath" jsonschema:"title=Mock config file,description=Path to the x86_64 mock config file for this version"`
78-
MockConfigPathAarch64 string `toml:"mock-config-aarch64,omitempty" validate:"omitempty,filepath" jsonschema:"title=Mock config file,description=Path to the aarch64 mock config file for this version"`
76+
MockConfigPath string `toml:"mock-config,omitempty" json:"mockConfig,omitempty" validate:"omitempty,filepath" jsonschema:"title=Mock config file,description=Path to the mock config file for this version"`
77+
MockConfigPathX86_64 string `toml:"mock-config-x86_64,omitempty" json:"mockConfigX8664,omitempty" validate:"omitempty,filepath" jsonschema:"title=Mock config file,description=Path to the x86_64 mock config file for this version"`
78+
MockConfigPathAarch64 string `toml:"mock-config-aarch64,omitempty" json:"mockConfigAarch64,omitempty" validate:"omitempty,filepath" jsonschema:"title=Mock config file,description=Path to the aarch64 mock config file for this version"`
7979
}
8080

8181
// Returns a copy of the distro definition with relative file paths converted to absolute

0 commit comments

Comments
 (0)