diff --git a/install.go b/install.go index f2172351..1e36e93d 100644 --- a/install.go +++ b/install.go @@ -16,13 +16,15 @@ import ( // Install handles package installs func install(parser *arguments) error { - removeMake := false requestTargets := parser.targets.toSlice() aurTargets, repoTargets, err := packageSlices(requestTargets) 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 @@ -200,26 +202,37 @@ func install(parser *arguments) error { uask := alpm.QuestionType(ask) | alpm.QuestionTypeConflictPkg cmdArgs.globals["ask"] = fmt.Sprint(uask) - //this downloads the package build sources but also causes - //a version bumb for vsc packages - //that should not edit the sources so we should be safe to skip - //it and parse the srcinfo at the current version + //inital srcinfo parse before pkgver() bump + err = parsesrcinfosFile(dc.Aur, srcinfosStale, dc.Bases) + if err != nil { + return err + } + if arguments.existsArg("gendb") { - err = parsesrcinfosFile(dc.Aur, srcinfos, dc.Bases) - if err != nil { - return err + 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 } - err = checkPgpKeys(dc.Aur, dc.Bases) + incompatable, err = getIncompatable(dc.Aur, srcinfosStale, dc.Bases) if err != nil { return err } - err = downloadPkgBuildsSources(dc.Aur, dc.Bases) + + err = checkPgpKeys(dc.Aur, dc.Bases, srcinfosStale) + if err != nil { + return err + } + + err = downloadPkgBuildsSources(dc.Aur, dc.Bases, incompatable) if err != nil { return err } @@ -228,8 +241,8 @@ func install(parser *arguments) error { if err != nil { return err } - - err = buildInstallPkgBuilds(dc.Aur, srcinfos, parser.targets, parser, dc.Bases) + + err = buildInstallPkgBuilds(dc.Aur, srcinfos, parser.targets, parser, dc.Bases, incompatable) if err != nil { return err } @@ -266,6 +279,41 @@ func install(parser *arguments) error { 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 @@ -502,12 +550,7 @@ func parsesrcinfosFile(pkgs []*rpc.Pkg, srcinfos map[string]*gopkg.PKGBUILD, bas return fmt.Errorf("%s: %s", pkg.Name, err) } - srcinfos[pkg.PackageBase] = pkgbuild - - for _, pkg := range bases[pkg.PackageBase] { - updateVCSData(pkg.Name, pkgbuild.Source) - } - + srcinfos[pkg.PackageBase] = pkgbuild } return nil @@ -571,10 +614,16 @@ func downloadPkgBuilds(pkgs []*rpc.Pkg, targets stringSet, bases map[string][]*r return nil } -func downloadPkgBuildsSources(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg) (err error) { +func downloadPkgBuildsSources(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, incompatable stringSet) (err error) { for _, pkg := range pkgs { dir := config.BuildDir + pkg.PackageBase + "/" - err = passToMakepkg(dir, "--nobuild", "--nocheck", "--noprepare", "--nodeps") + 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)) } @@ -583,7 +632,7 @@ func downloadPkgBuildsSources(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg) (err return } -func buildInstallPkgBuilds(pkgs []*rpc.Pkg, srcinfos map[string]*gopkg.PKGBUILD, targets stringSet, parser *arguments, bases map[string][]*rpc.Pkg) error { +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 @@ -622,7 +671,13 @@ func buildInstallPkgBuilds(pkgs []*rpc.Pkg, srcinfos map[string]*gopkg.PKGBUILD, fmt.Println(bold(red(arrow+" Warning:")), pkg.Name+"-"+pkg.Version+" Already made -- skipping build") } else { - err := passToMakepkg(dir, "-Ccf", "--noconfirm") + 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) } diff --git a/keys.go b/keys.go index dc600d0f..945e5e07 100644 --- a/keys.go +++ b/keys.go @@ -5,7 +5,6 @@ import ( "fmt" "os" "os/exec" - "path" "strings" rpc "github.com/mikkeloscar/aur" @@ -42,7 +41,7 @@ func (set pgpKeySet) get(key string) bool { // checkPgpKeys iterates through the keys listed in the PKGBUILDs and if needed, // asks the user whether yay should try to import them. -func checkPgpKeys(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg) error { +func checkPgpKeys(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, srcinfos map[string]*gopkg.PKGBUILD) error { // Let's check the keys individually, and then we can offer to import // the problematic ones. problematic := make(pgpKeySet) @@ -50,13 +49,9 @@ func checkPgpKeys(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg) error { // Mapping all the keys. for _, pkg := range pkgs { - srcinfo := path.Join(config.BuildDir, pkg.PackageBase, ".SRCINFO") - pkgbuild, err := gopkg.ParseSRCINFO(srcinfo) - if err != nil { - return fmt.Errorf("%s: %s", pkg.Name, err) - } + srcinfo := srcinfos[pkg.PackageBase] - for _, key := range pkgbuild.Validpgpkeys { + for _, key := range srcinfo.Validpgpkeys { // If key already marked as problematic, indicate the current // PKGBUILD requires it. if problematic.get(key) { @@ -77,6 +72,7 @@ func checkPgpKeys(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg) error { return nil } + fmt.Println() question, err := formatKeysToImport(problematic, bases) if err != nil { return err diff --git a/keys_test.go b/keys_test.go index 12fc6c05..078cdf29 100644 --- a/keys_test.go +++ b/keys_test.go @@ -1,11 +1,9 @@ package main import ( - "bytes" "fmt" "io/ioutil" "os" - "path" "testing" rpc "github.com/mikkeloscar/aur" @@ -20,31 +18,6 @@ func newSplitPkg(basename, name string) *rpc.Pkg { return &rpc.Pkg{Name: name, PackageBase: basename} } -func createSrcinfo(pkgbase, srcinfoData string) error { - dir := path.Join(config.BuildDir, pkgbase) - if err := os.Mkdir(dir, 0755); err != nil { - return err - } - - return ioutil.WriteFile(path.Join(dir, ".SRCINFO"), []byte(srcinfoData), 0666) -} - -func createDummyPkg(pkgbase string, keys []string, split []string) string { - var buffer bytes.Buffer - buffer.WriteString(fmt.Sprintf("pkgbase = %s\n\tpkgver = 42\n\tarch = x86_64\n", pkgbase)) - // Keys. - for _, k := range keys { - buffer.WriteString(fmt.Sprintf("validpgpkeys = %s\n", k)) - } - - buffer.WriteString(fmt.Sprintf("\npkgname = %s\n", pkgbase)) - - for _, s := range split { - buffer.WriteString(fmt.Sprintf("\npkgname = %s%s\n", pkgbase, s)) - } - return buffer.String() -} - func TestFormatKeysToImport(t *testing.T) { casetests := []struct { keySet pgpKeySet @@ -214,25 +187,6 @@ func TestCheckPgpKeys(t *testing.T) { config.GpgBin = "gpg" config.GpgFlags = fmt.Sprintf("--homedir %s", keyringDir) - // Creating the dummy package data used in the tests. - dummyData := map[string]string{ - "cower": createDummyPkg("cower", []string{"487EACC08557AD082088DABA1EB2638FF56C0C53"}, nil), - "libc++": createDummyPkg("libc++", []string{"11E521D646982372EB577A1F8F0871F202119294", "B6C8F98282B944E3B0D5C2530FC3042E345AD05D"}, []string{"abi", "experimental"}), - "dummy-1": createDummyPkg("dummy-1", []string{"ABAF11C65A2970B130ABE3C479BE3E4300411886"}, nil), - "dummy-2": createDummyPkg("dummy-2", []string{"ABAF11C65A2970B130ABE3C479BE3E4300411886"}, nil), - "dummy-3": createDummyPkg("dummy-3", []string{"11E521D646982372EB577A1F8F0871F202119294", "C52048C0C0748FEE227D47A2702353E0F7E48EDB"}, nil), - "dummy-4": createDummyPkg("dummy-4", []string{"11E521D646982372EB577A1F8F0871F202119294"}, nil), - "dummy-5": createDummyPkg("dummy-5", []string{"C52048C0C0748FEE227D47A2702353E0F7E48EDB"}, nil), - "dummy-6": createDummyPkg("dummy-6", []string{"THIS-SHOULD-FAIL"}, nil), - "dummy-7": createDummyPkg("dummy-7", []string{"A314827C4E4250A204CE6E13284FC34C8E4B1A25", "THIS-SHOULD-FAIL"}, nil), - } - - for pkgbase, srcinfoData := range dummyData { - if err = createSrcinfo(pkgbase, srcinfoData); err != nil { - t.Fatalf("Unable to create dummy data for package %q: %v\n", pkgbase, err) - } - } - casetests := []struct { pkgs []*rpc.Pkg srcinfos map[string]*gopkg.PKGBUILD @@ -243,6 +197,7 @@ func TestCheckPgpKeys(t *testing.T) { // 487EACC08557AD082088DABA1EB2638FF56C0C53: Dave Reisner. { pkgs: []*rpc.Pkg{newPkg("cower")}, + srcinfos: map[string]*gopkg.PKGBUILD{"cower": &gopkg.PKGBUILD{Pkgbase: "cower", Validpgpkeys: []string{"487EACC08557AD082088DABA1EB2638FF56C0C53"}}}, bases: map[string][]*rpc.Pkg{"cower": {newPkg("cower")}}, wantError: false, }, @@ -251,6 +206,7 @@ func TestCheckPgpKeys(t *testing.T) { // B6C8F98282B944E3B0D5C2530FC3042E345AD05D: Hans Wennborg. { pkgs: []*rpc.Pkg{newPkg("libc++")}, + srcinfos: map[string]*gopkg.PKGBUILD{"libc++": &gopkg.PKGBUILD{Pkgbase: "libc++", Validpgpkeys: []string{"11E521D646982372EB577A1F8F0871F202119294", "B6C8F98282B944E3B0D5C2530FC3042E345AD05D"}}}, bases: map[string][]*rpc.Pkg{"libc++": {newPkg("libc++")}}, wantError: false, }, @@ -258,6 +214,7 @@ func TestCheckPgpKeys(t *testing.T) { // ABAF11C65A2970B130ABE3C479BE3E4300411886: Linus Torvalds. { pkgs: []*rpc.Pkg{newPkg("dummy-1"), newPkg("dummy-2")}, + srcinfos: map[string]*gopkg.PKGBUILD{"dummy-1": &gopkg.PKGBUILD{Pkgbase: "dummy-1", Validpgpkeys: []string{"ABAF11C65A2970B130ABE3C479BE3E4300411886"}}, "dummy-2": &gopkg.PKGBUILD{Pkgbase: "dummy-2", Validpgpkeys: []string{"ABAF11C65A2970B130ABE3C479BE3E4300411886"}}}, bases: map[string][]*rpc.Pkg{"dummy-1": {newPkg("dummy-1")}, "dummy-2": {newPkg("dummy-2")}}, wantError: false, }, @@ -267,32 +224,36 @@ func TestCheckPgpKeys(t *testing.T) { // C52048C0C0748FEE227D47A2702353E0F7E48EDB: Thomas Dickey. { pkgs: []*rpc.Pkg{newPkg("dummy-3")}, + srcinfos: map[string]*gopkg.PKGBUILD{"dummy-3": &gopkg.PKGBUILD{Pkgbase: "dummy-3", Validpgpkeys: []string{"11E521D646982372EB577A1F8F0871F202119294", "C52048C0C0748FEE227D47A2702353E0F7E48EDB"}}}, bases: map[string][]*rpc.Pkg{"dummy-3": {newPkg("dummy-3")}}, wantError: false, }, // Two dummy packages with existing keys. { pkgs: []*rpc.Pkg{newPkg("dummy-4"), newPkg("dummy-5")}, + srcinfos: map[string]*gopkg.PKGBUILD{"dummy-4": &gopkg.PKGBUILD{Pkgbase: "dummy-4", Validpgpkeys: []string{"11E521D646982372EB577A1F8F0871F202119294"}}, "dummy-5": &gopkg.PKGBUILD{Pkgbase: "dummy-5", Validpgpkeys: []string{"C52048C0C0748FEE227D47A2702353E0F7E48EDB"}}}, bases: map[string][]*rpc.Pkg{"dummy-4": {newPkg("dummy-4")}, "dummy-5": {newPkg("dummy-5")}}, wantError: false, }, // Dummy package with invalid key, should fail. { - pkgs: []*rpc.Pkg{newPkg("dummy-6")}, - bases: map[string][]*rpc.Pkg{"dummy-6": {newPkg("dummy-6")}}, + pkgs: []*rpc.Pkg{newPkg("dummy-7")}, + srcinfos: map[string]*gopkg.PKGBUILD{"dummy-7": &gopkg.PKGBUILD{Pkgbase: "dummy-7", Validpgpkeys: []string{"THIS-SHOULD-FAIL"}}}, + bases: map[string][]*rpc.Pkg{"dummy-7": {newPkg("dummy-7")}}, wantError: true, }, // Dummy package with both an invalid an another valid key, should fail. // A314827C4E4250A204CE6E13284FC34C8E4B1A25: Thomas Bächler. { - pkgs: []*rpc.Pkg{newPkg("dummy-7")}, - bases: map[string][]*rpc.Pkg{"dummy-7": {newPkg("dummy-7")}}, + pkgs: []*rpc.Pkg{newPkg("dummy-8")}, + srcinfos: map[string]*gopkg.PKGBUILD{"dummy-8": &gopkg.PKGBUILD{Pkgbase: "dummy-8", Validpgpkeys: []string{"A314827C4E4250A204CE6E13284FC34C8E4B1A25", "THIS-SHOULD-FAIL"}}}, + bases: map[string][]*rpc.Pkg{"dummy-8": {newPkg("dummy-8")}}, wantError: true, }, } for _, tt := range casetests { - err := checkPgpKeys(tt.pkgs, tt.bases) + err := checkPgpKeys(tt.pkgs, tt.bases, tt.srcinfos) if !tt.wantError { if err != nil { t.Fatalf("Got error %q, want no error", err)