fix(news): package news and begin settings

This commit is contained in:
jguer 2020-07-05 02:01:08 +02:00
parent fff9d74764
commit cb8a988701
No known key found for this signature in database
GPG key ID: 6D6CC9BEA8556B35
17 changed files with 418 additions and 382 deletions

View file

@ -8,6 +8,7 @@ import (
"github.com/leonelquinteros/gotext"
"github.com/Jguer/yay/v10/pkg/query"
"github.com/Jguer/yay/v10/pkg/stringset"
"github.com/Jguer/yay/v10/pkg/text"
)
@ -116,7 +117,7 @@ func cleanAUR(keepInstalled, keepCurrent, removeAll bool) error {
installedBases := make(stringset.StringSet)
inAURBases := make(stringset.StringSet)
_, remotePackages, _, _, err := filterPackages()
_, remotePackages, _, _, err := query.FilterPackages(alpmHandle)
if err != nil {
return err
}

20
cmd.go
View file

@ -11,6 +11,8 @@ import (
"github.com/Jguer/yay/v10/pkg/completion"
"github.com/Jguer/yay/v10/pkg/intrange"
"github.com/Jguer/yay/v10/pkg/news"
"github.com/Jguer/yay/v10/pkg/settings"
"github.com/Jguer/yay/v10/pkg/text"
)
@ -198,7 +200,7 @@ func handlePrint() (err error) {
switch {
case cmdArgs.existsArg("d", "defaultconfig"):
tmpConfig := defaultSettings()
tmpConfig.expandEnv()
tmpConfig.ExpandEnv()
fmt.Printf("%v", tmpConfig)
case cmdArgs.existsArg("g", "currentconfig"):
fmt.Printf("%v", config)
@ -207,7 +209,9 @@ func handlePrint() (err error) {
case cmdArgs.existsArg("u", "upgrades"):
err = printUpdateList(cmdArgs)
case cmdArgs.existsArg("w", "news"):
err = printNewsFeed()
_, double, _ := cmdArgs.getArg("news", "w")
quiet := cmdArgs.existsArg("q", "quiet")
err = news.PrintNewsFeed(alpmHandle, config.SortMode, double, quiet)
case cmdArgs.existsDouble("c", "complete"):
err = completion.Show(alpmHandle, config.AURURL, cacheHome, config.CompletionInterval, true)
case cmdArgs.existsArg("c", "complete"):
@ -320,14 +324,14 @@ func displayNumberMenu(pkgS []string) error {
}
switch config.SortMode {
case topDown:
case settings.TopDown:
if mode == modeRepo || mode == modeAny {
pq.printSearch()
}
if mode == modeAUR || mode == modeAny {
aq.printSearch(lenpq + 1)
}
case bottomUp:
case settings.BottomUp:
if mode == modeAUR || mode == modeAny {
aq.printSearch(lenpq + 1)
}
@ -364,9 +368,9 @@ func displayNumberMenu(pkgS []string) error {
for i, pkg := range pq {
var target int
switch config.SortMode {
case topDown:
case settings.TopDown:
target = i + 1
case bottomUp:
case settings.BottomUp:
target = len(pq) - i
default:
return fmt.Errorf(gotext.Get("invalid sort mode. Fix with yay -Y --bottomup --save"))
@ -381,9 +385,9 @@ func displayNumberMenu(pkgS []string) error {
var target int
switch config.SortMode {
case topDown:
case settings.TopDown:
target = i + 1 + len(pq)
case bottomUp:
case settings.BottomUp:
target = len(aq) - i + len(pq)
default:
return fmt.Errorf(gotext.Get("invalid sort mode. Fix with yay -Y --bottomup --save"))

119
config.go
View file

@ -2,8 +2,6 @@ package main
import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"os"
"os/exec"
@ -13,6 +11,7 @@ import (
pacmanconf "github.com/Morganamilo/go-pacmanconf"
"github.com/leonelquinteros/gotext"
"github.com/Jguer/yay/v10/pkg/settings"
"github.com/Jguer/yay/v10/pkg/text"
)
@ -23,12 +22,6 @@ const (
minimal
)
const (
// Describes Sorting method for numberdisplay
bottomUp = iota
topDown
)
const (
modeAUR targetMode = iota
modeRepo
@ -37,53 +30,6 @@ const (
type targetMode int
// Configuration stores yay's config.
type Configuration struct {
AURURL string `json:"aururl"`
BuildDir string `json:"buildDir"`
ABSDir string `json:"absdir"`
Editor string `json:"editor"`
EditorFlags string `json:"editorflags"`
MakepkgBin string `json:"makepkgbin"`
MakepkgConf string `json:"makepkgconf"`
PacmanBin string `json:"pacmanbin"`
PacmanConf string `json:"pacmanconf"`
ReDownload string `json:"redownload"`
ReBuild string `json:"rebuild"`
AnswerClean string `json:"answerclean"`
AnswerDiff string `json:"answerdiff"`
AnswerEdit string `json:"answeredit"`
AnswerUpgrade string `json:"answerupgrade"`
GitBin string `json:"gitbin"`
GpgBin string `json:"gpgbin"`
GpgFlags string `json:"gpgflags"`
MFlags string `json:"mflags"`
SortBy string `json:"sortby"`
SearchBy string `json:"searchby"`
GitFlags string `json:"gitflags"`
RemoveMake string `json:"removemake"`
SudoBin string `json:"sudobin"`
SudoFlags string `json:"sudoflags"`
RequestSplitN int `json:"requestsplitn"`
SearchMode int `json:"-"`
SortMode int `json:"sortmode"`
CompletionInterval int `json:"completionrefreshtime"`
SudoLoop bool `json:"sudoloop"`
TimeUpdate bool `json:"timeupdate"`
NoConfirm bool `json:"-"`
Devel bool `json:"devel"`
CleanAfter bool `json:"cleanAfter"`
Provides bool `json:"provides"`
PGPFetch bool `json:"pgpfetch"`
UpgradeMenu bool `json:"upgrademenu"`
CleanMenu bool `json:"cleanmenu"`
DiffMenu bool `json:"diffmenu"`
EditMenu bool `json:"editmenu"`
CombinedUpgrade bool `json:"combinedupgrade"`
UseAsk bool `json:"useask"`
BatchInstall bool `json:"batchinstall"`
}
var yayVersion = "10.0.0"
var localePath = "/usr/share/locale"
@ -113,7 +59,7 @@ var vcsFile string
var shouldSaveConfig bool
// YayConf holds the current config values for yay.
var config *Configuration
var config *settings.Configuration
// AlpmConf holds the current config values for pacman.
var pacmanConf *pacmanconf.Config
@ -126,25 +72,8 @@ var mode = modeAny
var hideMenus = false
// SaveConfig writes yay config to file.
func (config *Configuration) saveConfig() error {
marshalledinfo, err := json.MarshalIndent(config, "", "\t")
if err != nil {
return err
}
in, err := os.OpenFile(configFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
return err
}
defer in.Close()
if _, err = in.Write(marshalledinfo); err != nil {
return err
}
return in.Sync()
}
func defaultSettings() *Configuration {
newConfig := &Configuration{
func defaultSettings() *settings.Configuration {
newConfig := &settings.Configuration{
AURURL: "https://aur.archlinux.org",
BuildDir: "$HOME/.cache/yay",
ABSDir: "$HOME/.cache/yay/abs",
@ -161,7 +90,7 @@ func defaultSettings() *Configuration {
GpgFlags: "",
MFlags: "",
GitFlags: "",
SortMode: bottomUp,
SortMode: settings.BottomUp,
CompletionInterval: 7,
SortBy: "votes",
SearchBy: "name-desc",
@ -196,34 +125,6 @@ func defaultSettings() *Configuration {
return newConfig
}
func (config *Configuration) expandEnv() {
config.AURURL = os.ExpandEnv(config.AURURL)
config.ABSDir = os.ExpandEnv(config.ABSDir)
config.BuildDir = os.ExpandEnv(config.BuildDir)
config.Editor = os.ExpandEnv(config.Editor)
config.EditorFlags = os.ExpandEnv(config.EditorFlags)
config.MakepkgBin = os.ExpandEnv(config.MakepkgBin)
config.MakepkgConf = os.ExpandEnv(config.MakepkgConf)
config.PacmanBin = os.ExpandEnv(config.PacmanBin)
config.PacmanConf = os.ExpandEnv(config.PacmanConf)
config.GpgFlags = os.ExpandEnv(config.GpgFlags)
config.MFlags = os.ExpandEnv(config.MFlags)
config.GitFlags = os.ExpandEnv(config.GitFlags)
config.SortBy = os.ExpandEnv(config.SortBy)
config.SearchBy = os.ExpandEnv(config.SearchBy)
config.GitBin = os.ExpandEnv(config.GitBin)
config.GpgBin = os.ExpandEnv(config.GpgBin)
config.SudoBin = os.ExpandEnv(config.SudoBin)
config.SudoFlags = os.ExpandEnv(config.SudoFlags)
config.ReDownload = os.ExpandEnv(config.ReDownload)
config.ReBuild = os.ExpandEnv(config.ReBuild)
config.AnswerClean = os.ExpandEnv(config.AnswerClean)
config.AnswerDiff = os.ExpandEnv(config.AnswerDiff)
config.AnswerEdit = os.ExpandEnv(config.AnswerEdit)
config.AnswerUpgrade = os.ExpandEnv(config.AnswerUpgrade)
config.RemoveMake = os.ExpandEnv(config.RemoveMake)
}
// Editor returns the preferred system editor.
func editor() (editor string, args []string) {
switch {
@ -334,16 +235,6 @@ func getInput(defaultValue string) (string, error) {
return string(buf), nil
}
func (config *Configuration) String() string {
var buf bytes.Buffer
enc := json.NewEncoder(&buf)
enc.SetIndent("", "\t")
if err := enc.Encode(config); err != nil {
fmt.Fprintln(os.Stderr, err)
}
return buf.String()
}
func toUsage(usages []string) alpm.Usage {
if len(usages) == 0 {
return alpm.UsageAll

View file

@ -13,11 +13,8 @@ func expect(t *testing.T, field string, a interface{}, b interface{}, err error)
}
}
func TestConfig(t *testing.T) {
config = &Configuration{}
config.PacmanConf = "./testdata/pacman.conf"
err := initAlpm()
func TestAlpmConfig(t *testing.T) {
err := initAlpm("testdata/pacman.conf")
if err != nil {
t.Fatal(err)
}

View file

@ -17,6 +17,7 @@ import (
"github.com/Jguer/yay/v10/pkg/completion"
"github.com/Jguer/yay/v10/pkg/intrange"
"github.com/Jguer/yay/v10/pkg/multierror"
"github.com/Jguer/yay/v10/pkg/query"
"github.com/Jguer/yay/v10/pkg/stringset"
"github.com/Jguer/yay/v10/pkg/text"
)
@ -88,7 +89,7 @@ func install(parser *arguments) (err error) {
return err
}
_, _, localNames, remoteNames, err := filterPackages()
_, _, localNames, remoteNames, err := query.FilterPackages(alpmHandle)
if err != nil {
return err
}
@ -951,7 +952,7 @@ func buildInstallPkgbuilds(
config.NoConfirm = true
//remotenames: names of all non repo packages on the system
_, _, localNames, remoteNames, err := filterPackages()
_, _, localNames, remoteNames, err := query.FilterPackages(alpmHandle)
if err != nil {
return err
}

View file

@ -72,6 +72,7 @@ func TestImportKeys(t *testing.T) {
}
defer os.RemoveAll(keyringDir)
config = defaultSettings()
config.GpgBin = "gpg"
config.GpgFlags = fmt.Sprintf("--homedir %s --keyserver 127.0.0.1", keyringDir)

10
main.go
View file

@ -117,7 +117,7 @@ func initBuildDir() error {
return nil
}
func initAlpm() error {
func initAlpm(pacmanConfigPath string) error {
var err error
var stderr string
@ -126,7 +126,7 @@ func initAlpm() error {
root = value
}
pacmanConf, stderr, err = pacmanconf.PacmanConf("--config", config.PacmanConf, "--root", root)
pacmanConf, stderr, err = pacmanconf.PacmanConf("--config", pacmanConfigPath, "--root", root)
if err != nil {
return fmt.Errorf("%s", stderr)
}
@ -231,15 +231,15 @@ func main() {
exitOnError(initConfig())
exitOnError(cmdArgs.parseCommandLine())
if shouldSaveConfig {
err := config.saveConfig()
err := config.SaveConfig(configFile)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
}
config.expandEnv()
config.ExpandEnv()
exitOnError(initBuildDir())
exitOnError(initVCS())
exitOnError(initAlpm())
exitOnError(initAlpm(config.PacmanConf))
exitOnError(handleCmd())
os.Exit(cleanup())
}

View file

@ -2,8 +2,6 @@ package main
import (
"bufio"
"bytes"
"html"
"os"
"strconv"
"strings"
@ -12,6 +10,7 @@ import (
rpc "github.com/mikkeloscar/aur"
"github.com/pkg/errors"
"github.com/Jguer/yay/v10/pkg/settings"
"github.com/Jguer/yay/v10/pkg/stringset"
)
@ -474,9 +473,9 @@ func handleConfig(option, value string) bool {
case "notimeupdate":
config.TimeUpdate = false
case "topdown":
config.SortMode = topDown
config.SortMode = settings.TopDown
case "bottomup":
config.SortMode = bottomUp
config.SortMode = settings.BottomUp
case "completioninterval":
n, err := strconv.Atoi(value)
if err == nil {
@ -849,66 +848,3 @@ func (parser *arguments) extractYayOptions() {
rpc.AURURL = strings.TrimRight(config.AURURL, "/") + "/rpc.php?"
config.AURURL = strings.TrimRight(config.AURURL, "/")
}
// Crude html parsing, good enough for the arch news
// This is only displayed in the terminal so there should be no security
// concerns
func parseNews(str string) string {
var buffer bytes.Buffer
var tagBuffer bytes.Buffer
var escapeBuffer bytes.Buffer
inTag := false
inEscape := false
for _, char := range str {
if inTag {
if char == '>' {
inTag = false
switch tagBuffer.String() {
case "code":
buffer.WriteString(cyanCode)
case "/code":
buffer.WriteString(resetCode)
case "/p":
buffer.WriteRune('\n')
}
continue
}
tagBuffer.WriteRune(char)
continue
}
if inEscape {
if char == ';' {
inEscape = false
escapeBuffer.WriteRune(char)
s := html.UnescapeString(escapeBuffer.String())
buffer.WriteString(s)
continue
}
escapeBuffer.WriteRune(char)
continue
}
if char == '<' {
inTag = true
tagBuffer.Reset()
continue
}
if char == '&' {
inEscape = true
escapeBuffer.Reset()
escapeBuffer.WriteRune(char)
continue
}
buffer.WriteRune(char)
}
buffer.WriteString(resetCode)
return buffer.String()
}

182
pkg/news/news.go Normal file
View file

@ -0,0 +1,182 @@
package news
import (
"bytes"
"encoding/xml"
"fmt"
"html"
"io/ioutil"
"net/http"
"os"
"strings"
"time"
"github.com/Jguer/go-alpm"
"github.com/Jguer/yay/v10/pkg/query"
"github.com/Jguer/yay/v10/pkg/settings"
"github.com/Jguer/yay/v10/pkg/text"
)
type item struct {
Title string `xml:"title"`
Link string `xml:"link"`
Description string `xml:"description"`
PubDate string `xml:"pubDate"`
Creator string `xml:"dc:creator"`
}
func (item *item) print(buildTime time.Time, double, quiet bool) {
var fd string
date, err := time.Parse(time.RFC1123Z, item.PubDate)
if err != nil {
fmt.Fprintln(os.Stderr, err)
} else {
fd = text.FormatTime(int(date.Unix()))
if !double && !buildTime.IsZero() {
if buildTime.After(date) {
return
}
}
}
fmt.Println(text.Bold(text.Magenta(fd)), text.Bold(strings.TrimSpace(item.Title)))
if !quiet {
desc := strings.TrimSpace(parseNews(item.Description))
fmt.Println(desc)
}
}
type channel struct {
Title string `xml:"title"`
Link string `xml:"link"`
Description string `xml:"description"`
Language string `xml:"language"`
Lastbuilddate string `xml:"lastbuilddate"`
Items []item `xml:"item"`
}
type rss struct {
Channel channel `xml:"channel"`
}
func PrintNewsFeed(alpmHandle *alpm.Handle, sortMode int, double, quiet bool) error {
resp, err := http.Get("https://archlinux.org/feeds/news")
if err != nil {
return err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
rssGot := rss{}
d := xml.NewDecoder(bytes.NewReader(body))
err = d.Decode(&rssGot)
if err != nil {
return err
}
buildTime, err := lastBuildTime(alpmHandle)
if err != nil {
return err
}
if sortMode == settings.BottomUp {
for i := len(rssGot.Channel.Items) - 1; i >= 0; i-- {
rssGot.Channel.Items[i].print(buildTime, double, quiet)
}
} else {
for i := 0; i < len(rssGot.Channel.Items); i++ {
rssGot.Channel.Items[i].print(buildTime, double, quiet)
}
}
return nil
}
func lastBuildTime(alpmHandle *alpm.Handle) (time.Time, error) {
var lastTime time.Time
pkgs, _, _, _, err := query.FilterPackages(alpmHandle)
if err != nil {
return lastTime, err
}
for _, pkg := range pkgs {
thisTime := pkg.BuildDate()
if thisTime.After(lastTime) {
lastTime = thisTime
}
}
return lastTime, nil
}
// Crude html parsing, good enough for the arch news
// This is only displayed in the terminal so there should be no security
// concerns
func parseNews(str string) string {
var buffer bytes.Buffer
var tagBuffer bytes.Buffer
var escapeBuffer bytes.Buffer
inTag := false
inEscape := false
for _, char := range str {
if inTag {
if char == '>' {
inTag = false
switch tagBuffer.String() {
case "code":
buffer.WriteString(text.CyanCode)
case "/code":
buffer.WriteString(text.ResetCode)
case "/p":
buffer.WriteRune('\n')
}
continue
}
tagBuffer.WriteRune(char)
continue
}
if inEscape {
if char == ';' {
inEscape = false
escapeBuffer.WriteRune(char)
s := html.UnescapeString(escapeBuffer.String())
buffer.WriteString(s)
continue
}
escapeBuffer.WriteRune(char)
continue
}
if char == '<' {
inTag = true
tagBuffer.Reset()
continue
}
if char == '&' {
inEscape = true
escapeBuffer.Reset()
escapeBuffer.WriteRune(char)
continue
}
buffer.WriteRune(char)
}
buffer.WriteString(text.ResetCode)
return buffer.String()
}

44
pkg/query/filter.go Normal file
View file

@ -0,0 +1,44 @@
package query
import "github.com/Jguer/go-alpm"
// FilterPackages filters packages based on source and type from local repository.
func FilterPackages(alpmHandle *alpm.Handle) (
local, remote []alpm.Package,
localNames, remoteNames []string,
err error) {
localDB, err := alpmHandle.LocalDB()
if err != nil {
return
}
dbList, err := alpmHandle.SyncDBs()
if err != nil {
return
}
f := func(k alpm.Package) error {
found := false
// For each DB search for our secret package.
_ = dbList.ForEach(func(d alpm.DB) error {
if found {
return nil
}
if d.Pkg(k.Name()) != nil {
found = true
local = append(local, k)
localNames = append(localNames, k.Name())
}
return nil
})
if !found {
remote = append(remote, k)
remoteNames = append(remoteNames, k.Name())
}
return nil
}
err = localDB.PkgCache().ForEach(f)
return local, remote, localNames, remoteNames, err
}

116
pkg/settings/config.go Normal file
View file

@ -0,0 +1,116 @@
package settings
import (
"bytes"
"encoding/json"
"fmt"
"os"
)
const (
// Describes Sorting method for numberdisplay
BottomUp = iota
TopDown
)
// Configuration stores yay's config.
type Configuration struct {
AURURL string `json:"aururl"`
BuildDir string `json:"buildDir"`
ABSDir string `json:"absdir"`
Editor string `json:"editor"`
EditorFlags string `json:"editorflags"`
MakepkgBin string `json:"makepkgbin"`
MakepkgConf string `json:"makepkgconf"`
PacmanBin string `json:"pacmanbin"`
PacmanConf string `json:"pacmanconf"`
ReDownload string `json:"redownload"`
ReBuild string `json:"rebuild"`
AnswerClean string `json:"answerclean"`
AnswerDiff string `json:"answerdiff"`
AnswerEdit string `json:"answeredit"`
AnswerUpgrade string `json:"answerupgrade"`
GitBin string `json:"gitbin"`
GpgBin string `json:"gpgbin"`
GpgFlags string `json:"gpgflags"`
MFlags string `json:"mflags"`
SortBy string `json:"sortby"`
SearchBy string `json:"searchby"`
GitFlags string `json:"gitflags"`
RemoveMake string `json:"removemake"`
SudoBin string `json:"sudobin"`
SudoFlags string `json:"sudoflags"`
RequestSplitN int `json:"requestsplitn"`
SearchMode int `json:"-"`
SortMode int `json:"sortmode"`
CompletionInterval int `json:"completionrefreshtime"`
SudoLoop bool `json:"sudoloop"`
TimeUpdate bool `json:"timeupdate"`
NoConfirm bool `json:"-"`
Devel bool `json:"devel"`
CleanAfter bool `json:"cleanAfter"`
Provides bool `json:"provides"`
PGPFetch bool `json:"pgpfetch"`
UpgradeMenu bool `json:"upgrademenu"`
CleanMenu bool `json:"cleanmenu"`
DiffMenu bool `json:"diffmenu"`
EditMenu bool `json:"editmenu"`
CombinedUpgrade bool `json:"combinedupgrade"`
UseAsk bool `json:"useask"`
BatchInstall bool `json:"batchinstall"`
}
// SaveConfig writes yay config to file.
func (config *Configuration) SaveConfig(configPath string) error {
marshalledinfo, err := json.MarshalIndent(config, "", "\t")
if err != nil {
return err
}
in, err := os.OpenFile(configPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
return err
}
defer in.Close()
if _, err = in.Write(marshalledinfo); err != nil {
return err
}
return in.Sync()
}
func (config *Configuration) ExpandEnv() {
config.AURURL = os.ExpandEnv(config.AURURL)
config.ABSDir = os.ExpandEnv(config.ABSDir)
config.BuildDir = os.ExpandEnv(config.BuildDir)
config.Editor = os.ExpandEnv(config.Editor)
config.EditorFlags = os.ExpandEnv(config.EditorFlags)
config.MakepkgBin = os.ExpandEnv(config.MakepkgBin)
config.MakepkgConf = os.ExpandEnv(config.MakepkgConf)
config.PacmanBin = os.ExpandEnv(config.PacmanBin)
config.PacmanConf = os.ExpandEnv(config.PacmanConf)
config.GpgFlags = os.ExpandEnv(config.GpgFlags)
config.MFlags = os.ExpandEnv(config.MFlags)
config.GitFlags = os.ExpandEnv(config.GitFlags)
config.SortBy = os.ExpandEnv(config.SortBy)
config.SearchBy = os.ExpandEnv(config.SearchBy)
config.GitBin = os.ExpandEnv(config.GitBin)
config.GpgBin = os.ExpandEnv(config.GpgBin)
config.SudoBin = os.ExpandEnv(config.SudoBin)
config.SudoFlags = os.ExpandEnv(config.SudoFlags)
config.ReDownload = os.ExpandEnv(config.ReDownload)
config.ReBuild = os.ExpandEnv(config.ReBuild)
config.AnswerClean = os.ExpandEnv(config.AnswerClean)
config.AnswerDiff = os.ExpandEnv(config.AnswerDiff)
config.AnswerEdit = os.ExpandEnv(config.AnswerEdit)
config.AnswerUpgrade = os.ExpandEnv(config.AnswerUpgrade)
config.RemoveMake = os.ExpandEnv(config.RemoveMake)
}
func (config *Configuration) String() string {
var buf bytes.Buffer
enc := json.NewEncoder(&buf)
enc.SetIndent("", "\t")
if err := enc.Encode(config); err != nil {
fmt.Fprintln(os.Stderr, err)
}
return buf.String()
}

View file

@ -3,13 +3,14 @@ package text
import "fmt"
const (
redCode = "\x1b[31m"
greenCode = "\x1b[32m"
yellowCode = "\x1b[33m"
cyanCode = "\x1b[36m"
boldCode = "\x1b[1m"
redCode = "\x1b[31m"
greenCode = "\x1b[32m"
yellowCode = "\x1b[33m"
magentaCode = "\x1b[35m"
CyanCode = "\x1b[36m"
boldCode = "\x1b[1m"
resetCode = "\x1b[0m"
ResetCode = "\x1b[0m"
)
// UseColor determines if package will emit colors
@ -17,7 +18,7 @@ var UseColor = true
func stylize(startCode, in string) string {
if UseColor {
return startCode + in + resetCode
return startCode + in + ResetCode
}
return in
@ -36,10 +37,14 @@ func yellow(in string) string {
}
func cyan(in string) string {
return stylize(cyanCode, in)
return stylize(CyanCode, in)
}
func bold(in string) string {
func Magenta(in string) string {
return stylize(magentaCode, in)
}
func Bold(in string) string {
return stylize(boldCode, in)
}

View file

@ -9,40 +9,40 @@ import (
const arrow = "==>"
const smallArrow = " ->"
const opSymbol = ":: "
const opSymbol = "::"
func OperationInfoln(a ...interface{}) {
fmt.Fprint(os.Stdout, append([]interface{}{boldCode, cyan(opSymbol), boldCode}, a...)...)
fmt.Fprintln(os.Stdout, resetCode)
fmt.Fprint(os.Stdout, append([]interface{}{Bold(cyan(opSymbol + " ")), boldCode}, a...)...)
fmt.Fprintln(os.Stdout, ResetCode)
}
func OperationInfo(a ...interface{}) {
fmt.Fprint(os.Stdout, append([]interface{}{boldCode, cyan(opSymbol), boldCode}, a...)...)
fmt.Fprint(os.Stdout, resetCode+" ")
fmt.Fprint(os.Stdout, append([]interface{}{Bold(cyan(opSymbol + " ")), boldCode}, a...)...)
fmt.Fprint(os.Stdout, ResetCode+" ")
}
func Info(a ...interface{}) {
fmt.Fprint(os.Stdout, append([]interface{}{bold(green(arrow + " "))}, a...)...)
fmt.Fprint(os.Stdout, append([]interface{}{Bold(green(arrow + " "))}, a...)...)
}
func Infoln(a ...interface{}) {
fmt.Fprintln(os.Stdout, append([]interface{}{bold(green(arrow))}, a...)...)
fmt.Fprintln(os.Stdout, append([]interface{}{Bold(green(arrow))}, a...)...)
}
func Warn(a ...interface{}) {
fmt.Fprint(os.Stdout, append([]interface{}{bold(yellow(smallArrow + " "))}, a...)...)
fmt.Fprint(os.Stdout, append([]interface{}{Bold(yellow(smallArrow + " "))}, a...)...)
}
func Warnln(a ...interface{}) {
fmt.Fprintln(os.Stdout, append([]interface{}{bold(yellow(smallArrow))}, a...)...)
fmt.Fprintln(os.Stdout, append([]interface{}{Bold(yellow(smallArrow))}, a...)...)
}
func Error(a ...interface{}) {
fmt.Fprint(os.Stderr, append([]interface{}{bold(red(smallArrow + " "))}, a...)...)
fmt.Fprint(os.Stderr, append([]interface{}{Bold(red(smallArrow + " "))}, a...)...)
}
func Errorln(a ...interface{}) {
fmt.Fprintln(os.Stderr, append([]interface{}{bold(red(smallArrow))}, a...)...)
fmt.Fprintln(os.Stderr, append([]interface{}{Bold(red(smallArrow))}, a...)...)
}
func PrintInfoValue(str, value string) {
@ -50,5 +50,5 @@ func PrintInfoValue(str, value string) {
value = gotext.Get("None")
}
fmt.Fprintf(os.Stdout, bold("%-16s%s")+" %s\n", str, ":", value)
fmt.Fprintf(os.Stdout, Bold("%-16s%s")+" %s\n", str, ":", value)
}

101
print.go
View file

@ -2,20 +2,17 @@ package main
import (
"bufio"
"bytes"
"encoding/xml"
"fmt"
"io/ioutil"
"net/http"
"os"
"strconv"
"strings"
"time"
"github.com/leonelquinteros/gotext"
rpc "github.com/mikkeloscar/aur"
"github.com/Jguer/yay/v10/pkg/intrange"
"github.com/Jguer/yay/v10/pkg/query"
"github.com/Jguer/yay/v10/pkg/settings"
"github.com/Jguer/yay/v10/pkg/stringset"
"github.com/Jguer/yay/v10/pkg/text"
)
@ -57,9 +54,9 @@ func (q aurQuery) printSearch(start int) {
var toprint string
if config.SearchMode == numberMenu {
switch config.SortMode {
case topDown:
case settings.TopDown:
toprint += magenta(strconv.Itoa(start+i) + " ")
case bottomUp:
case settings.BottomUp:
toprint += magenta(strconv.Itoa(len(q)+start-i-1) + " ")
default:
text.Warnln(gotext.Get("invalid sort mode. Fix with yay -Y --bottomup --save"))
@ -100,9 +97,9 @@ func (s repoQuery) printSearch() {
var toprint string
if config.SearchMode == numberMenu {
switch config.SortMode {
case topDown:
case settings.TopDown:
toprint += magenta(strconv.Itoa(i+1) + " ")
case bottomUp:
case settings.BottomUp:
toprint += magenta(strconv.Itoa(len(s)-i) + " ")
default:
text.Warnln(gotext.Get("invalid sort mode. Fix with yay -Y --bottomup --save"))
@ -333,7 +330,7 @@ func localStatistics() error {
return err
}
_, _, _, remoteNames, err := filterPackages()
_, _, _, remoteNames, err := query.FilterPackages(alpmHandle)
if err != nil {
return err
}
@ -375,7 +372,7 @@ func printUpdateList(parser *arguments) error {
warnings := makeWarnings()
old := os.Stdout // keep backup of the real stdout
os.Stdout = nil
_, _, localNames, remoteNames, err := filterPackages()
_, _, localNames, remoteNames, err := query.FilterPackages(alpmHandle)
if err != nil {
return err
}
@ -441,88 +438,6 @@ outer:
return nil
}
type item struct {
Title string `xml:"title"`
Link string `xml:"link"`
Description string `xml:"description"`
PubDate string `xml:"pubDate"`
Creator string `xml:"dc:creator"`
}
func (item *item) print(buildTime time.Time) {
var fd string
date, err := time.Parse(time.RFC1123Z, item.PubDate)
if err != nil {
fmt.Fprintln(os.Stderr, err)
} else {
fd = text.FormatTime(int(date.Unix()))
if _, double, _ := cmdArgs.getArg("news", "w"); !double && !buildTime.IsZero() {
if buildTime.After(date) {
return
}
}
}
fmt.Println(bold(magenta(fd)), bold(strings.TrimSpace(item.Title)))
if !cmdArgs.existsArg("q", "quiet") {
desc := strings.TrimSpace(parseNews(item.Description))
fmt.Println(desc)
}
}
type channel struct {
Title string `xml:"title"`
Link string `xml:"link"`
Description string `xml:"description"`
Language string `xml:"language"`
Lastbuilddate string `xml:"lastbuilddate"`
Items []item `xml:"item"`
}
type rss struct {
Channel channel `xml:"channel"`
}
func printNewsFeed() error {
resp, err := http.Get("https://archlinux.org/feeds/news")
if err != nil {
return err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
rssGot := rss{}
d := xml.NewDecoder(bytes.NewReader(body))
err = d.Decode(&rssGot)
if err != nil {
return err
}
buildTime, err := lastBuildTime()
if err != nil {
return err
}
if config.SortMode == bottomUp {
for i := len(rssGot.Channel.Items) - 1; i >= 0; i-- {
rssGot.Channel.Items[i].print(buildTime)
}
} else {
for i := 0; i < len(rssGot.Channel.Items); i++ {
rssGot.Channel.Items[i].print(buildTime)
}
}
return nil
}
const (
redCode = "\x1b[31m"
greenCode = "\x1b[32m"

View file

@ -7,7 +7,6 @@ import (
"sort"
"strings"
"sync"
"time"
alpm "github.com/Jguer/go-alpm"
"github.com/leonelquinteros/gotext"
@ -15,6 +14,7 @@ import (
"github.com/Jguer/yay/v10/pkg/intrange"
"github.com/Jguer/yay/v10/pkg/multierror"
"github.com/Jguer/yay/v10/pkg/settings"
"github.com/Jguer/yay/v10/pkg/stringset"
"github.com/Jguer/yay/v10/pkg/text"
)
@ -62,7 +62,7 @@ func (q aurQuery) Less(i, j int) bool {
result = q[i].PackageBaseID < q[j].PackageBaseID
}
if config.SortMode == bottomUp {
if config.SortMode == settings.BottomUp {
return !result
}
@ -73,47 +73,6 @@ func (q aurQuery) Swap(i, j int) {
q[i], q[j] = q[j], q[i]
}
// FilterPackages filters packages based on source and type from local repository.
func filterPackages() (
local, remote []alpm.Package,
localNames, remoteNames []string,
err error) {
localDB, err := alpmHandle.LocalDB()
if err != nil {
return
}
dbList, err := alpmHandle.SyncDBs()
if err != nil {
return
}
f := func(k alpm.Package) error {
found := false
// For each DB search for our secret package.
_ = dbList.ForEach(func(d alpm.DB) error {
if found {
return nil
}
if d.Pkg(k.Name()) != nil {
found = true
local = append(local, k)
localNames = append(localNames, k.Name())
}
return nil
})
if !found {
remote = append(remote, k)
remoteNames = append(remoteNames, k.Name())
}
return nil
}
err = localDB.PkgCache().ForEach(f)
return local, remote, localNames, remoteNames, err
}
func getSearchBy(value string) rpc.By {
switch value {
case "name":
@ -212,14 +171,14 @@ func syncSearch(pkgS []string) (err error) {
}
switch config.SortMode {
case topDown:
case settings.TopDown:
if mode == modeRepo || mode == modeAny {
pq.printSearch()
}
if mode == modeAUR || mode == modeAny {
aq.printSearch(1)
}
case bottomUp:
case settings.BottomUp:
if mode == modeAUR || mode == modeAny {
aq.printSearch(1)
}
@ -310,7 +269,7 @@ func queryRepo(pkgInputN []string) (s repoQuery, err error) {
return nil
})
if config.SortMode == bottomUp {
if config.SortMode == settings.BottomUp {
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
@ -450,24 +409,6 @@ func hangingPackages(removeOptional bool) (hanging []string, err error) {
return hanging, err
}
func lastBuildTime() (time.Time, error) {
var lastTime time.Time
pkgs, _, _, _, err := filterPackages()
if err != nil {
return lastTime, err
}
for _, pkg := range pkgs {
thisTime := pkg.BuildDate()
if thisTime.After(lastTime) {
lastTime = thisTime
}
}
return lastTime, nil
}
// Statistics returns statistics about packages installed in system
func statistics() (*struct {
Totaln int

View file

@ -10,6 +10,7 @@ import (
"github.com/leonelquinteros/gotext"
"github.com/Jguer/yay/v10/pkg/intrange"
"github.com/Jguer/yay/v10/pkg/query"
"github.com/Jguer/yay/v10/pkg/text"
rpc "github.com/mikkeloscar/aur"
@ -117,7 +118,7 @@ func getVersionDiff(oldVersion, newVersion string) (left, right string) {
// upList returns lists of packages to upgrade from each source.
func upList(warnings *aurWarnings) (aurUp, repoUp upSlice, err error) {
_, remote, _, remoteNames, err := filterPackages()
_, remote, _, remoteNames, err := query.FilterPackages(alpmHandle)
if err != nil {
return nil, nil, err
}

3
vcs.go
View file

@ -12,6 +12,7 @@ import (
gosrc "github.com/Morganamilo/go-srcinfo"
"github.com/leonelquinteros/gotext"
"github.com/Jguer/yay/v10/pkg/query"
"github.com/Jguer/yay/v10/pkg/stringset"
"github.com/Jguer/yay/v10/pkg/text"
)
@ -30,7 +31,7 @@ func createDevelDB() error {
var mux sync.Mutex
var wg sync.WaitGroup
_, _, _, remoteNames, err := filterPackages()
_, _, _, remoteNames, err := query.FilterPackages(alpmHandle)
if err != nil {
return err
}