diff --git a/.golangci.yaml b/.golangci.yaml index 2934e8a..6006d52 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -31,5 +31,8 @@ linters-settings: linters: enable-all: true disable: - #- json + - exhaustivestruct + - exhaustruct + - gomnd + - tagliatelle fast: false diff --git a/cmd/enbas/main.go b/cmd/enbas/main.go index cd7eb09..c393784 100644 --- a/cmd/enbas/main.go +++ b/cmd/enbas/main.go @@ -16,10 +16,10 @@ import ( ) var ( - binaryVersion string - buildTime string - goVersion string - gitCommit string + binaryVersion string //nolint:gochecknoglobals + buildTime string //nolint:gochecknoglobals + goVersion string //nolint:gochecknoglobals + gitCommit string //nolint:gochecknoglobals ) func main() { @@ -83,98 +83,97 @@ func run() error { executorMap := map[string]executor.Executor{ executor.CommandAccept: executor.NewAcceptOrRejectExecutor( printer, - configDir, + config, executor.CommandAccept, executor.CommandSummaryLookup(executor.CommandAccept), ), executor.CommandAdd: executor.NewAddExecutor( printer, - configDir, + config, executor.CommandAdd, executor.CommandSummaryLookup(executor.CommandAdd), ), executor.CommandBlock: executor.NewBlockOrUnblockExecutor( printer, - configDir, + config, executor.CommandBlock, executor.CommandSummaryLookup(executor.CommandBlock), ), executor.CommandCreate: executor.NewCreateExecutor( printer, - configDir, + config, executor.CommandCreate, executor.CommandSummaryLookup(executor.CommandCreate), ), executor.CommandDelete: executor.NewDeleteExecutor( printer, - configDir, + config, executor.CommandDelete, executor.CommandSummaryLookup(executor.CommandDelete), ), executor.CommandEdit: executor.NewEditExecutor( printer, - configDir, + config, executor.CommandEdit, executor.CommandSummaryLookup(executor.CommandEdit), ), executor.CommandFollow: executor.NewFollowOrUnfollowExecutor( printer, - configDir, + config, executor.CommandFollow, executor.CommandSummaryLookup(executor.CommandFollow), ), executor.CommandLogin: executor.NewLoginExecutor( printer, - configDir, + config, executor.CommandLogin, executor.CommandSummaryLookup(executor.CommandLogin), ), executor.CommandMute: executor.NewMuteOrUnmuteExecutor( printer, - configDir, + config, executor.CommandMute, executor.CommandSummaryLookup(executor.CommandMute), ), executor.CommandReject: executor.NewAcceptOrRejectExecutor( printer, - configDir, + config, executor.CommandReject, executor.CommandSummaryLookup(executor.CommandReject), ), executor.CommandRemove: executor.NewRemoveExecutor( printer, - configDir, + config, executor.CommandRemove, executor.CommandSummaryLookup(executor.CommandRemove), ), executor.CommandSwitch: executor.NewSwitchExecutor( printer, - configDir, + config, executor.CommandSwitch, executor.CommandSummaryLookup(executor.CommandSwitch), ), executor.CommandUnfollow: executor.NewFollowOrUnfollowExecutor( printer, - configDir, + config, executor.CommandUnfollow, executor.CommandSummaryLookup(executor.CommandUnfollow), ), executor.CommandUnmute: executor.NewMuteOrUnmuteExecutor( printer, - configDir, + config, executor.CommandUnmute, executor.CommandSummaryLookup(executor.CommandUnmute), ), executor.CommandUnblock: executor.NewBlockOrUnblockExecutor( printer, - configDir, + config, executor.CommandUnblock, executor.CommandSummaryLookup(executor.CommandUnblock), ), executor.CommandShow: executor.NewShowExecutor( printer, - &config, - configDir, + config, executor.CommandShow, executor.CommandSummaryLookup(executor.CommandShow), ), @@ -189,7 +188,7 @@ func run() error { ), executor.CommandWhoami: executor.NewWhoAmIExecutor( printer, - configDir, + config, executor.CommandWhoami, executor.CommandSummaryLookup(executor.CommandWhoami), ), diff --git a/internal/client/client.go b/internal/client/client.go index 27ece40..620b957 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -25,8 +25,8 @@ type Client struct { Timeout time.Duration } -func NewClientFromConfig(configDir string) (*Client, error) { - config, err := config.NewCredentialsConfigFromFile(configDir) +func NewClientFromFile(path string) (*Client, error) { + config, err := config.NewCredentialsConfigFromFile(path) if err != nil { return nil, fmt.Errorf("unable to get the authentication configuration: %w", err) } @@ -51,7 +51,7 @@ func NewClient(authentication config.Credentials) *Client { func (g *Client) AuthCodeURL() string { format := "%s/oauth/authorize?client_id=%s&redirect_uri=%s&response_type=code" - escapedRedirectURI := url.QueryEscape(internal.RedirectUri) + escapedRedirectURI := url.QueryEscape(internal.RedirectURI) return fmt.Sprintf( format, diff --git a/internal/client/register.go b/internal/client/register.go index 3800b3a..9be1c32 100644 --- a/internal/client/register.go +++ b/internal/client/register.go @@ -24,7 +24,7 @@ type registerRequest struct { func (g *Client) Register() error { params := registerRequest{ ClientName: internal.ApplicationName, - RedirectUris: internal.RedirectUri, + RedirectUris: internal.RedirectURI, Scopes: "read write", Website: internal.ApplicationWebsite, } diff --git a/internal/client/token.go b/internal/client/token.go index ed8190d..4aeff04 100644 --- a/internal/client/token.go +++ b/internal/client/token.go @@ -17,7 +17,7 @@ import ( var errEmptyAccessToken = errors.New("received an empty access token") type tokenRequest struct { - RedirectUri string `json:"redirect_uri"` + RedirectURI string `json:"redirect_uri"` ClientID string `json:"client_id"` ClientSecret string `json:"client_secret"` GrantType string `json:"grant_type"` @@ -33,7 +33,7 @@ type tokenResponse struct { func (g *Client) UpdateToken(code string) error { params := tokenRequest{ - RedirectUri: internal.RedirectUri, + RedirectURI: internal.RedirectURI, ClientID: g.Authentication.ClientID, ClientSecret: g.Authentication.ClientSecret, GrantType: "authorization_code", diff --git a/internal/config/config.go b/internal/config/config.go index 1b40503..17a6925 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -14,6 +14,7 @@ const ( ) type Config struct { + CredentialsFile string `json:"credentialsFile"` CacheDirectory string `json:"cacheDirectory"` LineWrapMaxWidth int `json:"lineWrapMaxWidth"` HTTP HTTPConfig `json:"http"` @@ -33,47 +34,47 @@ type Integrations struct { VideoPlayer string `json:"videoPlayer"` } -func NewConfigFromFile(configDir string) (Config, error) { +func NewConfigFromFile(configDir string) (*Config, error) { path := configFile(configDir) fileExists, err := utilities.FileExists(path) if err != nil { - return Config{}, fmt.Errorf("unable to check if the config file exists: %w", err) + return nil, fmt.Errorf("unable to check if the config file exists: %w", err) } if !fileExists { - if err := saveDefaultConfigToFile(path); err != nil { - return Config{}, fmt.Errorf("unable to save the default config to file: %w", err) + if err := saveDefaultConfigToFile(configDir, path); err != nil { + return nil, fmt.Errorf("unable to save the default config to file: %w", err) } } file, err := os.Open(path) if err != nil { - return Config{}, fmt.Errorf("unable to open %s: %w", path, err) + return nil, fmt.Errorf("unable to open %s: %w", path, err) } defer file.Close() var config Config if err := json.NewDecoder(file).Decode(&config); err != nil { - return Config{}, fmt.Errorf("unable to decode the JSON data: %w", err) + return nil, fmt.Errorf("unable to decode the JSON data: %w", err) } - return config, nil + return &config, nil } func configFile(configDir string) string { return filepath.Join(utilities.CalculateConfigDir(configDir), configFileName) } -func saveDefaultConfigToFile(path string) error { - file, err := os.Create(path) +func saveDefaultConfigToFile(configDir, configPath string) error { + file, err := os.Create(configPath) if err != nil { - return fmt.Errorf("unable to create the file at %s: %w", path, err) + return fmt.Errorf("unable to create the file at %s: %w", configPath, err) } defer file.Close() - config := defaultConfig() + config := defaultConfig(configDir) encoder := json.NewEncoder(file) encoder.SetIndent("", " ") @@ -84,9 +85,12 @@ func saveDefaultConfigToFile(path string) error { return nil } -func defaultConfig() Config { +func defaultConfig(configDir string) Config { + credentialsFilePath := defaultCredentialsConfigFile(configDir) + return Config{ - CacheDirectory: "", + CredentialsFile: credentialsFilePath, + CacheDirectory: "", HTTP: HTTPConfig{ Timeout: 5, MediaTimeout: 30, diff --git a/internal/config/credentials.go b/internal/config/credentials.go index ace8bd7..a2fb554 100644 --- a/internal/config/credentials.go +++ b/internal/config/credentials.go @@ -10,13 +10,12 @@ import ( "fmt" "os" "path/filepath" - "strings" "codeflow.dananglin.me.uk/apollo/enbas/internal/utilities" ) const ( - credentialsFileName = "credentials.json" + defaultCredentialsFileName = "credentials.json" ) type CredentialsConfig struct { @@ -42,35 +41,29 @@ func (e CredentialsNotFoundError) Error() string { // SaveCredentials saves the credentials into the credentials file within the specified configuration // directory. If the directory is not specified then the default directory is used. If the directory // is not present, it will be created. -func SaveCredentials(configDir, username string, credentials Credentials) (string, error) { - if err := utilities.EnsureDirectory(utilities.CalculateConfigDir(configDir)); err != nil { +func SaveCredentials(filePath, username string, credentials Credentials) (string, error) { + directory := filepath.Dir(filePath) + + if err := utilities.EnsureDirectory(utilities.CalculateConfigDir(directory)); err != nil { return "", fmt.Errorf("unable to ensure the configuration directory: %w", err) } var authConfig CredentialsConfig - filepath := credentialsConfigFile(configDir) - - if _, err := os.Stat(filepath); err != nil { + if _, err := os.Stat(filePath); err != nil { if !errors.Is(err, os.ErrNotExist) { - return "", fmt.Errorf("unknown error received when running stat on %s: %w", filepath, err) + return "", fmt.Errorf("unknown error received when running stat on %s: %w", filePath, err) } authConfig.Credentials = make(map[string]Credentials) } else { - authConfig, err = NewCredentialsConfigFromFile(configDir) + authConfig, err = NewCredentialsConfigFromFile(filePath) if err != nil { return "", fmt.Errorf("unable to retrieve the existing authentication configuration: %w", err) } } - instance := "" - - if strings.HasPrefix(credentials.Instance, "https://") { - instance = strings.TrimPrefix(credentials.Instance, "https://") - } else if strings.HasPrefix(credentials.Instance, "http://") { - instance = strings.TrimPrefix(credentials.Instance, "http://") - } + instance := utilities.GetFQDN(credentials.Instance) authenticationName := username + "@" + instance @@ -78,15 +71,15 @@ func SaveCredentials(configDir, username string, credentials Credentials) (strin authConfig.Credentials[authenticationName] = credentials - if err := saveCredentialsConfigFile(authConfig, configDir); err != nil { + if err := saveCredentialsConfigFile(authConfig, filePath); err != nil { return "", fmt.Errorf("unable to save the authentication configuration to file: %w", err) } return authenticationName, nil } -func UpdateCurrentAccount(account string, configDir string) error { - credentialsConfig, err := NewCredentialsConfigFromFile(configDir) +func UpdateCurrentAccount(account string, filePath string) error { + credentialsConfig, err := NewCredentialsConfigFromFile(filePath) if err != nil { return fmt.Errorf("unable to retrieve the existing authentication configuration: %w", err) } @@ -97,19 +90,19 @@ func UpdateCurrentAccount(account string, configDir string) error { credentialsConfig.CurrentAccount = account - if err := saveCredentialsConfigFile(credentialsConfig, configDir); err != nil { + if err := saveCredentialsConfigFile(credentialsConfig, filePath); err != nil { return fmt.Errorf("unable to save the authentication configuration to file: %w", err) } return nil } -func NewCredentialsConfigFromFile(configDir string) (CredentialsConfig, error) { - path := credentialsConfigFile(configDir) - - file, err := os.Open(path) +// NewCredentialsConfigFromFile creates a new CredentialsConfig value from reading +// the credentials file. +func NewCredentialsConfigFromFile(filePath string) (CredentialsConfig, error) { + file, err := os.Open(filePath) if err != nil { - return CredentialsConfig{}, fmt.Errorf("unable to open %s: %w", path, err) + return CredentialsConfig{}, fmt.Errorf("unable to open %s: %w", filePath, err) } defer file.Close() @@ -122,12 +115,10 @@ func NewCredentialsConfigFromFile(configDir string) (CredentialsConfig, error) { return authConfig, nil } -func saveCredentialsConfigFile(authConfig CredentialsConfig, configDir string) error { - path := credentialsConfigFile(configDir) - - file, err := os.Create(path) +func saveCredentialsConfigFile(authConfig CredentialsConfig, filePath string) error { + file, err := os.Create(filePath) if err != nil { - return fmt.Errorf("unable to create the file at %s: %w", path, err) + return fmt.Errorf("unable to create the file at %s: %w", filePath, err) } defer file.Close() @@ -141,6 +132,6 @@ func saveCredentialsConfigFile(authConfig CredentialsConfig, configDir string) e return nil } -func credentialsConfigFile(configDir string) string { - return filepath.Join(utilities.CalculateConfigDir(configDir), credentialsFileName) +func defaultCredentialsConfigFile(configDir string) string { + return filepath.Join(utilities.CalculateConfigDir(configDir), defaultCredentialsFileName) } diff --git a/internal/executor/accept_or_reject.go b/internal/executor/accept_or_reject.go index 7e32c69..767661c 100644 --- a/internal/executor/accept_or_reject.go +++ b/internal/executor/accept_or_reject.go @@ -9,6 +9,7 @@ import ( "fmt" "codeflow.dananglin.me.uk/apollo/enbas/internal/client" + "codeflow.dananglin.me.uk/apollo/enbas/internal/config" "codeflow.dananglin.me.uk/apollo/enbas/internal/printer" ) @@ -16,19 +17,19 @@ type AcceptOrRejectExecutor struct { *flag.FlagSet printer *printer.Printer - configDir string + config *config.Config resourceType string accountName string command string } -func NewAcceptOrRejectExecutor(enbasPrinter *printer.Printer, configDir, name, summary string) *AcceptOrRejectExecutor { +func NewAcceptOrRejectExecutor(enbasPrinter *printer.Printer, config *config.Config, name, summary string) *AcceptOrRejectExecutor { acceptExe := AcceptOrRejectExecutor{ FlagSet: flag.NewFlagSet(name, flag.ExitOnError), - printer: enbasPrinter, - configDir: configDir, - command: name, + printer: enbasPrinter, + config: config, + command: name, } acceptExe.StringVar(&acceptExe.resourceType, flagType, "", "Specify the type of resource to accept or reject") @@ -49,7 +50,7 @@ func (a *AcceptOrRejectExecutor) Execute() error { return UnsupportedTypeError{resourceType: a.resourceType} } - gtsClient, err := client.NewClientFromConfig(a.configDir) + gtsClient, err := client.NewClientFromFile(a.config.CredentialsFile) if err != nil { return fmt.Errorf("unable to create the GoToSocial client: %w", err) } @@ -58,7 +59,7 @@ func (a *AcceptOrRejectExecutor) Execute() error { } func (a *AcceptOrRejectExecutor) acceptOrRejectFollowRequest(gtsClient *client.Client) error { - accountID, err := getAccountID(gtsClient, false, a.accountName, a.configDir) + accountID, err := getAccountID(gtsClient, false, a.accountName, a.config.CredentialsFile) if err != nil { return fmt.Errorf("received an error while getting the account ID: %w", err) } diff --git a/internal/executor/account.go b/internal/executor/account.go index 0d2ec37..b67be29 100644 --- a/internal/executor/account.go +++ b/internal/executor/account.go @@ -12,7 +12,7 @@ import ( "codeflow.dananglin.me.uk/apollo/enbas/internal/model" ) -func getAccountID(gtsClient *client.Client, myAccount bool, accountName, configDir string) (string, error) { +func getAccountID(gtsClient *client.Client, myAccount bool, accountName, path string) (string, error) { var ( accountID string err error @@ -20,7 +20,7 @@ func getAccountID(gtsClient *client.Client, myAccount bool, accountName, configD switch { case myAccount: - accountID, err = getMyAccountID(gtsClient, configDir) + accountID, err = getMyAccountID(gtsClient, path) if err != nil { return "", fmt.Errorf("unable to get your account ID: %w", err) } @@ -45,8 +45,8 @@ func getTheirAccountID(gtsClient *client.Client, accountURI string) (string, err return account.ID, nil } -func getMyAccountID(gtsClient *client.Client, configDir string) (string, error) { - account, err := getMyAccount(gtsClient, configDir) +func getMyAccountID(gtsClient *client.Client, path string) (string, error) { + account, err := getMyAccount(gtsClient, path) if err != nil { return "", fmt.Errorf("received an error while getting your account details: %w", err) } @@ -54,8 +54,8 @@ func getMyAccountID(gtsClient *client.Client, configDir string) (string, error) return account.ID, nil } -func getMyAccount(gtsClient *client.Client, configDir string) (model.Account, error) { - authConfig, err := config.NewCredentialsConfigFromFile(configDir) +func getMyAccount(gtsClient *client.Client, path string) (model.Account, error) { + authConfig, err := config.NewCredentialsConfigFromFile(path) if err != nil { return model.Account{}, fmt.Errorf("unable to retrieve the authentication configuration: %w", err) } diff --git a/internal/executor/add.go b/internal/executor/add.go index dce233e..ab6e7e2 100644 --- a/internal/executor/add.go +++ b/internal/executor/add.go @@ -10,6 +10,7 @@ import ( "fmt" "codeflow.dananglin.me.uk/apollo/enbas/internal/client" + "codeflow.dananglin.me.uk/apollo/enbas/internal/config" "codeflow.dananglin.me.uk/apollo/enbas/internal/printer" ) @@ -17,7 +18,7 @@ type AddExecutor struct { *flag.FlagSet printer *printer.Printer - configDir string + config *config.Config resourceType string toResourceType string listID string @@ -28,14 +29,14 @@ type AddExecutor struct { content string } -func NewAddExecutor(printer *printer.Printer, configDir, name, summary string) *AddExecutor { +func NewAddExecutor(printer *printer.Printer, config *config.Config, name, summary string) *AddExecutor { emptyArr := make([]string, 0, 3) addExe := AddExecutor{ FlagSet: flag.NewFlagSet(name, flag.ExitOnError), printer: printer, - configDir: configDir, + config: config, accountNames: MultiStringFlagValue(emptyArr), } @@ -71,7 +72,7 @@ func (a *AddExecutor) Execute() error { return UnsupportedTypeError{resourceType: a.toResourceType} } - gtsClient, err := client.NewClientFromConfig(a.configDir) + gtsClient, err := client.NewClientFromFile(a.config.CredentialsFile) if err != nil { return fmt.Errorf("unable to create the GoToSocial client: %w", err) } @@ -154,7 +155,7 @@ func (a *AddExecutor) addNoteToAccount(gtsClient *client.Client) error { return fmt.Errorf("unexpected number of accounts specified: want 1, got %d", len(a.accountNames)) } - accountID, err := getAccountID(gtsClient, false, a.accountNames[0], a.configDir) + accountID, err := getAccountID(gtsClient, false, a.accountNames[0], a.config.CredentialsFile) if err != nil { return fmt.Errorf("received an error while getting the account ID: %w", err) } diff --git a/internal/executor/block_or_unblock.go b/internal/executor/block_or_unblock.go index d8b4e0c..c383e99 100644 --- a/internal/executor/block_or_unblock.go +++ b/internal/executor/block_or_unblock.go @@ -9,6 +9,7 @@ import ( "fmt" "codeflow.dananglin.me.uk/apollo/enbas/internal/client" + "codeflow.dananglin.me.uk/apollo/enbas/internal/config" "codeflow.dananglin.me.uk/apollo/enbas/internal/printer" ) @@ -16,19 +17,19 @@ type BlockOrUnblockExecutor struct { *flag.FlagSet printer *printer.Printer - configDir string + config *config.Config resourceType string accountName string command string } -func NewBlockOrUnblockExecutor(printer *printer.Printer, configDir, name, summary string) *BlockOrUnblockExecutor { +func NewBlockOrUnblockExecutor(printer *printer.Printer, config *config.Config, name, summary string) *BlockOrUnblockExecutor { blockExe := BlockOrUnblockExecutor{ FlagSet: flag.NewFlagSet(name, flag.ExitOnError), - printer: printer, - configDir: configDir, - command: name, + printer: printer, + config: config, + command: name, } blockExe.StringVar(&blockExe.resourceType, flagType, "", "Specify the type of resource to block or unblock") @@ -49,7 +50,7 @@ func (b *BlockOrUnblockExecutor) Execute() error { return UnsupportedTypeError{resourceType: b.resourceType} } - gtsClient, err := client.NewClientFromConfig(b.configDir) + gtsClient, err := client.NewClientFromFile(b.config.CredentialsFile) if err != nil { return fmt.Errorf("unable to create the GoToSocial client: %w", err) } @@ -62,7 +63,7 @@ func (b *BlockOrUnblockExecutor) blockOrUnblockAccount(gtsClient *client.Client) return FlagNotSetError{flagText: flagAccountName} } - accountID, err := getAccountID(gtsClient, false, b.accountName, b.configDir) + accountID, err := getAccountID(gtsClient, false, b.accountName, b.config.CredentialsFile) if err != nil { return fmt.Errorf("received an error while getting the account ID: %w", err) } diff --git a/internal/executor/create.go b/internal/executor/create.go index 9aee759..856b261 100644 --- a/internal/executor/create.go +++ b/internal/executor/create.go @@ -10,6 +10,7 @@ import ( "strconv" "codeflow.dananglin.me.uk/apollo/enbas/internal/client" + "codeflow.dananglin.me.uk/apollo/enbas/internal/config" "codeflow.dananglin.me.uk/apollo/enbas/internal/model" "codeflow.dananglin.me.uk/apollo/enbas/internal/printer" "codeflow.dananglin.me.uk/apollo/enbas/internal/utilities" @@ -19,6 +20,7 @@ type CreateExecutor struct { *flag.FlagSet printer *printer.Printer + config *config.Config addPoll bool boostable bool federated bool @@ -27,7 +29,6 @@ type CreateExecutor struct { pollHidesVoteCounts bool replyable bool sensitive *bool - configDir string content string contentType string fromFile string @@ -41,12 +42,12 @@ type CreateExecutor struct { pollOptions MultiStringFlagValue } -func NewCreateExecutor(printer *printer.Printer, configDir, name, summary string) *CreateExecutor { +func NewCreateExecutor(printer *printer.Printer, config *config.Config, name, summary string) *CreateExecutor { createExe := CreateExecutor{ FlagSet: flag.NewFlagSet(name, flag.ExitOnError), - printer: printer, - configDir: configDir, + printer: printer, + config: config, } createExe.BoolVar(&createExe.boostable, flagEnableReposts, true, "Specify if the status can be reposted/boosted by others") @@ -90,7 +91,7 @@ func (c *CreateExecutor) Execute() error { return FlagNotSetError{flagText: flagType} } - gtsClient, err := client.NewClientFromConfig(c.configDir) + gtsClient, err := client.NewClientFromFile(c.config.CredentialsFile) if err != nil { return fmt.Errorf("unable to create the GoToSocial client: %w", err) } diff --git a/internal/executor/delete.go b/internal/executor/delete.go index 7d173c6..819204f 100644 --- a/internal/executor/delete.go +++ b/internal/executor/delete.go @@ -9,6 +9,7 @@ import ( "fmt" "codeflow.dananglin.me.uk/apollo/enbas/internal/client" + "codeflow.dananglin.me.uk/apollo/enbas/internal/config" "codeflow.dananglin.me.uk/apollo/enbas/internal/printer" ) @@ -16,17 +17,17 @@ type DeleteExecutor struct { *flag.FlagSet printer *printer.Printer - configDir string + config *config.Config resourceType string listID string } -func NewDeleteExecutor(printer *printer.Printer, configDir, name, summary string) *DeleteExecutor { +func NewDeleteExecutor(printer *printer.Printer, config *config.Config, name, summary string) *DeleteExecutor { deleteExe := DeleteExecutor{ FlagSet: flag.NewFlagSet(name, flag.ExitOnError), - printer: printer, - configDir: configDir, + printer: printer, + config: config, } deleteExe.StringVar(&deleteExe.resourceType, flagType, "", "Specify the type of resource to delete") @@ -51,7 +52,7 @@ func (d *DeleteExecutor) Execute() error { return UnsupportedTypeError{resourceType: d.resourceType} } - gtsClient, err := client.NewClientFromConfig(d.configDir) + gtsClient, err := client.NewClientFromFile(d.config.CredentialsFile) if err != nil { return fmt.Errorf("unable to create the GoToSocial client: %w", err) } diff --git a/internal/executor/edit.go b/internal/executor/edit.go index e18e2e8..ee92375 100644 --- a/internal/executor/edit.go +++ b/internal/executor/edit.go @@ -9,6 +9,7 @@ import ( "fmt" "codeflow.dananglin.me.uk/apollo/enbas/internal/client" + "codeflow.dananglin.me.uk/apollo/enbas/internal/config" "codeflow.dananglin.me.uk/apollo/enbas/internal/model" "codeflow.dananglin.me.uk/apollo/enbas/internal/printer" ) @@ -17,19 +18,19 @@ type EditExecutor struct { *flag.FlagSet printer *printer.Printer - configDir string + config *config.Config resourceType string listID string listTitle string listRepliesPolicy string } -func NewEditExecutor(printer *printer.Printer, configDir, name, summary string) *EditExecutor { +func NewEditExecutor(printer *printer.Printer, config *config.Config, name, summary string) *EditExecutor { editExe := EditExecutor{ FlagSet: flag.NewFlagSet(name, flag.ExitOnError), - printer: printer, - configDir: configDir, + printer: printer, + config: config, } editExe.StringVar(&editExe.resourceType, flagType, "", "Specify the type of resource to update") @@ -56,7 +57,7 @@ func (e *EditExecutor) Execute() error { return UnsupportedTypeError{resourceType: e.resourceType} } - gtsClient, err := client.NewClientFromConfig(e.configDir) + gtsClient, err := client.NewClientFromFile(e.config.CredentialsFile) if err != nil { return fmt.Errorf("unable to create the GoToSocial client: %w", err) } diff --git a/internal/executor/follow_or_unfollow.go b/internal/executor/follow_or_unfollow.go index 535df04..697c8a3 100644 --- a/internal/executor/follow_or_unfollow.go +++ b/internal/executor/follow_or_unfollow.go @@ -9,6 +9,7 @@ import ( "fmt" "codeflow.dananglin.me.uk/apollo/enbas/internal/client" + "codeflow.dananglin.me.uk/apollo/enbas/internal/config" "codeflow.dananglin.me.uk/apollo/enbas/internal/printer" ) @@ -16,7 +17,7 @@ type FollowOrUnfollowExecutor struct { *flag.FlagSet printer *printer.Printer - configDir string + config *config.Config resourceType string accountName string showReposts bool @@ -24,13 +25,13 @@ type FollowOrUnfollowExecutor struct { action string } -func NewFollowOrUnfollowExecutor(printer *printer.Printer, configDir, name, summary string) *FollowOrUnfollowExecutor { +func NewFollowOrUnfollowExecutor(printer *printer.Printer, config *config.Config, name, summary string) *FollowOrUnfollowExecutor { command := FollowOrUnfollowExecutor{ FlagSet: flag.NewFlagSet(name, flag.ExitOnError), - printer: printer, - configDir: configDir, - action: name, + printer: printer, + config: config, + action: name, } command.StringVar(&command.resourceType, flagType, "", "Specify the type of resource to follow") @@ -53,7 +54,7 @@ func (f *FollowOrUnfollowExecutor) Execute() error { return UnsupportedTypeError{resourceType: f.resourceType} } - gtsClient, err := client.NewClientFromConfig(f.configDir) + gtsClient, err := client.NewClientFromFile(f.config.CredentialsFile) if err != nil { return fmt.Errorf("unable to create the GoToSocial client: %w", err) } @@ -62,7 +63,7 @@ func (f *FollowOrUnfollowExecutor) Execute() error { } func (f *FollowOrUnfollowExecutor) followOrUnfollowAccount(gtsClient *client.Client) error { - accountID, err := getAccountID(gtsClient, false, f.accountName, f.configDir) + accountID, err := getAccountID(gtsClient, false, f.accountName, f.config.CredentialsFile) if err != nil { return fmt.Errorf("received an error while getting the account ID: %w", err) } diff --git a/internal/executor/login.go b/internal/executor/login.go index 37d4115..975ed22 100644 --- a/internal/executor/login.go +++ b/internal/executor/login.go @@ -18,18 +18,18 @@ import ( type LoginExecutor struct { *flag.FlagSet - printer *printer.Printer - configDir string - instance string + printer *printer.Printer + config *config.Config + instance string } -func NewLoginExecutor(printer *printer.Printer, configDir, name, summary string) *LoginExecutor { +func NewLoginExecutor(printer *printer.Printer, config *config.Config, name, summary string) *LoginExecutor { command := LoginExecutor{ FlagSet: flag.NewFlagSet(name, flag.ExitOnError), - printer: printer, - configDir: configDir, - instance: "", + printer: printer, + config: config, + instance: "", } command.StringVar(&command.instance, flagInstance, "", "Specify the instance that you want to login to.") @@ -95,7 +95,7 @@ func (c *LoginExecutor) Execute() error { return fmt.Errorf("unable to verify the credentials: %w", err) } - loginName, err := config.SaveCredentials(c.configDir, account.Username, gtsClient.Authentication) + loginName, err := config.SaveCredentials(c.config.CredentialsFile, account.Username, gtsClient.Authentication) if err != nil { return fmt.Errorf("unable to save the authentication details: %w", err) } diff --git a/internal/executor/mute_or_unmute.go b/internal/executor/mute_or_unmute.go index ff49f5e..b04dd19 100644 --- a/internal/executor/mute_or_unmute.go +++ b/internal/executor/mute_or_unmute.go @@ -9,6 +9,7 @@ import ( "fmt" "codeflow.dananglin.me.uk/apollo/enbas/internal/client" + "codeflow.dananglin.me.uk/apollo/enbas/internal/config" "codeflow.dananglin.me.uk/apollo/enbas/internal/printer" ) @@ -16,21 +17,21 @@ type MuteOrUnmuteExecutor struct { *flag.FlagSet printer *printer.Printer + config *config.Config accountName string - configDir string command string resourceType string muteDuration TimeDurationFlagValue muteNotifications bool } -func NewMuteOrUnmuteExecutor(printer *printer.Printer, configDir, name, summary string) *MuteOrUnmuteExecutor { +func NewMuteOrUnmuteExecutor(printer *printer.Printer, config *config.Config, name, summary string) *MuteOrUnmuteExecutor { exe := MuteOrUnmuteExecutor{ FlagSet: flag.NewFlagSet(name, flag.ExitOnError), - printer: printer, - configDir: configDir, - command: name, + printer: printer, + config: config, + command: name, } exe.StringVar(&exe.accountName, flagAccountName, "", "Specify the account name in full (username@domain)") @@ -53,7 +54,7 @@ func (m *MuteOrUnmuteExecutor) Execute() error { return UnsupportedTypeError{resourceType: m.resourceType} } - gtsClient, err := client.NewClientFromConfig(m.configDir) + gtsClient, err := client.NewClientFromFile(m.config.CredentialsFile) if err != nil { return fmt.Errorf("unable to create the GoToSocial client: %w", err) } @@ -66,7 +67,7 @@ func (m *MuteOrUnmuteExecutor) muteOrUnmuteAccount(gtsClient *client.Client) err return FlagNotSetError{flagText: flagAccountName} } - accountID, err := getAccountID(gtsClient, false, m.accountName, m.configDir) + accountID, err := getAccountID(gtsClient, false, m.accountName, m.config.CredentialsFile) if err != nil { return fmt.Errorf("received an error while getting the account ID: %w", err) } diff --git a/internal/executor/remove.go b/internal/executor/remove.go index 3814872..eeff8b0 100644 --- a/internal/executor/remove.go +++ b/internal/executor/remove.go @@ -9,6 +9,7 @@ import ( "fmt" "codeflow.dananglin.me.uk/apollo/enbas/internal/client" + "codeflow.dananglin.me.uk/apollo/enbas/internal/config" "codeflow.dananglin.me.uk/apollo/enbas/internal/printer" ) @@ -16,7 +17,7 @@ type RemoveExecutor struct { *flag.FlagSet printer *printer.Printer - configDir string + config *config.Config resourceType string fromResourceType string listID string @@ -24,14 +25,14 @@ type RemoveExecutor struct { accountNames MultiStringFlagValue } -func NewRemoveExecutor(printer *printer.Printer, configDir, name, summary string) *RemoveExecutor { +func NewRemoveExecutor(printer *printer.Printer, config *config.Config, name, summary string) *RemoveExecutor { emptyArr := make([]string, 0, 3) removeExe := RemoveExecutor{ FlagSet: flag.NewFlagSet(name, flag.ExitOnError), printer: printer, - configDir: configDir, + config: config, accountNames: MultiStringFlagValue(emptyArr), } @@ -63,7 +64,7 @@ func (r *RemoveExecutor) Execute() error { return UnsupportedTypeError{resourceType: r.fromResourceType} } - gtsClient, err := client.NewClientFromConfig(r.configDir) + gtsClient, err := client.NewClientFromFile(r.config.CredentialsFile) if err != nil { return fmt.Errorf("unable to create the GoToSocial client: %w", err) } @@ -137,7 +138,7 @@ func (r *RemoveExecutor) removeNoteFromAccount(gtsClient *client.Client) error { return fmt.Errorf("unexpected number of accounts specified: want 1, got %d", len(r.accountNames)) } - accountID, err := getAccountID(gtsClient, false, r.accountNames[0], r.configDir) + accountID, err := getAccountID(gtsClient, false, r.accountNames[0], r.config.CredentialsFile) if err != nil { return fmt.Errorf("received an error while getting the account ID: %w", err) } diff --git a/internal/executor/show.go b/internal/executor/show.go index dbb2604..f8b47a1 100644 --- a/internal/executor/show.go +++ b/internal/executor/show.go @@ -26,7 +26,6 @@ type ShowExecutor struct { skipAccountRelationship bool showUserPreferences bool showInBrowser bool - configDir string resourceType string accountName string statusID string @@ -39,13 +38,12 @@ type ShowExecutor struct { attachmentIDs MultiStringFlagValue } -func NewShowExecutor(printer *printer.Printer, config *config.Config, configDir, name, summary string) *ShowExecutor { +func NewShowExecutor(printer *printer.Printer, config *config.Config, name, summary string) *ShowExecutor { showExe := ShowExecutor{ FlagSet: flag.NewFlagSet(name, flag.ExitOnError), - printer: printer, - config: config, - configDir: configDir, + printer: printer, + config: config, } showExe.BoolVar(&showExe.myAccount, flagMyAccount, false, "Set to true to lookup your account") @@ -97,7 +95,7 @@ func (s *ShowExecutor) Execute() error { return UnsupportedTypeError{resourceType: s.resourceType} } - gtsClient, err := client.NewClientFromConfig(s.configDir) + gtsClient, err := client.NewClientFromFile(s.config.CredentialsFile) if err != nil { return fmt.Errorf("unable to create the GoToSocial client: %w", err) } @@ -123,7 +121,7 @@ func (s *ShowExecutor) showAccount(gtsClient *client.Client) error { ) if s.myAccount { - account, err = getMyAccount(gtsClient, s.configDir) + account, err = getMyAccount(gtsClient, s.config.CredentialsFile) if err != nil { return fmt.Errorf("received an error while getting the account details: %w", err) } @@ -285,7 +283,7 @@ func (s *ShowExecutor) showLists(gtsClient *client.Client) error { } func (s *ShowExecutor) showFollowers(gtsClient *client.Client) error { - accountID, err := getAccountID(gtsClient, s.myAccount, s.accountName, s.configDir) + accountID, err := getAccountID(gtsClient, s.myAccount, s.accountName, s.config.CredentialsFile) if err != nil { return fmt.Errorf("received an error while getting the account ID: %w", err) } @@ -305,7 +303,7 @@ func (s *ShowExecutor) showFollowers(gtsClient *client.Client) error { } func (s *ShowExecutor) showFollowing(gtsClient *client.Client) error { - accountID, err := getAccountID(gtsClient, s.myAccount, s.accountName, s.configDir) + accountID, err := getAccountID(gtsClient, s.myAccount, s.accountName, s.config.CredentialsFile) if err != nil { return fmt.Errorf("received an error while getting the account ID: %w", err) } diff --git a/internal/executor/switch.go b/internal/executor/switch.go index 988047d..7c8bf53 100644 --- a/internal/executor/switch.go +++ b/internal/executor/switch.go @@ -15,17 +15,17 @@ import ( type SwitchExecutor struct { *flag.FlagSet - configDir string + config *config.Config toResourceType string accountName string printer *printer.Printer } -func NewSwitchExecutor(printer *printer.Printer, configDir, name, summary string) *SwitchExecutor { +func NewSwitchExecutor(printer *printer.Printer, config *config.Config, name, summary string) *SwitchExecutor { switchExe := SwitchExecutor{ - FlagSet: flag.NewFlagSet(name, flag.ExitOnError), - printer: printer, - configDir: configDir, + FlagSet: flag.NewFlagSet(name, flag.ExitOnError), + printer: printer, + config: config, } switchExe.StringVar(&switchExe.toResourceType, flagTo, "", "The account to switch to") @@ -54,7 +54,7 @@ func (s *SwitchExecutor) switchToAccount() error { return NoAccountSpecifiedError{} } - if err := config.UpdateCurrentAccount(s.accountName, s.configDir); err != nil { + if err := config.UpdateCurrentAccount(s.accountName, s.config.CredentialsFile); err != nil { return fmt.Errorf("unable to switch account to the account: %w", err) } diff --git a/internal/executor/whoami.go b/internal/executor/whoami.go index a1673cb..4d068e9 100644 --- a/internal/executor/whoami.go +++ b/internal/executor/whoami.go @@ -15,16 +15,16 @@ import ( type WhoAmIExecutor struct { *flag.FlagSet - printer *printer.Printer - configDir string + printer *printer.Printer + config *config.Config } -func NewWhoAmIExecutor(printer *printer.Printer, configDir, name, summary string) *WhoAmIExecutor { +func NewWhoAmIExecutor(printer *printer.Printer, config *config.Config, name, summary string) *WhoAmIExecutor { whoExe := WhoAmIExecutor{ FlagSet: flag.NewFlagSet(name, flag.ExitOnError), - printer: printer, - configDir: configDir, + printer: printer, + config: config, } whoExe.Usage = commandUsageFunc(name, summary, whoExe.FlagSet) @@ -33,7 +33,7 @@ func NewWhoAmIExecutor(printer *printer.Printer, configDir, name, summary string } func (c *WhoAmIExecutor) Execute() error { - config, err := config.NewCredentialsConfigFromFile(c.configDir) + config, err := config.NewCredentialsConfigFromFile(c.config.CredentialsFile) if err != nil { return fmt.Errorf("unable to load the credential config: %w", err) } diff --git a/internal/internal.go b/internal/internal.go index 02566fd..7e36795 100644 --- a/internal/internal.go +++ b/internal/internal.go @@ -7,6 +7,6 @@ package internal const ( ApplicationName = "enbas" ApplicationWebsite = "https://codeflow.dananglin.me.uk/apollo/enbas" - RedirectUri = "urn:ietf:wg:oauth:2.0:oob" + RedirectURI = "urn:ietf:wg:oauth:2.0:oob" UserAgent = "Enbas/0.0.0" ) diff --git a/internal/model/application.go b/internal/model/application.go index 03f91f1..f251fd8 100644 --- a/internal/model/application.go +++ b/internal/model/application.go @@ -9,7 +9,7 @@ type Application struct { ClientSecret string `json:"client_secret"` ID string `json:"id"` Name string `json:"name"` - RedirectUri string `json:"redirect_uri"` + RedirectURI string `json:"redirect_uri"` VapidKey string `json:"vapid_key"` Website string `json:"website"` } diff --git a/internal/model/instance_v2.go b/internal/model/instance_v2.go index c1461d4..83a438f 100644 --- a/internal/model/instance_v2.go +++ b/internal/model/instance_v2.go @@ -95,7 +95,7 @@ type InstanceV2Thumbnail struct { ThumbnailDescription string `json:"thumbnail_description"` ThumbnailType string `json:"thumbnail_type"` URL string `json:"url"` - Versions InstanceV2ThumbnailVersions `json:"versions"` + Versions InstanceV2ThumbnailVersions `json:"versions"` } type InstanceV2ThumbnailVersions struct {