diff --git a/internal/pipe/chocolatey/nuspec.go b/internal/pipe/chocolatey/nuspec.go new file mode 100644 index 000000000000..85d6637ac785 --- /dev/null +++ b/internal/pipe/chocolatey/nuspec.go @@ -0,0 +1,87 @@ +package chocolatey + +import ( + "bytes" + "encoding/xml" + "strings" +) + +const schema = "http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd" + +// Nuspec represents a Nuget/Chocolatey Nuspec. +// More info: https://learn.microsoft.com/en-us/nuget/reference/nuspec +// https://docs.chocolatey.org/en-us/create/create-packages +type Nuspec struct { + XMLName xml.Name `xml:"package"` + Xmlns string `xml:"xmlns,attr,omitempty"` + Metadata Metadata `xml:"metadata"` + Files Files `xml:"files,omitempty"` +} + +// Metadata contains information about a single package. +type Metadata struct { + ID string `xml:"id"` + Version string `xml:"version"` + PackageSourceURL string `xml:"packageSourceUrl,omitempty"` + Owners string `xml:"owners,omitempty"` + Title string `xml:"title,omitempty"` + Authors string `xml:"authors"` + ProjectURL string `xml:"projectUrl,omitempty"` + IconURL string `xml:"iconUrl,omitempty"` + Copyright string `xml:"copyright,omitempty"` + LicenseURL string `xml:"licenseUrl,omitempty"` + RequireLicenseAcceptance bool `xml:"requireLicenseAcceptance"` + ProjectSourceURL string `xml:"projectSourceUrl,omitempty"` + DocsURL string `xml:"docsUrl,omitempty"` + BugTrackerURL string `xml:"bugTrackerUrl,omitempty"` + Tags string `xml:"tags,omitempty"` + Summary string `xml:"summary,omitempty"` + Description string `xml:"description"` + ReleaseNotes string `xml:"releaseNotes,omitempty"` + Dependencies *Dependencies `xml:"dependencies,omitempty"` +} + +// Dependency represents a dependency element. +type Dependency struct { + ID string `xml:"id,attr"` + Version string `xml:"version,attr,omitempty"` +} + +// Dependencies represents a collection zero or more dependency elements. +type Dependencies struct { + Dependency []Dependency `xml:"dependency"` +} + +// File represents a file to be copied. +type File struct { + Source string `xml:"src,attr"` + Target string `xml:"target,attr,omitempty"` +} + +// Files represents files that will be copied during packaging. +type Files struct { + File []File `xml:"file"` +} + +// Bytes marshals the Nuspec into XML format and return as []byte. +func (m *Nuspec) Bytes() ([]byte, error) { + b := &bytes.Buffer{} + b.WriteString(strings.ToLower(xml.Header)) + + enc := xml.NewEncoder(b) + enc.Indent("", " ") + + if err := enc.Encode(m); err != nil { + return nil, err + } + + out := b.Bytes() + + // Follows the nuget specification of self-closing xml tags. + tags := []string{"dependency", "file"} + for _, tag := range tags { + out = bytes.ReplaceAll(out, []byte(">"), []byte(" />")) + } + + return out, nil +} diff --git a/internal/pipe/chocolatey/nuspec_test.go b/internal/pipe/chocolatey/nuspec_test.go new file mode 100644 index 000000000000..3d51e0e1b57e --- /dev/null +++ b/internal/pipe/chocolatey/nuspec_test.go @@ -0,0 +1,45 @@ +package chocolatey + +import ( + "testing" + + "github.com/goreleaser/goreleaser/internal/golden" + "github.com/stretchr/testify/require" +) + +func TestNuspecBytes(t *testing.T) { + m := &Nuspec{ + Xmlns: schema, + Metadata: Metadata{ + ID: "goreleaser", + Version: "1.12.3", + PackageSourceURL: "https://github.com/goreleaser/goreleaser", + Owners: "caarlos0", + Title: "GoReleaser", + Authors: "caarlos0", + ProjectURL: "https://goreleaser.com/", + IconURL: "https://raw.githubusercontent.com/goreleaser/goreleaser/main/www/docs/static/avatar.png", + Copyright: "2016-2022 Carlos Alexandro Becker", + LicenseURL: "https://github.com/goreleaser/goreleaser/blob/main/LICENSE.md", + RequireLicenseAcceptance: true, + ProjectSourceURL: "https://github.com/goreleaser/goreleaser", + DocsURL: "https://github.com/goreleaser/goreleaser/blob/main/README.md", + BugTrackerURL: "https://github.com/goreleaser/goreleaser/issues", + Tags: "go docker homebrew golang package", + Summary: "Deliver Go binaries as fast and easily as possible", + Description: "GoReleaser builds Go binaries for several platforms, creates a GitHub release and then pushes a Homebrew formula to a tap repository. All that wrapped in your favorite CI.", + ReleaseNotes: "This tag is only to keep version parity with the pro version, which does have a couple of bugfixes.", + Dependencies: &Dependencies{Dependency: []Dependency{ + {ID: "nfpm", Version: "2.20.0"}, + }}, + }, + Files: Files{File: []File{ + {Source: "tools\\**", Target: "tools"}, + }}, + } + + out, err := m.Bytes() + require.NoError(t, err) + + golden.RequireEqualExt(t, out, ".nuspec") +} diff --git a/internal/pipe/chocolatey/testdata/TestNuspecBytes.nuspec.golden b/internal/pipe/chocolatey/testdata/TestNuspecBytes.nuspec.golden new file mode 100644 index 000000000000..029680975682 --- /dev/null +++ b/internal/pipe/chocolatey/testdata/TestNuspecBytes.nuspec.golden @@ -0,0 +1,29 @@ + + + + goreleaser + 1.12.3 + https://github.com/goreleaser/goreleaser + caarlos0 + GoReleaser + caarlos0 + https://goreleaser.com/ + https://raw.githubusercontent.com/goreleaser/goreleaser/main/www/docs/static/avatar.png + 2016-2022 Carlos Alexandro Becker + https://github.com/goreleaser/goreleaser/blob/main/LICENSE.md + true + https://github.com/goreleaser/goreleaser + https://github.com/goreleaser/goreleaser/blob/main/README.md + https://github.com/goreleaser/goreleaser/issues + go docker homebrew golang package + Deliver Go binaries as fast and easily as possible + GoReleaser builds Go binaries for several platforms, creates a GitHub release and then pushes a Homebrew formula to a tap repository. All that wrapped in your favorite CI. + This tag is only to keep version parity with the pro version, which does have a couple of bugfixes. + + + + + + + + \ No newline at end of file