From 5b4edd768e9c4b394db200f1842b186e5d19dab7 Mon Sep 17 00:00:00 2001 From: Gianluca Boiano <491117+M0Rf30@users.noreply.github.com> Date: Sat, 21 Oct 2023 19:15:36 +0200 Subject: [PATCH] feat: add shellcheckrc and editorconfig (#36) --- .editorconfig | 14 ++++++++++++++ .shellcheckrc | 2 ++ cmd/yap/command/root.go | 5 +++-- examples/yap/PKGBUILD | 9 +++++---- pkg/builder/builder.go | 11 +++++++++++ pkg/options/strip.go | 4 ++++ pkg/packer/packer.go | 14 ++++++++++++++ pkg/pkgbuild/pkgbuild.go | 31 +++++++++++++++++++++++++++++++ pkg/project/project.go | 2 ++ pkg/source/source.go | 2 ++ pkg/utils/strings.go | 16 +++++++++------- 11 files changed, 97 insertions(+), 13 deletions(-) create mode 100644 .editorconfig create mode 100644 .shellcheckrc diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..af262f4 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +# top-most EditorConfig file +root = true + +[{go.mod,go.sum,*.go,.gitmodules}] +indent_style = tab +indent_size = 4 + +[PKGBUILD] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = false \ No newline at end of file diff --git a/.shellcheckrc b/.shellcheckrc new file mode 100644 index 0000000..02df2c0 --- /dev/null +++ b/.shellcheckrc @@ -0,0 +1,2 @@ +# Disable individual error codes +disable=SC2154,SC2164,SC2034 diff --git a/cmd/yap/command/root.go b/cmd/yap/command/root.go index 84baee2..6c2d3d7 100644 --- a/cmd/yap/command/root.go +++ b/cmd/yap/command/root.go @@ -15,8 +15,9 @@ Complete documentation is available at 🌐 https://github.com/M0Rf30/yap`, } -// Execute adds all child commands to the root command and sets flags appropriately. -// This is called by main.main(). It only needs to happen once to the rootCmd. +// Execute adds all child commands to the root command and sets flags +// appropriately. This is called by main.main(). It only needs to happen once to +// the rootCmd. func Execute() { cobra.CheckErr(rootCmd.Execute()) } diff --git a/examples/yap/PKGBUILD b/examples/yap/PKGBUILD index 0a80abb..612c418 100644 --- a/examples/yap/PKGBUILD +++ b/examples/yap/PKGBUILD @@ -37,7 +37,8 @@ build() { -buildvcs=false \ -ldflags="-w -s -linkmode=external \ -X main.version=${pkgver}" \ - cmd + -o yap \ + cmd/yap/main.go } package() { @@ -50,11 +51,11 @@ package() { mkdir -p "${pkgdir}/usr/share/zsh/site-functions/" mkdir -p "${pkgdir}/usr/share/fish/vendor_completions.d/" - ./"${pkgname}" completion bash > \ + ./${pkgname} completion bash > \ "${pkgdir}/usr/share/bash-completion/completions/${pkgname}" - ./"${pkgname}" completion zsh > \ + ./${pkgname} completion zsh > \ "${pkgdir}/usr/share/zsh/site-functions/_${pkgname}" - ./"${pkgname}" completion fish > \ + ./${pkgname} completion fish > \ "${pkgdir}/usr/share/fish/vendor_completions.d/${pkgname}.fish" install -Dm 644 -t \ diff --git a/pkg/builder/builder.go b/pkg/builder/builder.go index aa801e2..0323d04 100644 --- a/pkg/builder/builder.go +++ b/pkg/builder/builder.go @@ -9,10 +9,13 @@ import ( "github.com/M0Rf30/yap/pkg/utils" ) +// Builder maps PKGBUILD to generic functions aimed at artifacts generation. type Builder struct { PKGBUILD *pkgbuild.PKGBUILD } +// Compile manages all the instructions that lead to a single project artifact. +// It returns any error if occurred. func (builder *Builder) Compile() error { err := builder.initDirs() if err != nil { @@ -52,6 +55,8 @@ func (builder *Builder) Compile() error { return err } +// Package executes the instructions provided by a single project package() +// function. It returns any error if occurred. func (builder *Builder) Package() error { err := RunScript(builder.PKGBUILD.Package) if err != nil { @@ -61,6 +66,8 @@ func (builder *Builder) Package() error { return err } +// build executes the instructions provided by a single project build() +// function. It returns any error if occurred. func (builder *Builder) build() error { err := RunScript(builder.PKGBUILD.Build) if err != nil { @@ -70,6 +77,8 @@ func (builder *Builder) build() error { return err } +// getSources detects sources provided by a single project source array and +// downloads them if occurred. It returns any error if occurred. func (builder *Builder) getSources() error { var err error @@ -92,6 +101,8 @@ func (builder *Builder) getSources() error { return err } +// initDirs creates mandatory fakeroot folders (src, pkg) for a single project. +// It returns any error if occurred. func (builder *Builder) initDirs() error { err := utils.ExistsMakeDir(builder.PKGBUILD.SourceDir) if err != nil { diff --git a/pkg/options/strip.go b/pkg/options/strip.go index 436a954..482d359 100644 --- a/pkg/options/strip.go +++ b/pkg/options/strip.go @@ -1,5 +1,9 @@ package options +// StripScript is a scriptlet taken from makepkg resources. It's executed by +// mvdan/sh interpreter and provides strip instructions to dpkg-buildpackage. +// Although it's a very dirty solution, for now it's the faster way to have this +// essential feature. const StripScript = ` strip_file() { local binary=$1; shift diff --git a/pkg/packer/packer.go b/pkg/packer/packer.go index c02cbf8..17601e0 100644 --- a/pkg/packer/packer.go +++ b/pkg/packer/packer.go @@ -12,14 +12,28 @@ import ( "github.com/M0Rf30/yap/pkg/redhat" ) +// Packer is the common interface implemented by all package managers. type Packer interface { + // Prepare appends the dependencies required to build all the projects. It + // returns any error if encountered. Prepare(depends []string) error + // Build reads the path where the final artifact will be written. It returns any + // error if encountered. Build(output string) error + // Install reads the path where the final artifact will be written. It returns + // any error if encountered. Install(output string) error + // PrepareEnvironment reads a flag to install golang tools on request, on the + // build machine. It returns any error if encountered. PrepareEnvironment(flag bool) error + // Update performs a package manager update operation. It returns any error if + // encountered. Update() error } +// GetPackageManager reads the pkgBuild structure and the distro name. It +// returns a Packer interface representing the specialized package manager for +// that distro. func GetPackageManager(pkgBuild *pkgbuild.PKGBUILD, distro string) Packer { var packageManager Packer diff --git a/pkg/pkgbuild/pkgbuild.go b/pkg/pkgbuild/pkgbuild.go index dfe0e61..d07b9dc 100644 --- a/pkg/pkgbuild/pkgbuild.go +++ b/pkg/pkgbuild/pkgbuild.go @@ -14,8 +14,12 @@ import ( "mvdan.cc/sh/v3/shell" ) +// Verbos is a flag to enable verbose output. var Verbose bool +// PKGBUILD defines all the fields accepted by the yap specfile (variables, +// arrays, functions). It adds some exotics fields to manage debconfig +// templating and other rpm/deb descriptors. type PKGBUILD struct { Arch []string Backup []string @@ -61,6 +65,10 @@ type PKGBUILD struct { priorities map[string]int } +// AddItem reads a key and the related data. It checks the key for __ token and +// give to it a priority value. After that, it binds any element (variable, +// array, function) to the current environment. It returns any error if +// encountered. func (pkgBuild *PKGBUILD) AddItem(key string, data any) error { key, priority, err := pkgBuild.parseDirective(key) if err != nil { @@ -84,6 +92,9 @@ func (pkgBuild *PKGBUILD) AddItem(key string, data any) error { return err } +// CreateSpec reads the filepath where the specfile will be written and the +// content of the specfile. Specfile generation is done using go templates for +// every different distro family. It returns any error if encountered. func (pkgBuild *PKGBUILD) CreateSpec(filePath, script string) error { cleanFilePath := filepath.Clean(filePath) @@ -124,6 +135,9 @@ func (pkgBuild *PKGBUILD) CreateSpec(filePath, script string) error { return err } +// GetDepends reads the package manager name, its arguments and all the +// dependencies required to build the package. It returns any error if +// encountered. func (pkgBuild *PKGBUILD) GetDepends(packageManager string, args, makeDepends []string) error { var err error if len(makeDepends) == 0 { @@ -140,6 +154,9 @@ func (pkgBuild *PKGBUILD) GetDepends(packageManager string, args, makeDepends [] return err } +// GetUpdates reads the package manager name and its arguments to perform +// a sync with remotes and consequently retrieve updates. +// It returns any error if encountered. func (pkgBuild *PKGBUILD) GetUpdates(packageManager string, args ...string) error { err := utils.Exec("", packageManager, args...) if err != nil { @@ -158,6 +175,8 @@ func (pkgBuild *PKGBUILD) Init() { } } +// Validate checks that mandatory items are correctly provided by the PKGBUILD +// file. func (pkgBuild *PKGBUILD) Validate() { if len(pkgBuild.SourceURI) != len(pkgBuild.HashSums) { fmt.Printf("%s%s ❌ :: %snumber of sources and hashsums differs%s\n", @@ -178,6 +197,8 @@ func (pkgBuild *PKGBUILD) Validate() { } } +// mapArrays reads an array name and its content and maps them to the PKGBUILD +// struct. func (pkgBuild *PKGBUILD) mapArrays(key string, data any) { switch key { case "arch": @@ -207,6 +228,8 @@ func (pkgBuild *PKGBUILD) mapArrays(key string, data any) { } } +// mapFunctions reads a function name and its content and maps them to the +// PKGBUILD struct. func (pkgBuild *PKGBUILD) mapFunctions(key string, data any) { switch key { case "build": @@ -226,6 +249,8 @@ func (pkgBuild *PKGBUILD) mapFunctions(key string, data any) { } } +// mapVariables reads a variable name and its content and maps them to the +// PKGBUILD struct. func (pkgBuild *PKGBUILD) mapVariables(key string, data any) { var err error @@ -270,6 +295,10 @@ func (pkgBuild *PKGBUILD) mapVariables(key string, data any) { } } +// parseDirective reads a directive string and detect any specialized one (i.e +// only to be applied for ubuntu). It detects if distro codename is given and +// calculates and assigns a priority to the directive. It returns the directive +// key, assigned priority and any error if occurred. func (pkgBuild *PKGBUILD) parseDirective(input string) (string, int, error) { split := strings.Split(input, "__") key := split[0] @@ -324,6 +353,8 @@ func (pkgBuild *PKGBUILD) parseDirective(input string) (string, int, error) { return key, priority, err } +// setMainFolders checks for pkgbuild distro values and initialize the build +// fakeroot accordingly. func (pkgBuild *PKGBUILD) setMainFolders() { if pkgBuild.Distro == "arch" { pkgBuild.PackageDir = filepath.Join(pkgBuild.StartDir, "pkg", pkgBuild.PkgName) diff --git a/pkg/project/project.go b/pkg/project/project.go index 862e3b1..fae9e46 100644 --- a/pkg/project/project.go +++ b/pkg/project/project.go @@ -28,6 +28,8 @@ type DistroProject interface { Prepare() error } +// MultipleProject defnes the content of yap.json specfile and some in-memory +// objects. type MultipleProject struct { makeDepends []string packageManager packer.Packer diff --git a/pkg/source/source.go b/pkg/source/source.go index 6814d0d..3dfe871 100644 --- a/pkg/source/source.go +++ b/pkg/source/source.go @@ -192,6 +192,8 @@ func (src *Source) symlinkSources() error { return err } +// validate checks that items declared in the source array have a valid hashsum. +// It returns any error encountered. func (src *Source) validate() error { info, err := os.Stat(filepath.Join(src.StartDir, src.SourceItemPath)) if err != nil { diff --git a/pkg/utils/strings.go b/pkg/utils/strings.go index e5607c2..ead9751 100644 --- a/pkg/utils/strings.go +++ b/pkg/utils/strings.go @@ -11,10 +11,9 @@ import ( "mvdan.cc/sh/v3/syntax" ) -// GenerateRandomString returns a securely generated random string. -// It will return an error if the system's secure random -// number generator fails to function correctly, in which -// case the caller should not continue. +// GenerateRandomString returns a securely generated random string. It will +// return an error if the system's secure random number generator fails to +// function correctly, in which case the caller should not continue. func GenerateRandomString(n int) string { const letters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-" @@ -32,7 +31,8 @@ func GenerateRandomString(n int) string { return string(ret) } -// Generates a string from a *syntax.Assign of an array declaration. +// StringifyArray generates a string from a *syntax.Assign of an array +// declaration. func StringifyArray(node *syntax.Assign) []string { fields := make([]string, 0) printer := syntax.NewPrinter(syntax.Indent(2)) @@ -55,7 +55,8 @@ func StringifyArray(node *syntax.Assign) []string { return fields } -// Generates a string from a *syntax.Assign of a variable declaration. +// StringifyAssign generates a string from a *syntax.Assign of a variable +// declaration. func StringifyAssign(node *syntax.Assign) string { out := &strings.Builder{} printer := syntax.NewPrinter(syntax.Indent(2)) @@ -72,7 +73,8 @@ func StringifyAssign(node *syntax.Assign) string { return strings.Trim(out.String(), "\"") } -// Generates strings from a *syntax.Assign of a function declaration. +// StringifyFuncDecl generates strings from a *syntax.Assign of a function +// declaration. func StringifyFuncDecl(node *syntax.FuncDecl) string { out := &strings.Builder{} printer := syntax.NewPrinter(syntax.Indent(2))