1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060 |
- package main
- import (
- "bufio"
- "fmt"
- "io/ioutil"
- "os"
- "os/exec"
- "strconv"
- "strings"
- "sync"
- alpm "github.com/jguer/go-alpm"
- rpc "github.com/mikkeloscar/aur"
- gopkg "github.com/mikkeloscar/gopkgbuild"
- )
- // Install handles package installs
- func install(parser *arguments) error {
- requestTargets := parser.targets.toSlice()
- var err error
- if err != nil {
- return err
- }
- var incompatable stringSet
- removeMake := false
- srcinfosStale := make(map[string]*gopkg.PKGBUILD)
- srcinfos := make(map[string]*gopkg.PKGBUILD)
- var dc *depCatagories
- //remotenames: names of all non repo packages on the system
- _, _, _, remoteNames, err := filterPackages()
- if err != nil {
- return err
- }
- //cache as a stringset. maybe make it return a string set in the first
- //place
- remoteNamesCache := sliceToStringSet(remoteNames)
- //if we are doing -u also request every non repo package on the system
- if parser.existsArg("u", "sysupgrade") {
- requestTargets = append(requestTargets, remoteNames...)
- }
- //if len(aurTargets) > 0 || parser.existsArg("u", "sysupgrade") && len(remoteNames) > 0 {
- // fmt.Println(bold(cyan("::") + " Querying AUR..."))
- //}
- dt, err := getDepTree(requestTargets)
- if err != nil {
- return err
- }
- //only error if direct targets or deps are missing
- for missingName := range dt.Missing {
- if !remoteNamesCache.get(missingName) || parser.targets.get(missingName) {
- str := bold(red(arrow+" Error: ")) + "Could not find all required packages:"
- for name := range dt.Missing {
- str += "\n\t" + name
- }
- return fmt.Errorf("%s", str)
- }
- }
- //create the arguments to pass for the repo install
- arguments := parser.copy()
- arguments.delArg("u", "sysupgrade")
- arguments.delArg("y", "refresh")
- arguments.op = "S"
- arguments.targets = make(stringSet)
- if parser.existsArg("u", "sysupgrade") {
- repoUp, aurUp, err := upgradePkgs(dt)
- if err != nil {
- return err
- }
- fmt.Println()
- for pkg := range aurUp {
- parser.addTarget(pkg)
- }
- for pkg := range repoUp {
- arguments.addTarget(pkg)
- }
- //discard stuff thats
- //not a target and
- //not an upgrade and
- //is installed
- for pkg := range dt.Aur {
- if !parser.targets.get(pkg) && remoteNamesCache.get(pkg) {
- delete(dt.Aur, pkg)
- }
- }
- }
- hasAur := len(dt.Aur) != 0
- if hasAur && 0 == os.Geteuid() {
- return fmt.Errorf(red(arrow + " Refusing to install AUR Packages as root, Aborting."))
- }
- dc, err = getDepCatagories(parser.formatTargets(), dt)
- if err != nil {
- return err
- }
- for _, pkg := range dc.Repo {
- arguments.addTarget(pkg.DB().Name() + "/" + pkg.Name())
- }
- for pkg := range dt.Groups {
- arguments.addTarget(pkg)
- }
- if len(dc.Aur) == 0 && len(arguments.targets) == 0 {
- fmt.Println("There is nothing to do")
- return nil
- }
- if hasAur {
- printDepCatagories(dc)
- hasAur = len(dc.Aur) != 0
- fmt.Println()
- if !parser.existsArg("gendb") {
- err = checkForAllConflicts(dc)
- if err != nil {
- return err
- }
- }
- }
- if !parser.existsArg("gendb") && len(arguments.targets) > 0 {
- err := passToPacman(arguments)
- if err != nil {
- return fmt.Errorf("Error installing repo packages")
- }
- depArguments := makeArguments()
- depArguments.addArg("D", "asdeps")
- for _, pkg := range dc.Repo {
- depArguments.addTarget(pkg.Name())
- }
- for pkg := range dt.Repo {
- depArguments.delTarget(pkg)
- }
- if len(depArguments.targets) > 0 {
- _, stderr, err := passToPacmanCapture(depArguments)
- if err != nil {
- return fmt.Errorf("%s%s", stderr, err)
- }
- }
- }
- if hasAur {
- if len(dc.MakeOnly) > 0 {
- if !continueTask("Remove make dependencies after install?", "yY") {
- removeMake = true
- }
- }
- toClean, toEdit, err := cleanEditNumberMenu(dc.Aur, dc.Bases, remoteNamesCache)
- if err != nil {
- return err
- }
- cleanBuilds(toClean)
- err = downloadPkgBuilds(dc.Aur, parser.targets, dc.Bases)
- if err != nil {
- return err
- }
- if len(toEdit) > 0 {
- err = editPkgBuilds(toEdit)
- if err != nil {
- return err
- }
- }
- if len(toEdit) > 0 && !continueTask("Proceed with install?", "nN") {
- return fmt.Errorf("Aborting due to user")
- }
- //conflicts have been checked so answer y for them
- ask, _ := strconv.Atoi(cmdArgs.globals["ask"])
- uask := alpm.QuestionType(ask) | alpm.QuestionTypeConflictPkg
- cmdArgs.globals["ask"] = fmt.Sprint(uask)
- //inital srcinfo parse before pkgver() bump
- err = parsesrcinfosFile(dc.Aur, srcinfosStale, dc.Bases)
- if err != nil {
- return err
- }
- if arguments.existsArg("gendb") {
- for _, pkg := range dc.Aur {
- pkgbuild := srcinfosStale[pkg.PackageBase]
- for _, pkg := range dc.Bases[pkg.PackageBase] {
- updateVCSData(pkg.Name, pkgbuild.Source)
- }
- }
- fmt.Println(bold(green(arrow + " GenDB finished. No packages were installed")))
- return nil
- }
- incompatable, err = getIncompatable(dc.Aur, srcinfosStale, dc.Bases)
- if err != nil {
- return err
- }
- err = checkPgpKeys(dc.Aur, dc.Bases, srcinfosStale)
- if err != nil {
- return err
- }
- err = downloadPkgBuildsSources(dc.Aur, dc.Bases, incompatable)
- if err != nil {
- return err
- }
- err = parsesrcinfosGenerate(dc.Aur, srcinfos, dc.Bases)
- if err != nil {
- return err
- }
-
- err = buildInstallPkgBuilds(dc.Aur, srcinfos, parser.targets, parser, dc.Bases, incompatable)
- if err != nil {
- return err
- }
- if len(dc.MakeOnly) > 0 {
- if !removeMake {
- return nil
- }
- removeArguments := makeArguments()
- removeArguments.addArg("R", "u")
- for pkg := range dc.MakeOnly {
- removeArguments.addTarget(pkg)
- }
- oldValue := config.NoConfirm
- config.NoConfirm = true
- err = passToPacman(removeArguments)
- config.NoConfirm = oldValue
- if err != nil {
- return err
- }
- }
- if config.CleanAfter {
- clean(dc.Aur)
- }
- return nil
- }
- return nil
- }
- func getIncompatable(pkgs []*rpc.Pkg, srcinfos map[string]*gopkg.PKGBUILD, bases map[string][]*rpc.Pkg) (stringSet, error) {
- incompatable := make(stringSet)
- alpmArch, err := alpmHandle.Arch()
- if err != nil {
- return nil, err
- }
- nextpkg:
- for _, pkg := range pkgs {
- for _, arch := range srcinfos[pkg.PackageBase].Arch {
- if arch == "any" || arch == alpmArch {
- continue nextpkg
- }
- }
- incompatable.set(pkg.PackageBase)
- }
- if len(incompatable) > 0 {
- fmt.Print(
- bold(green(("\nThe following packages are not compatable with your architecture:"))))
- for pkg := range incompatable {
- fmt.Print(" " + cyan(pkg))
- }
- fmt.Println()
- if !continueTask("Try to build them anyway?", "nN") {
- return nil, fmt.Errorf("Aborting due to user")
- }
- }
- return incompatable, nil
- }
- func cleanEditNumberMenu(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, installed stringSet) ([]*rpc.Pkg, []*rpc.Pkg, error) {
- toPrint := ""
- askClean := false
- toClean := make([]*rpc.Pkg, 0)
- toEdit := make([]*rpc.Pkg, 0)
- if config.NoConfirm {
- return toClean, toEdit, nil
- }
- for n, pkg := range pkgs {
- dir := config.BuildDir + pkg.PackageBase + "/"
- toPrint += fmt.Sprintf("%s %-40s", magenta(strconv.Itoa(len(pkgs)-n)),
- bold(formatPkgbase(pkg, bases)))
- if installed.get(pkg.Name) {
- toPrint += bold(green(" (Installed)"))
- }
- if _, err := os.Stat(dir); !os.IsNotExist(err) {
- toPrint += bold(green(" (Build Files Exist)"))
- askClean = true
- }
- toPrint += "\n"
- }
- fmt.Print(toPrint)
- if askClean {
- fmt.Println(bold(green(arrow + " Packages to cleanBuild?")))
- fmt.Println(bold(green(arrow) + cyan(" [N]one ") + green("[A]ll [Ab]ort [I]nstalled [No]tInstalled or (1 2 3, 1-3, ^4)")))
- fmt.Print(bold(green(arrow + " ")))
- reader := bufio.NewReader(os.Stdin)
- numberBuf, overflow, err := reader.ReadLine()
- if err != nil {
- return nil, nil, err
- }
- if overflow {
- return nil, nil, fmt.Errorf("Input too long")
- }
- cleanInput := string(numberBuf)
- cInclude, cExclude, cOtherInclude, cOtherExclude := parseNumberMenu(cleanInput)
- cIsInclude := len(cExclude) == 0 && len(cOtherExclude) == 0
- if cOtherInclude.get("abort") || cOtherInclude.get("ab") {
- return nil, nil, fmt.Errorf("Aborting due to user")
- }
- if !cOtherInclude.get("n") && !cOtherInclude.get("none") {
- for i, pkg := range pkgs {
- dir := config.BuildDir + pkg.PackageBase + "/"
- if _, err := os.Stat(dir); os.IsNotExist(err) {
- continue
- }
- if !cIsInclude && cExclude.get(len(pkgs)-i) {
- continue
- }
- if installed.get(pkg.Name) && (cOtherInclude.get("i") || cOtherInclude.get("installed")) {
- toClean = append(toClean, pkg)
- continue
- }
- if !installed.get(pkg.Name) && (cOtherInclude.get("no") || cOtherInclude.get("notinstalled")) {
- toClean = append(toClean, pkg)
- continue
- }
- if cOtherInclude.get("a") || cOtherInclude.get("all") {
- toClean = append(toClean, pkg)
- continue
- }
- if cIsInclude && cInclude.get(len(pkgs)-i) {
- toClean = append(toClean, pkg)
- }
- if !cIsInclude && !cExclude.get(len(pkgs)-i) {
- toClean = append(toClean, pkg)
- }
- }
- }
- }
- fmt.Println(bold(green(arrow + " PKGBUILDs to edit?")))
- fmt.Println(bold(green(arrow) + cyan(" [N]one ") + green("[A]ll [Ab]ort [I]nstalled [No]tInstalled or (1 2 3, 1-3, ^4)")))
- fmt.Print(bold(green(arrow + " ")))
- reader := bufio.NewReader(os.Stdin)
- numberBuf, overflow, err := reader.ReadLine()
- if err != nil {
- return nil, nil, err
- }
- if overflow {
- return nil, nil, fmt.Errorf("Input too long")
- }
- editInput := string(numberBuf)
- eInclude, eExclude, eOtherInclude, eOtherExclude := parseNumberMenu(editInput)
- eIsInclude := len(eExclude) == 0 && len(eOtherExclude) == 0
- if eOtherInclude.get("abort") || eOtherInclude.get("ab") {
- return nil, nil, fmt.Errorf("Aborting due to user")
- }
- if !eOtherInclude.get("n") && !eOtherInclude.get("none") {
- for i, pkg := range pkgs {
- if !eIsInclude && eExclude.get(len(pkgs)-i) {
- continue
- }
- if installed.get(pkg.Name) && (eOtherInclude.get("i") || eOtherInclude.get("installed")) {
- toEdit = append(toEdit, pkg)
- continue
- }
- if !installed.get(pkg.Name) && (eOtherInclude.get("no") || eOtherInclude.get("notinstalled")) {
- toEdit = append(toEdit, pkg)
- continue
- }
- if eOtherInclude.get("a") || eOtherInclude.get("all") {
- toEdit = append(toEdit, pkg)
- continue
- }
- if eIsInclude && eInclude.get(len(pkgs)-i) {
- toEdit = append(toEdit, pkg)
- }
- if !eIsInclude && !eExclude.get(len(pkgs)-i) {
- toEdit = append(toEdit, pkg)
- }
- }
- }
- return toClean, toEdit, nil
- }
- func cleanBuilds(pkgs []*rpc.Pkg) {
- for i, pkg := range pkgs {
- dir := config.BuildDir + pkg.PackageBase
- fmt.Printf(bold(cyan("::")+" Deleting (%d/%d): %s\n"), i+1, len(pkgs), dir)
- os.RemoveAll(dir)
- }
- }
- func checkInnerConflict(name string, conflict string, conflicts map[string]stringSet, dc *depCatagories) {
- add := func(h map[string]stringSet, n string, v string) {
- _, ok := h[n]
- if !ok {
- h[n] = make(stringSet)
- }
- h[n].set(v)
- }
- deps, err := gopkg.ParseDeps([]string{conflict})
- if err != nil {
- return
- }
- dep := deps[0]
- for _, pkg := range dc.Aur {
- if name == pkg.Name {
- continue
- }
- version, err := gopkg.NewCompleteVersion(pkg.Version)
- if err != nil {
- return
- }
- if dep.Name == pkg.Name && version.Satisfies(dep) {
- add(conflicts, name, pkg.Name)
- continue
- }
- for _, provide := range pkg.Provides {
- // Provides are not versioned unless explicitly defined as
- // such. If a conflict is versioned but a provide is
- // not it can not conflict.
- if (dep.MaxVer != nil || dep.MinVer != nil) && !strings.ContainsAny(provide, "><=") {
- continue
- }
- var version *gopkg.CompleteVersion
- var err error
- pname, pversion := splitNameFromDep(provide)
- if dep.Name != pname {
- continue
- }
- if pversion != "" {
- version, err = gopkg.NewCompleteVersion(provide)
- if err != nil {
- return
- }
- }
- if version != nil && version.Satisfies(dep) {
- add(conflicts, name, pkg.Name)
- break
- }
- }
- }
- for _, pkg := range dc.Repo {
- if name == pkg.Name() {
- continue
- }
- version, err := gopkg.NewCompleteVersion(pkg.Version())
- if err != nil {
- return
- }
- if dep.Name == pkg.Name() && version.Satisfies(dep) {
- add(conflicts, name, pkg.Name())
- continue
- }
- pkg.Provides().ForEach(func(provide alpm.Depend) error {
- // Provides are not versioned unless explicitly defined as
- // such. If a conflict is versioned but a provide is
- // not it can not conflict.
- if (dep.MaxVer != nil || dep.MinVer != nil) && provide.Mod == alpm.DepModAny {
- return nil
- }
- if dep.Name != pkg.Name() {
- return nil
- }
- if provide.Mod == alpm.DepModAny {
- add(conflicts, name, pkg.Name())
- return fmt.Errorf("")
- }
- version, err := gopkg.NewCompleteVersion(provide.Version)
- if err != nil {
- return nil
- }
- if version.Satisfies(dep) {
- add(conflicts, name, pkg.Name())
- return fmt.Errorf("")
- }
- return nil
- })
- }
- }
- func checkForInnerConflicts(dc *depCatagories) (map[string]stringSet) {
- conflicts := make(map[string]stringSet)
- for _, pkg := range dc.Aur {
- for _, cpkg := range pkg.Conflicts {
- checkInnerConflict(pkg.Name, cpkg, conflicts, dc)
- }
- }
- for _, pkg := range dc.Repo {
- pkg.Conflicts().ForEach(func(conflict alpm.Depend) error {
- checkInnerConflict(pkg.Name(), conflict.String(), conflicts, dc)
- return nil
- })
- }
-
- return conflicts
- }
- func checkReverseConflict(name string, provide string, conflicts map[string]stringSet) error {
- add := func(h map[string]stringSet, n string, v string) {
- _, ok := h[n]
- if !ok {
- h[n] = make(stringSet)
- }
- h[n].set(v)
- }
- var version *gopkg.CompleteVersion
- var err error
- localDb, err := alpmHandle.LocalDb()
- if err != nil {
- return err
- }
- pname, pversion := splitNameFromDep(provide)
- if pversion != "" {
- version, err = gopkg.NewCompleteVersion(pversion)
- if err != nil {
- return nil
- }
- }
- localDb.PkgCache().ForEach(func(pkg alpm.Package) error {
- if name == pkg.Name() {
- return nil
- }
- pkg.Conflicts().ForEach(func(conflict alpm.Depend) error {
- deps, err := gopkg.ParseDeps([]string{conflict.String()})
- if err != nil {
- return nil
- }
- dep := deps[0]
- // Provides are not versioned unless explicitly defined as
- // such. If a conflict is versioned but a provide is
- // not it can not conflict.
- if (dep.MaxVer != nil || dep.MinVer != nil) && version == nil {
- return nil
- }
- if dep.Name != pname {
- return nil
- }
- if version == nil || version.Satisfies(dep) {
- // Todo
- add(conflicts, name, pkg.Name() + " (" + provide + ")")
- return fmt.Errorf("")
- }
- return nil
- })
- return nil
- })
- return nil
- }
- func checkConflict(name string, conflict string, conflicts map[string]stringSet) error {
- add := func(h map[string]stringSet, n string, v string) {
- _, ok := h[n]
- if !ok {
- h[n] = make(stringSet)
- }
- h[n].set(v)
- }
- localDb, err := alpmHandle.LocalDb()
- if err != nil {
- return err
- }
- deps, err := gopkg.ParseDeps([]string{conflict})
- if err != nil {
- return nil
- }
- dep := deps[0]
- localDb.PkgCache().ForEach(func(pkg alpm.Package) error {
- if name == pkg.Name() {
- return nil
- }
- version, err := gopkg.NewCompleteVersion(pkg.Version())
- if err != nil {
- return nil
- }
- if dep.Name == pkg.Name() && version.Satisfies(dep) {
- add(conflicts, name, pkg.Name())
- return nil
- }
- pkg.Provides().ForEach(func(provide alpm.Depend) error {
- if dep.Name != provide.Name {
- return nil
- }
- // Provides arent version unless explicitly defined as
- // such. If a conflict is versioned but a provide is
- // not it can not conflict.
- if (dep.MaxVer != nil || dep.MinVer != nil) && provide.Mod == alpm.DepModAny {
- return nil
- }
- if provide.Mod == alpm.DepModAny {
- add(conflicts, name, pkg.Name() + " (" + provide.Name + ")")
- return fmt.Errorf("")
- }
- version, err := gopkg.NewCompleteVersion(provide.Version)
- if err != nil {
- return nil
- }
- if version.Satisfies(dep) {
- add(conflicts, name, pkg.Name() + " (" + provide.Name + ")")
- return fmt.Errorf("")
- }
- return nil
- })
- return nil
- })
- return nil
- }
- func checkForConflicts(dc *depCatagories) (map[string]stringSet, error) {
- conflicts := make(map[string]stringSet)
- for _, pkg := range dc.Aur {
- for _, cpkg := range pkg.Conflicts {
- checkConflict(pkg.Name, cpkg, conflicts)
- }
- }
- for _, pkg := range dc.Repo {
- pkg.Conflicts().ForEach(func(conflict alpm.Depend) error {
- checkConflict(pkg.Name(), conflict.String(), conflicts)
- return nil
- })
- }
- for _, pkg := range dc.Aur {
- checkReverseConflict(pkg.Name, pkg.Name, conflicts)
- for _, ppkg := range pkg.Provides {
- checkReverseConflict(pkg.Name, ppkg, conflicts)
- }
- }
- for _, pkg := range dc.Repo {
- checkReverseConflict(pkg.Name(), pkg.Name(), conflicts)
- pkg.Provides().ForEach(func(provide alpm.Depend) error {
- checkReverseConflict(pkg.Name(), provide.String(), conflicts)
- return nil
- })
- }
- return conflicts, nil
- }
- func checkForAllConflicts(dc *depCatagories) error {
- var err error
- var conflicts map[string]stringSet
- var innerConflicts map[string]stringSet
- var wg sync.WaitGroup
- wg.Add(2)
-
- fmt.Println(bold(cyan("::")+ " Checking for conflicts..."))
- go func() {
- conflicts, err = checkForConflicts(dc)
- wg.Done()
- }()
- fmt.Println(bold(cyan("::")+ " Checking for inner conflicts..."))
- go func() {
- innerConflicts = checkForInnerConflicts(dc)
- wg.Done()
- }()
- wg.Wait()
- if len(innerConflicts) != 0 {
- fmt.Println(
- red("\nInner conflicts found:"))
- for name, pkgs := range innerConflicts {
- str := "\t" + name + ":"
- for pkg := range pkgs {
- str += " " + magenta(pkg)
- }
- fmt.Println(str)
- }
- return fmt.Errorf("Aborting")
- }
- if len(conflicts) != 0 {
- fmt.Println(
- red("\nPackage conflicts found:"))
- for name, pkgs := range conflicts {
- str := "\tInstalling " + magenta(name) + " will remove:"
- for pkg := range pkgs {
- str += " " + magenta(pkg)
- }
- fmt.Println(str)
- }
- fmt.Println()
- }
- return nil
- }
- func editPkgBuilds(pkgs []*rpc.Pkg) error {
- pkgbuilds := make([]string, 0, len(pkgs))
- for _, pkg := range pkgs {
- dir := config.BuildDir + pkg.PackageBase + "/"
- pkgbuilds = append(pkgbuilds, dir+"PKGBUILD")
- }
- editcmd := exec.Command(editor(), pkgbuilds...)
- editcmd.Stdin, editcmd.Stdout, editcmd.Stderr = os.Stdin, os.Stdout, os.Stderr
- err := editcmd.Run()
- if err != nil {
- return fmt.Errorf("Editor did not exit successfully, Abotring: %s", err)
- }
- return nil
- }
- func parsesrcinfosFile(pkgs []*rpc.Pkg, srcinfos map[string]*gopkg.PKGBUILD, bases map[string][]*rpc.Pkg) error {
- for k, pkg := range pkgs {
- dir := config.BuildDir + pkg.PackageBase + "/"
- str := bold(cyan("::") + " Parsing SRCINFO (%d/%d): %s\n")
- fmt.Printf(str, k+1, len(pkgs), formatPkgbase(pkg, bases))
- pkgbuild, err := gopkg.ParseSRCINFO(dir + ".SRCINFO")
- if err != nil {
- return fmt.Errorf("%s: %s", pkg.Name, err)
- }
- srcinfos[pkg.PackageBase] = pkgbuild
- }
- return nil
- }
- func parsesrcinfosGenerate(pkgs []*rpc.Pkg, srcinfos map[string]*gopkg.PKGBUILD, bases map[string][]*rpc.Pkg) error {
- for k, pkg := range pkgs {
- dir := config.BuildDir + pkg.PackageBase + "/"
- str := bold(cyan("::") + " Parsing SRCINFO (%d/%d): %s\n")
- fmt.Printf(str, k+1, len(pkgs), formatPkgbase(pkg, bases))
- cmd := exec.Command(config.MakepkgBin, "--printsrcinfo")
- cmd.Stderr = os.Stderr
- cmd.Dir = dir
- srcinfo, err := cmd.Output()
- if err != nil {
- return err
- }
- pkgbuild, err := gopkg.ParseSRCINFOContent(srcinfo)
- if err != nil {
- return fmt.Errorf("%s: %s", pkg.Name, err)
- }
- srcinfos[pkg.PackageBase] = pkgbuild
- }
- return nil
- }
- func downloadPkgBuilds(pkgs []*rpc.Pkg, targets stringSet, bases map[string][]*rpc.Pkg) error {
- for k, pkg := range pkgs {
- if config.ReDownload == "no" || (config.ReDownload == "yes" && !targets.get(pkg.Name)) {
- dir := config.BuildDir + pkg.PackageBase + "/.SRCINFO"
- pkgbuild, err := gopkg.ParseSRCINFO(dir)
- if err == nil {
- version, err := gopkg.NewCompleteVersion(pkg.Version)
- if err == nil {
- if !version.Newer(pkgbuild.Version()) {
- str := bold(cyan("::") + " PKGBUILD up to date, Skipping (%d/%d): %s\n")
- fmt.Printf(str, k+1, len(pkgs), formatPkgbase(pkg, bases))
- continue
- }
- }
- }
- }
- str := bold(cyan("::") + " Downloading PKGBUILD (%d/%d): %s\n")
- fmt.Printf(str, k+1, len(pkgs), formatPkgbase(pkg, bases))
- err := downloadAndUnpack(baseURL+pkg.URLPath, config.BuildDir, false)
- if err != nil {
- return err
- }
- }
- return nil
- }
- func downloadPkgBuildsSources(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, incompatable stringSet) (err error) {
- for _, pkg := range pkgs {
- dir := config.BuildDir + pkg.PackageBase + "/"
- args := []string{"--nobuild", "--nocheck", "--noprepare", "--nodeps"}
- if incompatable.get(pkg.PackageBase) {
- args = append(args, "--ignorearch")
- }
- err = passToMakepkg(dir, args...)
- if err != nil {
- return fmt.Errorf("Error downloading sources: %s", formatPkgbase(pkg, bases))
- }
- }
- return
- }
- func buildInstallPkgBuilds(pkgs []*rpc.Pkg, srcinfos map[string]*gopkg.PKGBUILD, targets stringSet, parser *arguments, bases map[string][]*rpc.Pkg, incompatable stringSet) error {
- alpmArch, err := alpmHandle.Arch()
- if err != nil {
- return err
- }
- for _, pkg := range pkgs {
- var arch string
- dir := config.BuildDir + pkg.PackageBase + "/"
- built := true
- srcinfo := srcinfos[pkg.PackageBase]
- version := srcinfo.CompleteVersion()
- if srcinfos[pkg.PackageBase].Arch[0] == "any" {
- arch = "any"
- } else {
- arch = alpmArch
- }
- if config.ReBuild == "no" || (config.ReBuild == "yes" && !targets.get(pkg.Name)) {
- for _, split := range bases[pkg.PackageBase] {
- file, err := completeFileName(dir, split.Name+"-"+version.String()+"-"+arch+".pkg")
- if err != nil {
- return err
- }
- if file == "" {
- built = false
- }
- }
- } else {
- built = false
- }
- if built {
- fmt.Println(bold(red(arrow+" Warning:")),
- pkg.Name+"-"+pkg.Version+" Already made -- skipping build")
- } else {
- args := []string{"-Ccf", "--noconfirm"}
- if incompatable.get(pkg.PackageBase) {
- args = append(args, "--ignorearch")
- }
- err := passToMakepkg(dir, args...)
- if err != nil {
- return fmt.Errorf("Error making: %s", pkg.Name)
- }
- }
- arguments := parser.copy()
- arguments.targets = make(stringSet)
- arguments.op = "U"
- arguments.delArg("confirm")
- arguments.delArg("c", "clean")
- arguments.delArg("q", "quiet")
- arguments.delArg("q", "quiet")
- arguments.delArg("y", "refresh")
- arguments.delArg("u", "sysupgrade")
- arguments.delArg("w", "downloadonly")
- depArguments := makeArguments()
- depArguments.addArg("D", "asdeps")
- for _, split := range bases[pkg.PackageBase] {
- file, err := completeFileName(dir, split.Name+"-"+version.String()+"-"+arch+".pkg")
- if err != nil {
- return err
- }
- if file == "" {
- return fmt.Errorf("Could not find built package " + split.Name + "-" + version.String() + "-" + arch + ".pkg")
- }
- arguments.addTarget(file)
- if !targets.get(split.Name) {
- depArguments.addTarget(split.Name)
- }
- }
- oldConfirm := config.NoConfirm
- config.NoConfirm = true
- err := passToPacman(arguments)
- if err != nil {
- return err
- }
- for _, pkg := range bases[pkg.PackageBase] {
- updateVCSData(pkg.Name, srcinfo.Source)
- }
- if len(depArguments.targets) > 0 {
- _, stderr, err := passToPacmanCapture(depArguments)
- if err != nil {
- return fmt.Errorf("%s%s", stderr, err)
- }
- }
- config.NoConfirm = oldConfirm
- }
- return nil
- }
- func clean(pkgs []*rpc.Pkg) {
- for _, pkg := range pkgs {
- dir := config.BuildDir + pkg.PackageBase + "/"
- fmt.Println(bold(green(arrow +
- " CleanAfter enabled. Deleting " + pkg.Name + " source folder.")))
- os.RemoveAll(dir)
- }
- }
- func completeFileName(dir, name string) (string, error) {
- files, err := ioutil.ReadDir(dir)
- if err != nil {
- return "", err
- }
- for _, file := range files {
- if file.IsDir() {
- continue
- }
- if strings.HasPrefix(file.Name(), name) {
- return dir + file.Name(), nil
- }
- }
- return "", nil
- }
|