2022-09-26 19:28:21 +00:00
/ *
* LURE - Linux User REpository
2023-01-31 07:12:29 +00:00
* Copyright ( C ) 2023 Arsen Musayelyan
2022-09-26 19:28:21 +00:00
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
* /
2022-09-25 21:00:15 +00:00
package main
import (
2022-10-03 03:09:12 +00:00
"bytes"
2022-09-25 21:00:15 +00:00
"context"
"encoding/hex"
2023-01-29 04:53:06 +00:00
"fmt"
2022-09-25 21:00:15 +00:00
"io"
"os"
"path/filepath"
"runtime"
"strconv"
"strings"
_ "github.com/goreleaser/nfpm/v2/apk"
_ "github.com/goreleaser/nfpm/v2/arch"
_ "github.com/goreleaser/nfpm/v2/deb"
_ "github.com/goreleaser/nfpm/v2/rpm"
"github.com/urfave/cli/v2"
"golang.org/x/exp/slices"
"github.com/goreleaser/nfpm/v2"
"github.com/goreleaser/nfpm/v2/files"
2023-04-21 03:01:05 +00:00
"go.elara.ws/logger/log"
"go.elara.ws/lure/distro"
"go.elara.ws/lure/internal/cliutils"
"go.elara.ws/lure/internal/config"
"go.elara.ws/lure/internal/cpu"
"go.elara.ws/lure/internal/db"
"go.elara.ws/lure/internal/dl"
"go.elara.ws/lure/internal/repos"
"go.elara.ws/lure/internal/shutils"
"go.elara.ws/lure/internal/shutils/decoder"
"go.elara.ws/lure/manager"
2022-09-25 21:00:15 +00:00
"mvdan.cc/sh/v3/expand"
"mvdan.cc/sh/v3/interp"
"mvdan.cc/sh/v3/syntax"
)
// BuildVars represents the script variables required
// to build a package
type BuildVars struct {
Name string ` sh:"name,required" `
Version string ` sh:"version,required" `
Release int ` sh:"release,required" `
Epoch uint ` sh:"epoch" `
Description string ` sh:"desc" `
Homepage string ` sh:"homepage" `
2022-09-29 08:31:33 +00:00
Maintainer string ` sh:"maintainer" `
2022-09-25 21:00:15 +00:00
Architectures [ ] string ` sh:"architectures" `
Licenses [ ] string ` sh:"license" `
Provides [ ] string ` sh:"provides" `
Conflicts [ ] string ` sh:"conflicts" `
Depends [ ] string ` sh:"deps" `
BuildDepends [ ] string ` sh:"build_deps" `
Replaces [ ] string ` sh:"replaces" `
Sources [ ] string ` sh:"sources" `
Checksums [ ] string ` sh:"checksums" `
Backup [ ] string ` sh:"backup" `
2022-09-26 21:38:14 +00:00
Scripts Scripts ` sh:"scripts" `
}
type Scripts struct {
PreInstall string ` sh:"preinstall" `
PostInstall string ` sh:"postinstall" `
PreRemove string ` sh:"preremove" `
2022-10-23 08:16:42 +00:00
PostRemove string ` sh:"postremove" `
2022-09-26 21:38:14 +00:00
PreUpgrade string ` sh:"preupgrade" `
PostUpgrade string ` sh:"postupgrade" `
PreTrans string ` sh:"pretrans" `
PostTrans string ` sh:"posttrans" `
2022-09-25 21:00:15 +00:00
}
func buildCmd ( c * cli . Context ) error {
script := c . String ( "script" )
2022-12-01 07:04:52 +00:00
err := repos . Pull ( c . Context , gdb , cfg . Repos )
if err != nil {
log . Fatal ( "Error pulling repositories" ) . Err ( err ) . Send ( )
}
2022-09-25 21:00:15 +00:00
mgr := manager . Detect ( )
if mgr == nil {
log . Fatal ( "Unable to detect supported package manager on system" ) . Send ( )
}
2023-02-24 00:38:08 +00:00
pkgPaths , _ , err := buildPackage ( c . Context , script , mgr , c . Bool ( "clean" ) , c . Bool ( "interactive" ) )
2022-09-25 21:00:15 +00:00
if err != nil {
log . Fatal ( "Error building package" ) . Err ( err ) . Send ( )
}
2022-10-14 08:37:13 +00:00
wd , err := os . Getwd ( )
if err != nil {
log . Fatal ( "Error getting working directory" ) . Err ( err ) . Send ( )
}
for _ , pkgPath := range pkgPaths {
name := filepath . Base ( pkgPath )
err = os . Rename ( pkgPath , filepath . Join ( wd , name ) )
if err != nil {
log . Fatal ( "Error moving the package" ) . Err ( err ) . Send ( )
}
}
2022-09-25 21:00:15 +00:00
return nil
}
2022-12-01 06:15:34 +00:00
// buildPackage builds the script at the given path. It returns two slices. One contains the paths
// to the built package(s), the other contains the names of the built package(s).
2023-02-24 00:38:08 +00:00
func buildPackage ( ctx context . Context , script string , mgr manager . Manager , clean , interactive bool ) ( [ ] string , [ ] string , error ) {
2022-09-25 21:00:15 +00:00
info , err := distro . ParseOSRelease ( ctx )
if err != nil {
return nil , nil , err
}
2022-10-02 03:56:08 +00:00
var distroChanged bool
2022-09-28 17:08:28 +00:00
if distID , ok := os . LookupEnv ( "LURE_DISTRO" ) ; ok {
info . ID = distID
2022-11-22 05:03:56 +00:00
// Since the distro was overwritten, we don't know what the
// like distros are, so set to nil
info . Like = nil
2022-10-02 03:56:08 +00:00
distroChanged = true
2022-09-28 17:08:28 +00:00
}
2022-09-25 21:00:15 +00:00
fl , err := os . Open ( script )
if err != nil {
return nil , nil , err
}
file , err := syntax . NewParser ( ) . Parse ( fl , "lure.sh" )
if err != nil {
return nil , nil , err
}
fl . Close ( )
2022-12-03 19:52:09 +00:00
scriptDir := filepath . Dir ( script )
2022-12-03 20:08:58 +00:00
env := genBuildEnv ( info , scriptDir )
2022-12-03 19:52:09 +00:00
// The first pass is just used to get variable values and runs before
// the script is displayed, so it is restricted so as to prevent malicious
// code from executing.
2022-09-25 21:00:15 +00:00
runner , err := interp . New (
interp . Env ( expand . ListEnviron ( env ... ) ) ,
interp . StdIO ( os . Stdin , os . Stdout , os . Stderr ) ,
2022-12-03 20:08:58 +00:00
interp . ExecHandler ( rHelpers . ExecHandler ( shutils . NopExec ) ) ,
2022-12-03 19:52:09 +00:00
interp . ReadDirHandler ( shutils . RestrictedReadDir ( scriptDir ) ) ,
interp . StatHandler ( shutils . RestrictedStat ( scriptDir ) ) ,
interp . OpenHandler ( shutils . RestrictedOpen ( scriptDir ) ) ,
2022-09-25 21:00:15 +00:00
)
if err != nil {
return nil , nil , err
}
err = runner . Run ( ctx , file )
if err != nil {
return nil , nil , err
}
dec := decoder . New ( info , runner )
2022-10-02 03:56:08 +00:00
// If distro was changed, the list of like distros
// no longer applies, so disable its use
if distroChanged {
dec . LikeDistros = false
}
2022-09-25 21:00:15 +00:00
var vars BuildVars
err = dec . DecodeVars ( & vars )
if err != nil {
return nil , nil , err
}
2023-01-29 22:40:37 +00:00
baseDir := filepath . Join ( config . PkgsDir , vars . Name )
srcdir := filepath . Join ( baseDir , "src" )
pkgdir := filepath . Join ( baseDir , "pkg" )
if ! clean {
builtPkgPath , ok , err := checkForBuiltPackage ( mgr , & vars , getPkgFormat ( mgr ) , baseDir )
if err != nil {
return nil , nil , err
}
if ok {
return [ ] string { builtPkgPath } , nil , err
}
}
2023-02-24 00:38:08 +00:00
err = cliutils . PromptViewScript ( script , vars . Name , cfg . PagerStyle , interactive , translator )
2022-12-03 19:52:09 +00:00
if err != nil {
log . Fatal ( "Failed to prompt user to view build script" ) . Err ( err ) . Send ( )
}
2022-10-01 21:39:26 +00:00
if ! archMatches ( vars . Architectures ) {
2023-02-24 00:38:08 +00:00
buildAnyway , err := cliutils . YesNoPrompt ( "Your system's CPU architecture doesn't match this package. Do you want to build anyway?" , interactive , true , translator )
2022-12-01 05:58:21 +00:00
if err != nil {
return nil , nil , err
}
2022-10-01 21:39:26 +00:00
if ! buildAnyway {
os . Exit ( 1 )
}
}
2022-09-25 21:00:15 +00:00
log . Info ( "Building package" ) . Str ( "name" , vars . Name ) . Str ( "version" , vars . Version ) . Send ( )
2022-12-03 19:52:09 +00:00
// The second pass will be used to execute the actual functions,
// so it cannot be restricted. The script has already been displayed
// to the user by this point, so it should be safe
runner , err = interp . New (
interp . Env ( expand . ListEnviron ( env ... ) ) ,
interp . StdIO ( os . Stdin , os . Stdout , os . Stderr ) ,
interp . ExecHandler ( helpers . ExecHandler ( nil ) ) ,
)
if err != nil {
return nil , nil , err
}
err = runner . Run ( ctx , file )
if err != nil {
return nil , nil , err
}
dec = decoder . New ( info , runner )
// If distro was changed, the list of like distros
// no longer applies, so disable its use
if distroChanged {
dec . LikeDistros = false
}
2022-09-25 21:00:15 +00:00
err = os . RemoveAll ( baseDir )
if err != nil {
return nil , nil , err
}
err = os . MkdirAll ( srcdir , 0 o755 )
if err != nil {
return nil , nil , err
}
err = os . MkdirAll ( pkgdir , 0 o755 )
if err != nil {
return nil , nil , err
}
2022-11-14 02:49:55 +00:00
installed , err := mgr . ListInstalled ( nil )
if err != nil {
return nil , nil , err
}
2023-01-26 00:43:25 +00:00
if instVer , ok := installed [ vars . Name ] ; ok {
log . Warn ( "This package is already installed" ) .
Str ( "name" , vars . Name ) .
Str ( "version" , instVer ) .
Send ( )
}
2022-11-14 02:49:55 +00:00
var buildDeps [ ] string
2023-01-29 09:32:55 +00:00
if len ( vars . BuildDepends ) > 0 {
found , notFound , err := repos . FindPkgs ( gdb , vars . BuildDepends )
2022-12-01 03:10:17 +00:00
if err != nil {
return nil , nil , err
}
2023-01-29 09:32:55 +00:00
found = filterBuildDeps ( found , installed )
2022-09-25 21:00:15 +00:00
log . Info ( "Installing build dependencies" ) . Send ( )
2023-01-29 09:32:55 +00:00
2023-02-24 00:38:08 +00:00
flattened := cliutils . FlattenPkgs ( found , "install" , interactive , translator )
2023-01-29 09:32:55 +00:00
buildDeps = packageNames ( flattened )
2023-02-24 00:38:08 +00:00
installPkgs ( ctx , flattened , notFound , mgr , clean , interactive )
2022-09-25 21:00:15 +00:00
}
var builtDeps , builtNames , repoDeps [ ] string
if len ( vars . Depends ) > 0 {
log . Info ( "Installing dependencies" ) . Send ( )
2022-12-01 03:10:17 +00:00
found , notFound , err := repos . FindPkgs ( gdb , vars . Depends )
if err != nil {
return nil , nil , err
}
2023-02-24 00:38:08 +00:00
scripts := getScriptPaths ( cliutils . FlattenPkgs ( found , "install" , interactive , translator ) )
2022-09-25 21:00:15 +00:00
for _ , script := range scripts {
2023-02-24 00:38:08 +00:00
pkgPaths , pkgNames , err := buildPackage ( ctx , script , mgr , clean , interactive )
2022-09-25 21:00:15 +00:00
if err != nil {
return nil , nil , err
}
builtDeps = append ( builtDeps , pkgPaths ... )
builtNames = append ( builtNames , pkgNames ... )
builtNames = append ( builtNames , filepath . Base ( filepath . Dir ( script ) ) )
}
repoDeps = notFound
}
log . Info ( "Downloading sources" ) . Send ( )
err = getSources ( ctx , srcdir , & vars )
if err != nil {
return nil , nil , err
}
2022-12-03 20:08:58 +00:00
err = setDirVars ( ctx , runner , srcdir , pkgdir )
2022-09-25 21:00:15 +00:00
if err != nil {
return nil , nil , err
}
2022-11-29 21:30:58 +00:00
fn , ok := dec . GetFunc ( "version" )
if ok {
log . Info ( "Executing version()" ) . Send ( )
buf := & bytes . Buffer { }
err = fn (
ctx ,
2022-11-29 21:33:47 +00:00
interp . Dir ( srcdir ) ,
2022-11-29 21:30:58 +00:00
interp . StdIO ( os . Stdin , buf , os . Stderr ) ,
)
if err != nil {
return nil , nil , err
}
newVer := strings . TrimSpace ( buf . String ( ) )
err = setVersion ( ctx , runner , newVer )
if err != nil {
return nil , nil , err
}
vars . Version = newVer
log . Info ( "Updating version" ) . Str ( "new" , newVer ) . Send ( )
}
2022-11-20 22:15:31 +00:00
fn , ok = dec . GetFunc ( "prepare" )
2022-09-30 20:22:10 +00:00
if ok {
log . Info ( "Executing prepare()" ) . Send ( )
2022-10-03 03:06:00 +00:00
err = fn ( ctx , interp . Dir ( srcdir ) )
2022-09-30 20:22:10 +00:00
if err != nil {
return nil , nil , err
}
}
fn , ok = dec . GetFunc ( "build" )
2022-09-25 21:00:15 +00:00
if ok {
log . Info ( "Executing build()" ) . Send ( )
2022-10-03 03:06:00 +00:00
err = fn ( ctx , interp . Dir ( srcdir ) )
2022-09-25 21:00:15 +00:00
if err != nil {
return nil , nil , err
}
}
fn , ok = dec . GetFunc ( "package" )
if ok {
log . Info ( "Executing package()" ) . Send ( )
2022-10-03 03:06:00 +00:00
err = fn ( ctx , interp . Dir ( srcdir ) )
2022-09-25 21:00:15 +00:00
if err != nil {
return nil , nil , err
}
2022-09-30 20:50:17 +00:00
} else {
log . Fatal ( "The package() function is required" ) . Send ( )
2022-09-25 21:00:15 +00:00
}
2023-01-31 22:05:34 +00:00
log . Info ( "Building package metadata" ) . Str ( "name" , vars . Name ) . Send ( )
2022-09-25 21:00:15 +00:00
uniq (
& repoDeps ,
& builtDeps ,
& builtNames ,
)
pkgInfo := & nfpm . Info {
Name : vars . Name ,
Description : vars . Description ,
2022-12-01 06:02:36 +00:00
Arch : cpu . Arch ( ) ,
2022-09-25 21:00:15 +00:00
Version : vars . Version ,
Release : strconv . Itoa ( vars . Release ) ,
Homepage : vars . Homepage ,
License : strings . Join ( vars . Licenses , ", " ) ,
2022-09-29 08:31:33 +00:00
Maintainer : vars . Maintainer ,
2022-09-25 21:00:15 +00:00
Overridables : nfpm . Overridables {
2022-09-29 21:35:56 +00:00
Conflicts : vars . Conflicts ,
Replaces : vars . Replaces ,
Provides : vars . Provides ,
Depends : append ( repoDeps , builtNames ... ) ,
2022-09-25 21:00:15 +00:00
} ,
}
2022-10-01 07:47:50 +00:00
if vars . Epoch != 0 {
pkgInfo . Epoch = strconv . FormatUint ( uint64 ( vars . Epoch ) , 10 )
}
2022-09-26 21:38:14 +00:00
setScripts ( & vars , pkgInfo , filepath . Dir ( script ) )
2022-09-28 20:03:44 +00:00
if slices . Contains ( vars . Architectures , "all" ) {
pkgInfo . Arch = "all"
}
2022-09-28 22:23:09 +00:00
2022-09-25 21:00:15 +00:00
contents := [ ] * files . Content { }
filepath . Walk ( pkgdir , func ( path string , fi os . FileInfo , err error ) error {
trimmed := strings . TrimPrefix ( path , pkgdir )
if fi . IsDir ( ) {
f , err := os . Open ( path )
if err != nil {
return err
}
_ , err = f . Readdirnames ( 1 )
if err != io . EOF {
return nil
}
contents = append ( contents , & files . Content {
Source : path ,
Destination : trimmed ,
Type : "dir" ,
FileInfo : & files . ContentFileInfo {
MTime : fi . ModTime ( ) ,
} ,
} )
f . Close ( )
return nil
}
if fi . Mode ( ) & os . ModeSymlink != 0 {
link , err := os . Readlink ( path )
if err != nil {
return err
}
2022-12-22 22:18:41 +00:00
link = strings . TrimPrefix ( link , pkgdir )
2022-09-25 21:00:15 +00:00
contents = append ( contents , & files . Content {
Source : link ,
Destination : trimmed ,
Type : "symlink" ,
FileInfo : & files . ContentFileInfo {
MTime : fi . ModTime ( ) ,
Mode : fi . Mode ( ) ,
} ,
} )
return nil
}
fileContent := & files . Content {
Source : path ,
Destination : trimmed ,
FileInfo : & files . ContentFileInfo {
MTime : fi . ModTime ( ) ,
Mode : fi . Mode ( ) ,
Size : fi . Size ( ) ,
} ,
}
if slices . Contains ( vars . Backup , trimmed ) {
fileContent . Type = "config|noreplace"
}
contents = append ( contents , fileContent )
return nil
} )
pkgInfo . Overridables . Contents = contents
2023-01-29 22:40:37 +00:00
packager , err := nfpm . Get ( getPkgFormat ( mgr ) )
2022-09-25 21:00:15 +00:00
if err != nil {
return nil , nil , err
}
pkgName := packager . ConventionalFileName ( pkgInfo )
pkgPath := filepath . Join ( baseDir , pkgName )
pkgPaths := append ( builtDeps , pkgPath )
pkgNames := append ( builtNames , vars . Name )
pkgFile , err := os . Create ( pkgPath )
if err != nil {
return nil , nil , err
}
2023-01-31 22:05:34 +00:00
log . Info ( "Compressing package" ) . Str ( "name" , pkgName ) . Send ( )
2022-09-25 21:00:15 +00:00
err = packager . Package ( pkgInfo , pkgFile )
if err != nil {
return nil , nil , err
}
2022-11-14 02:49:55 +00:00
if len ( buildDeps ) > 0 {
2023-02-24 00:38:08 +00:00
removeBuildDeps , err := cliutils . YesNoPrompt ( "Would you like to remove build dependencies?" , interactive , false , translator )
2022-09-30 22:52:46 +00:00
if err != nil {
return nil , nil , err
}
if removeBuildDeps {
2022-10-01 08:30:13 +00:00
err = mgr . Remove (
& manager . Opts {
AsRoot : true ,
NoConfirm : true ,
} ,
2022-11-14 02:49:55 +00:00
buildDeps ... ,
2022-10-01 08:30:13 +00:00
)
2022-09-30 22:52:46 +00:00
if err != nil {
return nil , nil , err
}
}
}
2022-09-25 21:00:15 +00:00
uniq ( & pkgPaths , & pkgNames )
return pkgPaths , pkgNames , nil
}
2023-01-29 22:40:37 +00:00
func checkForBuiltPackage ( mgr manager . Manager , vars * BuildVars , pkgFormat , baseDir string ) ( string , bool , error ) {
filename , err := pkgFileName ( vars , pkgFormat )
if err != nil {
return "" , false , err
}
pkgPath := filepath . Join ( baseDir , filename )
_ , err = os . Stat ( pkgPath )
if err != nil {
return "" , false , nil
}
return pkgPath , true , nil
}
func pkgFileName ( vars * BuildVars , pkgFormat string ) ( string , error ) {
pkgInfo := & nfpm . Info {
Name : vars . Name ,
Arch : cpu . Arch ( ) ,
Version : vars . Version ,
Release : strconv . Itoa ( vars . Release ) ,
Epoch : strconv . FormatUint ( uint64 ( vars . Epoch ) , 10 ) ,
}
packager , err := nfpm . Get ( pkgFormat )
if err != nil {
return "" , err
}
return packager . ConventionalFileName ( pkgInfo ) , nil
}
func getPkgFormat ( mgr manager . Manager ) string {
pkgFormat := mgr . Format ( )
if format , ok := os . LookupEnv ( "LURE_PKG_FORMAT" ) ; ok {
pkgFormat = format
}
return pkgFormat
}
2022-12-03 20:08:58 +00:00
func genBuildEnv ( info * distro . OSRelease , scriptdir string ) [ ] string {
2022-09-25 21:00:15 +00:00
env := os . Environ ( )
2022-11-20 21:57:59 +00:00
2022-09-25 21:00:15 +00:00
env = append (
env ,
"DISTRO_NAME=" + info . Name ,
"DISTRO_PRETTY_NAME=" + info . PrettyName ,
"DISTRO_ID=" + info . ID ,
2022-11-20 21:45:45 +00:00
"DISTRO_VERSION_ID=" + info . VersionID ,
2022-11-22 05:03:56 +00:00
"DISTRO_ID_LIKE=" + strings . Join ( info . Like , " " ) ,
2022-09-25 21:00:15 +00:00
2022-12-01 06:02:36 +00:00
"ARCH=" + cpu . Arch ( ) ,
2022-09-25 21:00:15 +00:00
"NCPU=" + strconv . Itoa ( runtime . NumCPU ( ) ) ,
2022-12-03 20:08:58 +00:00
"scriptdir=" + scriptdir ,
2022-09-25 21:00:15 +00:00
)
return env
}
func getSources ( ctx context . Context , srcdir string , bv * BuildVars ) error {
if len ( bv . Sources ) != len ( bv . Checksums ) {
log . Fatal ( "The checksums array must be the same length as sources" )
}
for i , src := range bv . Sources {
2023-01-29 04:53:06 +00:00
opts := dl . Options {
Name : fmt . Sprintf ( "%s[%d]" , bv . Name , i ) ,
URL : src ,
2022-09-25 21:00:15 +00:00
Destination : srcdir ,
2023-01-29 04:53:06 +00:00
Progress : os . Stderr ,
2022-09-25 21:00:15 +00:00
}
2022-11-06 22:48:31 +00:00
if ! strings . EqualFold ( bv . Checksums [ i ] , "SKIP" ) {
2022-09-25 21:00:15 +00:00
checksum , err := hex . DecodeString ( bv . Checksums [ i ] )
if err != nil {
return err
}
2023-01-29 04:53:06 +00:00
opts . SHA256 = checksum
2022-09-25 21:00:15 +00:00
}
2023-01-29 04:53:06 +00:00
err := dl . Download ( ctx , opts )
2022-09-25 21:00:15 +00:00
if err != nil {
return err
}
}
return nil
}
// setDirVars sets srcdir and pkgdir. It's a very hacky way of doing so,
// but setting the runner's Env and Vars fields doesn't seem to work.
2022-12-03 20:08:58 +00:00
func setDirVars ( ctx context . Context , runner * interp . Runner , srcdir , pkgdir string ) error {
cmd := "srcdir='" + srcdir + "'\npkgdir='" + pkgdir + "'\n"
2022-09-25 21:00:15 +00:00
fl , err := syntax . NewParser ( ) . Parse ( strings . NewReader ( cmd ) , "vars" )
if err != nil {
return err
}
return runner . Run ( ctx , fl )
}
2022-09-26 21:38:14 +00:00
func setScripts ( vars * BuildVars , info * nfpm . Info , scriptDir string ) {
if vars . Scripts . PreInstall != "" {
info . Scripts . PreInstall = filepath . Join ( scriptDir , vars . Scripts . PreInstall )
}
if vars . Scripts . PostInstall != "" {
info . Scripts . PostInstall = filepath . Join ( scriptDir , vars . Scripts . PostInstall )
}
if vars . Scripts . PreRemove != "" {
info . Scripts . PreRemove = filepath . Join ( scriptDir , vars . Scripts . PreRemove )
}
if vars . Scripts . PostRemove != "" {
info . Scripts . PostRemove = filepath . Join ( scriptDir , vars . Scripts . PostRemove )
}
if vars . Scripts . PreUpgrade != "" {
info . ArchLinux . Scripts . PreUpgrade = filepath . Join ( scriptDir , vars . Scripts . PreUpgrade )
info . APK . Scripts . PreUpgrade = filepath . Join ( scriptDir , vars . Scripts . PreUpgrade )
}
if vars . Scripts . PostUpgrade != "" {
info . ArchLinux . Scripts . PostUpgrade = filepath . Join ( scriptDir , vars . Scripts . PostUpgrade )
info . APK . Scripts . PostUpgrade = filepath . Join ( scriptDir , vars . Scripts . PostUpgrade )
}
if vars . Scripts . PreTrans != "" {
info . RPM . Scripts . PreTrans = filepath . Join ( scriptDir , vars . Scripts . PreTrans )
}
if vars . Scripts . PostTrans != "" {
info . RPM . Scripts . PostTrans = filepath . Join ( scriptDir , vars . Scripts . PostTrans )
}
}
2022-12-01 06:15:34 +00:00
// archMatches checks if your system architecture matches
// one of the provided architectures
2022-10-01 21:39:26 +00:00
func archMatches ( architectures [ ] string ) bool {
2022-11-20 21:54:49 +00:00
if slices . Contains ( architectures , "all" ) {
return true
}
2022-10-01 21:39:26 +00:00
if slices . Contains ( architectures , "arm" ) {
architectures = append ( architectures , cpu . ARMVariant ( ) )
}
2022-12-01 06:02:36 +00:00
return slices . Contains ( architectures , cpu . Arch ( ) )
2022-10-01 21:39:26 +00:00
}
2022-11-20 22:15:31 +00:00
func setVersion ( ctx context . Context , r * interp . Runner , to string ) error {
fl , err := syntax . NewParser ( ) . Parse ( strings . NewReader ( "version='" + to + "'" ) , "" )
if err != nil {
return err
}
return r . Run ( ctx , fl )
}
2023-01-29 09:32:55 +00:00
func filterBuildDeps ( found map [ string ] [ ] db . Package , installed map [ string ] string ) map [ string ] [ ] db . Package {
out := map [ string ] [ ] db . Package { }
for name , pkgs := range found {
var inner [ ] db . Package
for _ , pkg := range pkgs {
if _ , ok := installed [ pkg . Name ] ; ! ok {
addToFiltered := true
for _ , provides := range pkg . Provides . Val {
if _ , ok := installed [ provides ] ; ok {
addToFiltered = false
break
}
}
if addToFiltered {
inner = append ( inner , pkg )
}
}
}
if len ( inner ) > 0 {
out [ name ] = inner
}
}
return out
}
func packageNames ( pkgs [ ] db . Package ) [ ] string {
names := make ( [ ] string , len ( pkgs ) )
for i , p := range pkgs {
names [ i ] = p . Name
}
return names
}
2022-12-01 06:15:34 +00:00
// uniq removes all duplicates from string slices
2022-09-25 21:00:15 +00:00
func uniq ( ss ... * [ ] string ) {
for _ , s := range ss {
slices . Sort ( * s )
* s = slices . Compact ( * s )
}
2022-12-01 18:53:03 +00:00
}