1
1
Fork 0
mirror of https://github.com/goreleaser/nfpm synced 2024-04-26 20:05:46 +02:00

feat: overhaul cmd and release process (#325)

This commit is contained in:
Carlos Alexandro Becker 2021-04-23 09:29:19 -03:00 committed by GitHub
parent fe1413c7af
commit c39b8ba060
Signed by: GitHub
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 685 additions and 243 deletions

3
.gitignore vendored
View File

@ -12,4 +12,5 @@ coverage.out
/nfpm
www/site
.idea/
testdata/acceptance/tmp/
testdata/acceptance/tmp/
completions/

View File

@ -1,9 +1,9 @@
env:
- GO111MODULE=on
- GOPROXY=https://gocenter.io
before:
hooks:
- go mod tidy
- go mod tidy
- ./scripts/completions.sh
gomod:
proxy: true
builds:
@ -17,14 +17,17 @@ builds:
goarch:
- amd64
- arm64
mod_timestamp: '{{ .CommitTimestamp }}'
flags:
- -trimpath
ldflags:
- -s -w -X main.version={{ .Version }} -X main.commit={{ .Commit }} -X main.date={{ .CommitDate }} -X main.builtBy=goreleaser
dockers:
- image_templates:
- 'goreleaser/nfpm:{{ .Tag }}-amd64'
- 'ghcr.io/goreleaser/nfpm:{{ .Tag }}-amd64'
dockerfile: Dockerfile
use_buildx: true
binaries:
- nfpm
build_flag_templates:
- "--pull"
- "--label=org.opencontainers.image.created={{.Date}}"
@ -38,8 +41,6 @@ dockers:
- 'ghcr.io/goreleaser/nfpm:{{ .Tag }}-arm64v8'
dockerfile: Dockerfile
use_buildx: true
binaries:
- nfpm
build_flag_templates:
- "--pull"
- "--label=org.opencontainers.image.created={{.Date}}"
@ -77,19 +78,31 @@ archives:
windows: Windows
386: i386
amd64: x86_64
format_overrides:
- goos: windows
format: zip
files:
- README.md
- LICENSE.md
- completions/*
brews:
- tap:
owner: goreleaser
name: homebrew-tap
folder: Formula
homepage: https://github.com/goreleaser/nfpm
description: nFPM is not FPM
description: NFPM is a simple, 0-dependencies, deb, rpm and apk packager.
test: |
system "#{bin}/nfpm -v"
install: |-
bin.install "nfpm"
bash_completion.install "completions/nfpm.bash" => "nfpm"
zsh_completion.install "completions/nfpm.zsh" => "_nfpm"
fish_completion.install "completions/nfpm.fish"
nfpms:
- file_name_template: '{{ .ProjectName }}_{{ .Arch }}'
homepage: https://github.com/goreleaser/nfpm
description: nFPM is not FPM
description: NFPM is a simple, 0-dependencies, deb, rpm and apk packager.
maintainer: Carlos Alexandro Becker <root@carlosbecker.com>
license: MIT
vendor: GoReleaser
@ -97,10 +110,19 @@ nfpms:
- apk
- deb
- rpm
contents:
- src: ./completions/nfpm.bash
dst: /etc/bash_completion.d/nfpm
- src: ./completions/nfpm.fish
dst: /usr/share/fish/completions/nfpm.fish
- src: ./completions/nfpm.zsh
dst: /usr/local/share/zsh/site-functions/_nfpm
scoop:
bucket:
owner: goreleaser
name: scoop-bucket
homepage: https://goreleaser.com
description: Deliver Go binaries as fast and easily as possible
description: NFPM is a simple, 0-dependencies, deb, rpm and apk packager.
license: MIT
release:
discussion_category_name: "New Releases"

View File

@ -1,3 +1,4 @@
FROM alpine
COPY nfpm /usr/local/bin/nfpm
COPY nfpm_*.apk /tmp/
RUN apk add --allow-untrusted /tmp/nfpm_*.apk
ENTRYPOINT ["/usr/local/bin/nfpm"]

View File

@ -1,7 +1,7 @@
<p align="center">
<img alt="GoReleaser Logo" src="https://avatars2.githubusercontent.com/u/24697112?v=3&s=200" height="140" />
<h3 align="center">NFPM</h3>
<p align="center">NFPM is Not FPM - a simple deb, rpm and apk packager written in Go.</p>
<p align="center">NFPM is a simple, 0-dependencies, deb, rpm and apk packager.</p>
<p align="center">
<a href="https://github.com/goreleaser/nfpm/releases/latest"><img alt="Release" src="https://img.shields.io/github/release/goreleaser/nfpm.svg?style=for-the-badge"></a>
<a href="/LICENSE.md"><img alt="Software License" src="https://img.shields.io/badge/license-MIT-brightgreen.svg?style=for-the-badge"></a>

View File

@ -1,21 +1,11 @@
// Package main contains the main nfpm cli source code.
package main
import (
"errors"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"runtime/debug"
"github.com/alecthomas/kingpin"
"github.com/goreleaser/nfpm/v2"
_ "github.com/goreleaser/nfpm/v2/apk"
_ "github.com/goreleaser/nfpm/v2/deb"
_ "github.com/goreleaser/nfpm/v2/rpm"
"github.com/goreleaser/nfpm/v2/internal/cmd"
)
// nolint: gochecknoglobals
@ -24,40 +14,14 @@ var (
commit = ""
date = ""
builtBy = ""
app = kingpin.New("nfpm", "not-fpm packages apps in some formats")
config = app.Flag("config", "config file").
Default("nfpm.yaml").
Short('f').
String()
pkgCmd = app.Command("pkg", "package based on the config file").Alias("package")
target = pkgCmd.Flag("target", "where to save the generated package (filename, folder or blank for current folder)").
Default("").
Short('t').
String()
packager = pkgCmd.Flag("packager", "which packager implementation to use").
Short('p').
Enum("deb", "rpm", "apk")
initCmd = app.Command("init", "create an empty config file")
)
func main() {
app.Version(buildVersion(version, commit, date, builtBy))
app.VersionFlag.Short('v')
app.HelpFlag.Short('h')
switch kingpin.MustParse(app.Parse(os.Args[1:])) {
case initCmd.FullCommand():
if err := initFile(*config); err != nil {
kingpin.Fatalf(err.Error())
}
fmt.Printf("created config file from example: %s\n", *config)
case pkgCmd.FullCommand():
if err := doPackage(*config, *target, *packager); err != nil {
kingpin.Fatalf(err.Error())
}
}
cmd.Execute(
buildVersion(version, commit, date, builtBy),
os.Exit,
os.Args[1:],
)
}
func buildVersion(version, commit, date, builtBy string) string {
@ -76,131 +40,3 @@ func buildVersion(version, commit, date, builtBy string) string {
}
return result
}
func initFile(config string) error {
return ioutil.WriteFile(config, []byte(example), 0o600)
}
var errInsufficientParams = errors.New("a packager must be specified if target is a directory or blank")
// nolint:funlen
func doPackage(configPath, target, packager string) error {
targetIsADirectory := false
stat, err := os.Stat(target)
if err == nil && stat.IsDir() {
targetIsADirectory = true
}
if packager == "" {
ext := filepath.Ext(target)
if targetIsADirectory || ext == "" {
return errInsufficientParams
}
packager = ext[1:]
fmt.Println("guessing packager from target file extension...")
}
config, err := nfpm.ParseFile(configPath)
if err != nil {
return err
}
info, err := config.Get(packager)
if err != nil {
return err
}
info = nfpm.WithDefaults(info)
if err = nfpm.Validate(info); err != nil {
return err
}
fmt.Printf("using %s packager...\n", packager)
pkg, err := nfpm.Get(packager)
if err != nil {
return err
}
if target == "" {
// if no target was specified create a package in
// current directory with a conventional file name
target = pkg.ConventionalFileName(info)
} else if targetIsADirectory {
// if a directory was specified as target, create
// a package with conventional file name there
target = path.Join(target, pkg.ConventionalFileName(info))
}
f, err := os.Create(target)
if err != nil {
return err
}
info.Target = target
err = pkg.Package(info, f)
_ = f.Close()
if err != nil {
os.Remove(target)
return err
}
fmt.Printf("created package: %s\n", target)
return nil
}
const example = `# nfpm example config file
#
# check https://nfpm.goreleaser.com/configuration for detailed usage
#
name: "foo"
arch: "amd64"
platform: "linux"
version: "v1.0.0"
section: "default"
priority: "extra"
replaces:
- foobar
provides:
- bar
depends:
- foo
- bar
recommends:
- whatever
suggests:
- something-else
conflicts:
- not-foo
- not-bar
maintainer: "John Doe <john@example.com>"
description: |
FooBar is the great foo and bar software.
And this can be in multiple lines!
vendor: "FooBarCorp"
homepage: "http://example.com"
license: "MIT"
changelog: "changelog.yaml"
contents:
- src: ./foo
dst: /usr/local/bin/foo
- src: ./bar
dst: /usr/local/bin/bar
- src: ./foobar.conf
dst: /etc/foobar.conf
type: config
- src: /usr/local/bin/foo
dst: /sbin/foo
type: symlink
overrides:
rpm:
scripts:
preinstall: ./scripts/preinstall.sh
postremove: ./scripts/postremove.sh
deb:
scripts:
postinstall: ./scripts/postinstall.sh
preremove: ./scripts/preremove.sh
`

4
go.mod
View File

@ -8,9 +8,6 @@ require (
github.com/Masterminds/semver/v3 v3.1.1
github.com/ProtonMail/go-crypto v0.0.0-20210408094314-bf0c5240ed99
github.com/ProtonMail/gopenpgp/v2 v2.1.7
github.com/alecthomas/kingpin v2.2.6+incompatible
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb
github.com/go-git/go-git/v5 v5.3.0 // indirect
github.com/google/go-cmp v0.5.4 // indirect
@ -24,6 +21,7 @@ require (
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 // indirect
github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b
github.com/sergi/go-diff v1.2.0 // indirect
github.com/spf13/cobra v1.1.1
github.com/stretchr/testify v1.7.0
github.com/ulikunitz/xz v0.5.9 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect

14
go.sum
View File

@ -39,14 +39,8 @@ github.com/ProtonMail/gopenpgp/v2 v2.1.7 h1:6cDDCuHwC/DhRLsj0+w6e5taxtA48hpd1ZFK
github.com/ProtonMail/gopenpgp/v2 v2.1.7/go.mod h1:mjMvRMlOlBhNuaa3z0xOmEgAkba/Mu1Z8uWwYj4/6Ws=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
github.com/alecthomas/kingpin v2.2.6+incompatible h1:5svnBTFgJjZvGKyYBtMB0+m5wvrbUHiqye8wRJMlnYI=
github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
@ -71,6 +65,7 @@ github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -126,8 +121,6 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/rpmpack v0.0.0-20201225075926-0a97c2c4b688 h1:jyGRCFMyDK/gKe6QRZQWci5+wEUBFElvxLHs3iwO3hY=
github.com/google/rpmpack v0.0.0-20201225075926-0a97c2c4b688/go.mod h1:+y9lKiqDhR4zkLl+V9h4q0rdyrYVsWWm6LLCQP33DIk=
github.com/google/rpmpack v0.0.0-20210410105602-e20c988a6f5a h1:XC048Fc/OB2rUl/BxruopEl2u/EP6cJNFveVxI1cvdk=
github.com/google/rpmpack v0.0.0-20210410105602-e20c988a6f5a/go.mod h1:+y9lKiqDhR4zkLl+V9h4q0rdyrYVsWWm6LLCQP33DIk=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@ -170,6 +163,7 @@ github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
@ -248,6 +242,7 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b h1:+gCnWOZV8Z/8jehJ2CdqB47Z3S+SREmQcuXkRFLNsiI=
@ -256,6 +251,7 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
@ -269,10 +265,12 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B
github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4=
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=

View File

@ -0,0 +1,74 @@
package cmd
import "github.com/spf13/cobra"
type completionCmd struct {
cmd *cobra.Command
}
func newCompletionCmd() *completionCmd {
root := &completionCmd{}
cmd := &cobra.Command{
Use: "completion [bash|zsh|fish]",
Short: "Prints shell autocompletion scripts for NFPM",
Long: `Allows you to setup your shell to completions NFPM commands and flags.
#### Bash
$ source <(nfpm completion bash)
To load completions for each session, execute once:
##### Linux
$ nfpm completion bash > /etc/bash_completion.d/nfpm
##### MacOS
$ nfpm completion bash > /usr/local/etc/bash_completion.d/nfpm
#### ZSH
If shell completion is not already enabled in your environment you will need to enable it.
You can execute the following once:
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
To load completions for each session, execute once:
$ nfpm completion zsh > "${fpath[1]}/_nfpm"
You will need to start a new shell for this setup to take effect.
#### Fish
$ nfpm completion fish | source
To load completions for each session, execute once:
$ nfpm completion fish > ~/.config/fish/completions/nfpm.fish
**NOTE**: If you are using an official nfpm package, it should setup completions for you out of the box.
`,
SilenceUsage: true,
DisableFlagsInUseLine: true,
ValidArgs: []string{"bash", "zsh", "fish"},
Args: cobra.ExactValidArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
var err error
switch args[0] {
case "bash":
err = cmd.Root().GenBashCompletion(cmd.OutOrStdout())
case "zsh":
err = cmd.Root().GenZshCompletion(cmd.OutOrStdout())
case "fish":
err = cmd.Root().GenFishCompletion(cmd.OutOrStdout(), true)
}
return err
},
}
root.cmd = cmd
return root
}

View File

@ -0,0 +1,25 @@
package cmd
import (
"bytes"
"testing"
"github.com/stretchr/testify/require"
)
func TestCompletionGeneration(t *testing.T) {
for _, shell := range []string{"bash", "zsh", "fish"} {
t.Run(shell, func(t *testing.T) {
completionCmd := newCompletionCmd().cmd
stdout := bytes.NewBufferString("")
stderr := bytes.NewBufferString("")
completionCmd.SetOut(stdout)
completionCmd.SetErr(stderr)
completionCmd.SetArgs([]string{shell})
err := completionCmd.Execute()
require.NoError(t, err, shell+" arg experienced error with nfpm completion:\n"+stderr.String())
require.Equal(t, "", stderr.String(), shell+" arg experienced error with nfpm completion:\n"+stderr.String())
require.NotEmpty(t, stdout.String(), shell+" arg reported nothing to stdout with nfpm completion")
})
}
}

2
internal/cmd/doc.go Normal file
View File

@ -0,0 +1,2 @@
// Package cmd contains the main nfpm cli source code.
package cmd

35
internal/cmd/docs.go Normal file
View File

@ -0,0 +1,35 @@
package cmd
import (
"strings"
"github.com/spf13/cobra"
"github.com/spf13/cobra/doc"
)
type docsCmd struct {
cmd *cobra.Command
}
func newDocsCmd() *docsCmd {
root := &docsCmd{}
cmd := &cobra.Command{
Use: "docs",
Short: "Generates NFPM's command line docs",
SilenceUsage: true,
DisableFlagsInUseLine: true,
Hidden: true,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
root.cmd.Root().DisableAutoGenTag = true
return doc.GenMarkdownTreeCustom(root.cmd.Root(), "www/docs/cmd", func(_ string) string {
return ""
}, func(s string) string {
return "/cmd/" + strings.TrimSuffix(s, ".md")
})
},
}
root.cmd = cmd
return root
}

90
internal/cmd/init.go Normal file
View File

@ -0,0 +1,90 @@
package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
)
type initCmd struct {
cmd *cobra.Command
config string
}
func newInitCmd() *initCmd {
root := &initCmd{}
cmd := &cobra.Command{
Use: "init",
Aliases: []string{"i"},
Short: "Creates a sample nfpm.yaml config file",
SilenceUsage: true,
SilenceErrors: true,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
if err := os.WriteFile(root.config, []byte(example), 0o666); err != nil {
return fmt.Errorf("failed to create example file: %w", err)
}
return nil
},
}
cmd.Flags().StringVarP(&root.config, "config", "f", "nfpm.yaml", "Path to the to-be-created config file")
root.cmd = cmd
return root
}
const example = `# nfpm example config file
#
# check https://nfpm.goreleaser.com/configuration for detailed usage
#
name: "foo"
arch: "amd64"
platform: "linux"
version: "v1.0.0"
section: "default"
priority: "extra"
replaces:
- foobar
provides:
- bar
depends:
- foo
- bar
recommends:
- whatever
suggests:
- something-else
conflicts:
- not-foo
- not-bar
maintainer: "John Doe <john@example.com>"
description: |
FooBar is the great foo and bar software.
And this can be in multiple lines!
vendor: "FooBarCorp"
homepage: "http://example.com"
license: "MIT"
changelog: "changelog.yaml"
contents:
- src: ./foo
dst: /usr/local/bin/foo
- src: ./bar
dst: /usr/local/bin/bar
- src: ./foobar.conf
dst: /etc/foobar.conf
type: config
- src: /usr/local/bin/foo
dst: /sbin/foo
type: symlink
overrides:
rpm:
scripts:
preinstall: ./scripts/preinstall.sh
postremove: ./scripts/postremove.sh
deb:
scripts:
postinstall: ./scripts/postinstall.sh
preremove: ./scripts/preremove.sh
`

111
internal/cmd/package.go Normal file
View File

@ -0,0 +1,111 @@
package cmd
import (
"errors"
"fmt"
"os"
"path"
"path/filepath"
"github.com/goreleaser/nfpm/v2"
"github.com/spf13/cobra"
)
type packageCmd struct {
cmd *cobra.Command
config string
target string
packager string
}
func newPackageCmd() *packageCmd {
root := &packageCmd{}
cmd := &cobra.Command{
Use: "package",
Aliases: []string{"pkg", "p"},
Short: "Creates a package based on the given the given config file and flags",
SilenceUsage: true,
SilenceErrors: true,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return doPackage(root.config, root.target, root.packager)
},
}
cmd.Flags().StringVarP(&root.config, "config", "f", "nfpm.yaml", "Config file to be used")
cmd.Flags().StringVarP(&root.target, "target", "t", "", "Where to save the generated package (filename, folder or empty for current folder)")
cmd.Flags().StringVarP(&root.packager, "packager", "p", "", "Which packager implementation to use [apk|deb|rpm]")
root.cmd = cmd
return root
}
var errInsufficientParams = errors.New("a packager must be specified if target is a directory or blank")
// nolint:funlen
func doPackage(configPath, target, packager string) error {
targetIsADirectory := false
stat, err := os.Stat(target)
if err == nil && stat.IsDir() {
targetIsADirectory = true
}
if packager == "" {
ext := filepath.Ext(target)
if targetIsADirectory || ext == "" {
return errInsufficientParams
}
packager = ext[1:]
fmt.Println("guessing packager from target file extension...")
}
config, err := nfpm.ParseFile(configPath)
if err != nil {
return err
}
info, err := config.Get(packager)
if err != nil {
return err
}
info = nfpm.WithDefaults(info)
if err = nfpm.Validate(info); err != nil {
return err
}
fmt.Printf("using %s packager...\n", packager)
pkg, err := nfpm.Get(packager)
if err != nil {
return err
}
if target == "" {
// if no target was specified create a package in
// current directory with a conventional file name
target = pkg.ConventionalFileName(info)
} else if targetIsADirectory {
// if a directory was specified as target, create
// a package with conventional file name there
target = path.Join(target, pkg.ConventionalFileName(info))
}
f, err := os.Create(target)
if err != nil {
return err
}
info.Target = target
err = pkg.Package(info, f)
_ = f.Close()
if err != nil {
os.Remove(target)
return err
}
fmt.Printf("created package: %s\n", target)
return nil
}

54
internal/cmd/root.go Normal file
View File

@ -0,0 +1,54 @@
package cmd
import (
"fmt"
"github.com/spf13/cobra"
_ "github.com/goreleaser/nfpm/v2/apk"
_ "github.com/goreleaser/nfpm/v2/deb"
_ "github.com/goreleaser/nfpm/v2/rpm"
)
func Execute(version string, exit func(int), args []string) {
newRootCmd(version, exit).Execute(args)
}
type rootCmd struct {
cmd *cobra.Command
exit func(int)
}
func (cmd *rootCmd) Execute(args []string) {
cmd.cmd.SetArgs(args)
if err := cmd.cmd.Execute(); err != nil {
fmt.Println(err.Error())
cmd.exit(1)
}
}
func newRootCmd(version string, exit func(int)) *rootCmd {
root := &rootCmd{
exit: exit,
}
cmd := &cobra.Command{
Use: "nfpm",
Short: "Packages apps on RPM, Deb and APK formats based on a YAML configuration file",
Long: `NFPM is a simple, 0-dependencies, deb, rpm and apk packager.`,
Version: version,
SilenceUsage: true,
SilenceErrors: true,
Args: cobra.NoArgs,
}
cmd.AddCommand(
newInitCmd().cmd,
newPackageCmd().cmd,
newCompletionCmd().cmd,
newDocsCmd().cmd,
)
root.cmd = cmd
return root
}

19
scripts/cmd_docs.sh Executable file
View File

@ -0,0 +1,19 @@
#!/bin/sh
set -e
SED="sed"
if which gsed >/dev/null 2>&1; then
SED="gsed"
fi
rm -rf www/docs/cmd/
mkdir -p www/docs/cmd/
go run ./cmd/nfpm docs
"$SED" \
-i'' \
-e 's/SEE ALSO/See also/g' \
-e 's/^## /# /g' \
-e 's/^### /## /g' \
-e 's/^#### /### /g' \
-e 's/^##### /#### /g' \
./www/docs/cmd/*.md

7
scripts/completions.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/sh
set -e
rm -rf completions
mkdir completions
for sh in bash zsh fish; do
go run ./cmd/nfpm completion "$sh" >"completions/nfpm.$sh"
done

20
www/docs/cmd/nfpm.md Normal file
View File

@ -0,0 +1,20 @@
# nfpm
Packages apps on RPM, Deb and APK formats based on a YAML configuration file
## Synopsis
NFPM is a simple, 0-dependencies, deb, rpm and apk packager.
## Options
```
-h, --help help for nfpm
```
## See also
* [nfpm completion](/cmd/nfpm_completion) - Prints shell autocompletion scripts for NFPM
* [nfpm init](/cmd/nfpm_init) - Creates a sample nfpm.yaml config file
* [nfpm package](/cmd/nfpm_package) - Creates a package based on the given the given config file and flags

View File

@ -0,0 +1,60 @@
# nfpm completion
Prints shell autocompletion scripts for NFPM
## Synopsis
Allows you to setup your shell to completions NFPM commands and flags.
### Bash
$ source <(nfpm completion bash)
To load completions for each session, execute once:
#### Linux
$ nfpm completion bash > /etc/bash_completion.d/nfpm
#### MacOS
$ nfpm completion bash > /usr/local/etc/bash_completion.d/nfpm
### ZSH
If shell completion is not already enabled in your environment you will need to enable it.
You can execute the following once:
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
To load completions for each session, execute once:
$ nfpm completion zsh > "${fpath[1]}/_nfpm"
You will need to start a new shell for this setup to take effect.
### Fish
$ nfpm completion fish | source
To load completions for each session, execute once:
$ nfpm completion fish > ~/.config/fish/completions/nfpm.fish
**NOTE**: If you are using an official nfpm package, it should setup completions for you out of the box.
```
nfpm completion [bash|zsh|fish]
```
## Options
```
-h, --help help for completion
```
## See also
* [nfpm](/cmd/nfpm) - Packages apps on RPM, Deb and APK formats based on a YAML configuration file

19
www/docs/cmd/nfpm_init.md Normal file
View File

@ -0,0 +1,19 @@
# nfpm init
Creates a sample nfpm.yaml config file
```
nfpm init [flags]
```
## Options
```
-f, --config string Path to the to-be-created config file (default "nfpm.yaml")
-h, --help help for init
```
## See also
* [nfpm](/cmd/nfpm) - Packages apps on RPM, Deb and APK formats based on a YAML configuration file

View File

@ -0,0 +1,21 @@
# nfpm package
Creates a package based on the given the given config file and flags
```
nfpm package [flags]
```
## Options
```
-f, --config string Config file to be used (default "nfpm.yaml")
-h, --help help for package
-p, --packager string Which packager implementation to use [apk|deb|rpm]
-t, --target string Where to save the generated package (filename, folder or empty for current folder)
```
## See also
* [nfpm](/cmd/nfpm) - Packages apps on RPM, Deb and APK formats based on a YAML configuration file

View File

@ -1,4 +1,4 @@
# Home
# NFPM
![](/static/banner.svg)

View File

@ -7,28 +7,39 @@ Here are the steps for each of them:
## Install the pre-compiled binary
**homebrew tap** (only on macOS for now):
**homebrew tap** (official):
```console
$ brew install goreleaser/tap/nfpm
```sh
brew install goreleaser/tap/nfpm
```
**homebrew** (may not be the latest version):
```sh
brew install nfpm
```
**scoop**:
```console
$ scoop bucket add goreleaser https://github.com/goreleaser/scoop-bucket.git
$ scoop install nfpm
```sh
scoop bucket add goreleaser https://github.com/goreleaser/scoop-bucket.git
scoop install nfpm
```
**deb/rpm**:
**deb/rpm/apk**:
Download the `.deb` or `.rpm` from the [releases page][releases] and
install with `dpkg -i` and `rpm -i` respectively.
Download the `.deb`, `.rpm` or `.apk` from the [releases page][releases] and install them with the appropriate tools.
**Shell script**:
**shell script**:
```console
$ curl -sfL https://install.goreleaser.com/github.com/goreleaser/nfpm.sh | sh
```sh
curl -sfL https://install.goreleaser.com/github.com/goreleaser/nfpm.sh | sh
```
**go install**:
```sh
go install github.com/goreleaser/nfpm
```
**manually**:
@ -41,14 +52,13 @@ copy to the desired location.
You can also use it within a Docker container. To do that, you'll need to
execute something more-or-less like the following:
```console
$ docker run --rm \
-v $PWD:/tmp/pkg \
goreleaser/nfpm pkg --config /tmp/pkg/foo.yml --target /tmp/pkg/foo.rpm
```sh
docker run --rm -v $PWD:/tmp/pkg goreleaser/nfpm package \
--config /tmp/pkg/foo.yml \
--target /tmp \
--packager deb
```
[releases]: https://github.com/goreleaser/nfpm/releases
## Compiling from source
Here you have two options:
@ -58,27 +68,29 @@ steps on our [contributing guide](/contributing).
If you just want to build from source for whatever reason, follow these steps:
**Clone:**
**clone:**
```console
$ git clone https://github.com/goreleaser/nfpm
$ cd nfpm
```sh
git clone https://github.com/goreleaser/nfpm
cd nfpm
```
**Get the dependencies:**
**get the dependencies:**
```console
$ go mod tidy
```sh
go mod tidy
```
**Build:**
**build:**
```console
$ go build -o nfpm cmd/nfpm/main.go
```sh
go build -o nfpm ./cmd/nfpm
```
**Verify it works:**
**verify it works:**
```console
$ ./nfpm --version
```sh
./nfpm --version
```
[releases]: https://github.com/goreleaser/nfpm/releases

View File

@ -1,8 +1,31 @@
---
title: Sponsors
title: Sponsoring the Project
---
Does your company use goreleaser? Help keep the project bug-free and feature rich by [sponsoring the project](https://opencollective.com/goreleaser#sponsor).
Does you or your company use NFPM?
You can help keep the project bug-free and feature rich by sponsoring the project and the maintainers.
## GitHub Sponsors
GitHub Sponsors is a great way to contribute directly to the main maintainer, [caarlos0](https://github.com/caarlos0).
This money usually goes to buying coffee, beer, better hardware and such.
You can sponsor and see who's sponsoring Carlos [here](https://github.com/sponsors/caarlos0).
<iframe src="https://github.com/sponsors/caarlos0/card" title="Sponsor caarlos0" height="225" width="600" style="border: 0;"></iframe>
## OpenCollective
OpenCollective is a great way to send some money towards the GoReleaser organization.
This ultimately is used to buy/renew domains, keep servers up (although right now we're on free plans), print and send stickers to other contributors among other things.
You can start sponsoring at the [OpenCollective website](https://opencollective.com/goreleaser).
Bellow you can see a list of the current sponsors and backers on OpenCollective:
### Sponsors
<a href="https://opencollective.com/goreleaser/sponsors/0/website" target="_blank"><img src="https://opencollective.com/goreleaser/sponsors/0/avatar"></a>
<a href="https://opencollective.com/goreleaser/sponsors/1/website" target="_blank"><img src="https://opencollective.com/goreleaser/sponsors/1/avatar"></a>
@ -10,9 +33,7 @@ Does your company use goreleaser? Help keep the project bug-free and feature ric
<a href="https://opencollective.com/goreleaser/sponsors/3/website" target="_blank"><img src="https://opencollective.com/goreleaser/sponsors/3/avatar"></a>
<a href="https://opencollective.com/goreleaser/sponsors/4/website" target="_blank"><img src="https://opencollective.com/goreleaser/sponsors/4/avatar"></a>
## Backers
Love our work and community? [Become a backer](https://opencollective.com/goreleaser).
### Backers
<a href="https://opencollective.com/goreleaser/backers/0/website" target="_blank"><img src="https://opencollective.com/goreleaser/backers/0/avatar"></a>
<a href="https://opencollective.com/goreleaser/backers/1/website" target="_blank"><img src="https://opencollective.com/goreleaser/backers/1/avatar"></a>

View File

@ -1,27 +1,26 @@
# Usage
NFPM can be used both as command line tool or as a library.
## Command Line
To create a sample config file, run:
```console
$ nfpm init
```sh
nfpm init
```
You can then customize it and package to the formats you want:
```console
$ nfpm pkg --packager deb --target /tmp/
using deb packager...
created package: /tmp/foo_1.0.0_amd64.deb
$ nfpm pkg --packager rpm --target /tmp/
using rpm packager...
created package: /tmp/foo-1.0.0.x86_64.rpm
```sh
nfpm pkg --packager deb --target /tmp/
nfpm pkg --packager rpm --target /tmp/
```
You can learn about it in more detail in the [command line reference section](/cmd/nfpm/).
## Go Library
Check the [GoDocs](https://pkg.go.dev/github.com/goreleaser/nfpm/v2?tab=doc) page,
as well as [NFPM command line implementation](https://github.com/goreleaser/nfpm/blob/master/cmd/nfpm/main.go)
Check out the [GoDocs page](https://pkg.go.dev/github.com/goreleaser/nfpm/v2?tab=doc),
the [NFPM command line implementation](https://github.com/goreleaser/nfpm/blob/master/cmd/nfpm/main.go)
and [GoReleaser's usage](https://github.com/goreleaser/goreleaser/blob/master/internal/pipe/nfpm/nfpm.go).

View File

@ -12,6 +12,19 @@ theme:
favicon: static/favicon.ico
include_search_page: false
search_index_only: true
features:
- navigation.instant
palette:
- media: "(prefers-color-scheme: light)" # Light mode
scheme: default
toggle:
icon: material/lightbulb-outline
name: Switch to light mode
- media: "(prefers-color-scheme: dark)" # Dark mode
scheme: slate
toggle:
icon: material/lightbulb
name: Switch to dark mode
plugins:
# disable temporarely because its freezing the page
@ -22,7 +35,6 @@ plugins:
- minify:
minify_html: true
extra:
social:
- icon: fontawesome/brands/github-alt
@ -38,6 +50,11 @@ nav:
- index.md
- install.md
- usage.md
- Command Line Reference:
- nfpm: cmd/nfpm.md
- nfpm init: cmd/nfpm_init.md
- nfpm package: cmd/nfpm_package.md
- nfpm completion: cmd/nfpm_completion.md
- configuration.md
- tips.md
- contributing.md