main: add cli flag to load specified account(s)

Make it possible to specify which account(s) to load. Preserve listed
order when creating account tabs.

	aerc -a <account-name[,account-name]>

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
This commit is contained in:
Tim Culverhouse 2022-08-22 10:38:24 -05:00 committed by Robin Jarry
parent 5ed849688a
commit 50992cb9e6
3 changed files with 38 additions and 8 deletions

10
aerc.go
View file

@ -105,7 +105,7 @@ func buildInfo() string {
func usage(msg string) { func usage(msg string) {
fmt.Fprintln(os.Stderr, msg) fmt.Fprintln(os.Stderr, msg)
fmt.Fprintln(os.Stderr, "usage: aerc [-v] [mailto:...]") fmt.Fprintln(os.Stderr, "usage: aerc [-v] [-a <account-name>] [mailto:...]")
os.Exit(1) os.Exit(1)
} }
@ -132,17 +132,21 @@ func setWindowTitle() {
func main() { func main() {
defer logging.PanicHandler() defer logging.PanicHandler()
opts, optind, err := getopt.Getopts(os.Args, "v") opts, optind, err := getopt.Getopts(os.Args, "va:")
if err != nil { if err != nil {
usage("error: " + err.Error()) usage("error: " + err.Error())
return return
} }
logging.BuildInfo = buildInfo() logging.BuildInfo = buildInfo()
var accts []string
for _, opt := range opts { for _, opt := range opts {
if opt.Option == 'v' { if opt.Option == 'v' {
fmt.Println("aerc " + logging.BuildInfo) fmt.Println("aerc " + logging.BuildInfo)
return return
} }
if opt.Option == 'a' {
accts = strings.Split(opt.Value, ",")
}
} }
retryExec := false retryExec := false
args := os.Args[optind:] args := os.Args[optind:]
@ -165,7 +169,7 @@ func main() {
} }
logging.Infof("Starting up version %s", logging.BuildInfo) logging.Infof("Starting up version %s", logging.BuildInfo)
conf, err := config.LoadConfigFromFile(nil) conf, err := config.LoadConfigFromFile(nil, accts)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Failed to load config: %v\n", err) fmt.Fprintf(os.Stderr, "Failed to load config: %v\n", err)
os.Exit(1) //nolint:gocritic // PanicHandler does not need to run as it's not a panic os.Exit(1) //nolint:gocritic // PanicHandler does not need to run as it's not a panic

View file

@ -266,7 +266,7 @@ func mapName(raw string) string {
return string(newstr) return string(newstr)
} }
func loadAccountConfig(path string) ([]AccountConfig, error) { func loadAccountConfig(path string, accts []string) ([]AccountConfig, error) {
file, err := ini.Load(path) file, err := ini.Load(path)
if err != nil { if err != nil {
// No config triggers account configuration wizard // No config triggers account configuration wizard
@ -279,6 +279,9 @@ func loadAccountConfig(path string) ([]AccountConfig, error) {
if _sec == "DEFAULT" { if _sec == "DEFAULT" {
continue continue
} }
if len(accts) > 0 && !contains(accts, _sec) {
continue
}
sec := file.Section(_sec) sec := file.Section(_sec)
sourceRemoteConfig := RemoteConfig{} sourceRemoteConfig := RemoteConfig{}
account := AccountConfig{ account := AccountConfig{
@ -355,6 +358,16 @@ func loadAccountConfig(path string) ([]AccountConfig, error) {
accounts = append(accounts, account) accounts = append(accounts, account)
} }
if len(accts) > 0 {
// Sort accounts struct to match the specified order, if we
// have one
if len(accounts) != len(accts) {
return nil, errors.New("account(s) not found")
}
sort.Slice(accounts, func(i, j int) bool {
return accts[i] < accts[j]
})
}
return accounts, nil return accounts, nil
} }
@ -663,7 +676,7 @@ func validatePgpProvider(section *ini.Section) error {
return nil return nil
} }
func LoadConfigFromFile(root *string) (*AercConfig, error) { func LoadConfigFromFile(root *string, accts []string) (*AercConfig, error) {
if root == nil { if root == nil {
_root := path.Join(xdg.ConfigHome(), "aerc") _root := path.Join(xdg.ConfigHome(), "aerc")
root = &_root root = &_root
@ -823,7 +836,7 @@ func LoadConfigFromFile(root *string) (*AercConfig, error) {
accountsPath := path.Join(*root, "accounts.conf") accountsPath := path.Join(*root, "accounts.conf")
logging.Infof("Parsing accounts configuration from %s", accountsPath) logging.Infof("Parsing accounts configuration from %s", accountsPath)
if accounts, err := loadAccountConfig(accountsPath); err != nil { if accounts, err := loadAccountConfig(accountsPath, accts); err != nil {
return nil, err return nil, err
} else { } else {
config.Accounts = accounts config.Accounts = accounts
@ -1089,3 +1102,12 @@ func (uiConfig UIConfig) GetComposedStyle(base StyleObject,
func (uiConfig UIConfig) GetComposedStyleSelected(base StyleObject, styles []StyleObject) tcell.Style { func (uiConfig UIConfig) GetComposedStyleSelected(base StyleObject, styles []StyleObject) tcell.Style {
return uiConfig.style.ComposeSelected(base, styles) return uiConfig.style.ComposeSelected(base, styles)
} }
func contains(list []string, v string) bool {
for _, item := range list {
if item == v {
return true
}
}
return false
}

View file

@ -6,7 +6,7 @@ aerc - the world's best email client
# SYNOPSIS # SYNOPSIS
_aerc_ [-v] [mailto:...] _aerc_ [-v] [-a <account-name[,account-name]>] [mailto:...]
For a guided tutorial, use *:help tutorial* from aerc, or *man aerc-tutorial* For a guided tutorial, use *:help tutorial* from aerc, or *man aerc-tutorial*
from your terminal. from your terminal.
@ -16,6 +16,11 @@ from your terminal.
*-v* *-v*
Prints the installed version of aerc and exits. Prints the installed version of aerc and exits.
*-a <account-name[,account-name]>*
Load only the named accounts, as opposed to all configured accounts.
List must be comma separated, with no spaces. The account order will be
preserved.
*mailto:address[,address][?query[&query]]* *mailto:address[,address][?query[&query]]*
Opens the composer with the address(es) in the "to" field. These Opens the composer with the address(es) in the "to" field. These
addresses must not be percent encoded. addresses must not be percent encoded.
@ -40,7 +45,6 @@ from your terminal.
Note that reserved characters in the queries must be percent encoded. Note that reserved characters in the queries must be percent encoded.
# RUNTIME COMMANDS # RUNTIME COMMANDS
To execute a command, press ':' to bring up the command interface. Commands may To execute a command, press ':' to bring up the command interface. Commands may