Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement primary configuration using XDG conventions. #131

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions api/learn/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import (
"testing"

"github.com/gSchool/glearn-cli/api"
"github.com/spf13/viper"
appConfig "github.com/gSchool/glearn-cli/app/config"
)

const validBlockResponse = `{"blocks":[{"id":1,"repo_name":"blocks-test","sync_errors":["somethin is wrong"],"title":"Blocks Test","cohorts_using":[7,9]}]}`

func Test_Getters(t *testing.T) {
viper.Set("api_token", "apiToken")
appConfig.Set("api_token", "apiToken")
mockClient := api.MockResponse(validBlockResponse)
API, _ := NewAPI("https://example.com", mockClient, false)

Expand All @@ -20,7 +20,7 @@ func Test_Getters(t *testing.T) {
}

func Test_GetBlockByRepoName(t *testing.T) {
viper.Set("api_token", "apiToken")
appConfig.Set("api_token", "apiToken")
mockClient := api.MockResponse(validBlockResponse)
API, _ := NewAPI("https://example.com", mockClient, false)

Expand Down Expand Up @@ -62,7 +62,7 @@ func Test_GetBlockByRepoName(t *testing.T) {
}

func Test_CreateBlockByRepoName(t *testing.T) {
viper.Set("api_token", "apiToken")
appConfig.Set("api_token", "apiToken")
mockClient := api.MockResponse(validBlockResponse)
API, _ := NewAPI("https://example.com", mockClient, false)

Expand Down Expand Up @@ -106,7 +106,7 @@ func Test_CreateBlockByRepoName(t *testing.T) {
const validMasterReleaseResponse = `{"release_id":9}`

func Test_CreateBranchRelease(t *testing.T) {
viper.Set("api_token", "apiToken")
appConfig.Set("api_token", "apiToken")
mockClient := api.MockResponse(validMasterReleaseResponse)
API, _ := NewAPI("https://example.com", mockClient, false)

Expand Down
9 changes: 6 additions & 3 deletions api/learn/learn.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"time"

"github.com/gSchool/glearn-cli/api"
"github.com/spf13/viper"
appConfig "github.com/gSchool/glearn-cli/app/config"
)

// API is the exported APIClient, it is set during Init
Expand Down Expand Up @@ -97,8 +97,11 @@ func (api *APIClient) BaseURL() string {
// from Learn. It returns a populated *S3Credentials struct or an error
func (api *APIClient) RetrieveCredentials(getPresignedPostUrl bool) (*Credentials, error) {
// Early return if user's api_token is not set
apiToken, ok := viper.Get("api_token").(string)
if !ok {
apiToken, err := appConfig.GetString("api_token")
if err != nil {
return nil, err
}
if apiToken == "" {
return nil, errors.New("Please set your API token with this command: learn set --api_token=your-token-from-https://learn-2.galvanize.com/api_token")
}

Expand Down
12 changes: 6 additions & 6 deletions api/learn/preview_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import (
"testing"

"github.com/gSchool/glearn-cli/api"
"github.com/spf13/viper"
appConfig "github.com/gSchool/glearn-cli/app/config"
)

const validPreviewResponse = `{"status":"success","release_id":1,"preview_url":"http://example.com"}`
const pendingPreviewResponse = `{"status":"pending","release_id":1,"preview_url":"http://example.com"}`
const credentialsResponse = `{"presigned_url":"https://aws-presigned-url.com", "dev_notify_url": "development","user_id":5,"user_email":"[email protected]"}`

func Test_PollForBuildResponse(t *testing.T) {
viper.Set("api_token", "apiToken")
appConfig.Set("api_token", "apiToken")
mockClient := api.MockResponse(validPreviewResponse)
API, _ := NewAPI("https://example.com", mockClient, true)

Expand Down Expand Up @@ -55,7 +55,7 @@ func Test_PollForBuildResponse(t *testing.T) {
}

func Test_PollForBuildResponse_EndAttempts(t *testing.T) {
viper.Set("api_token", "apiToken")
appConfig.Set("api_token", "apiToken")
mockClient := api.MockResponse(pendingPreviewResponse)
API, _ := NewAPI("https://example.com", mockClient, true)

Expand Down Expand Up @@ -97,7 +97,7 @@ func Test_PollForBuildResponse_EndAttempts(t *testing.T) {
}

func Test_BuildReleaseFromS3_Directory(t *testing.T) {
viper.Set("api_token", "apiToken")
appConfig.Set("api_token", "apiToken")
mockClient := api.MockResponse(validPreviewResponse)
API, _ := NewAPI("https://example.com", mockClient, true)

Expand Down Expand Up @@ -139,7 +139,7 @@ func Test_BuildReleaseFromS3_Directory(t *testing.T) {
}

func Test_BuildReleaseFromS3_notDirectory(t *testing.T) {
viper.Set("api_token", "apiToken")
appConfig.Set("api_token", "apiToken")
mockClient := api.MockResponses(credentialsResponse, validPreviewResponse)
API, _ := NewAPI("https://example.com", mockClient, true)

Expand Down Expand Up @@ -180,7 +180,7 @@ func Test_BuildReleaseFromS3_notDirectory(t *testing.T) {
}

func Test_RetrieveCredentials(t *testing.T) {
viper.Set("api_token", "apiToken")
appConfig.Set("api_token", "apiToken")
mockClient := api.MockResponse(credentialsResponse)
API, _ := NewAPI("https://example.com", mockClient, true)

Expand Down
4 changes: 2 additions & 2 deletions app/cmd/preview.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import (

"github.com/briandowns/spinner"
"github.com/spf13/cobra"
"github.com/spf13/viper"
yaml "gopkg.in/yaml.v2"

"github.com/gSchool/glearn-cli/api/learn"
appConfig "github.com/gSchool/glearn-cli/app/config"
di "github.com/gSchool/glearn-cli/ignorematcher"
"github.com/gSchool/glearn-cli/mdresourceparser"
)
Expand Down Expand Up @@ -54,7 +54,7 @@ type previewBuilder struct {
func NewPreviewBuilder(args []string) (*previewBuilder, error) {
setupLearnAPI(true)

if viper.Get("api_token") == "" || viper.Get("api_token") == nil {
if token, err := appConfig.GetString("api_token"); token == "" || err != nil {
return &previewBuilder{}, fmt.Errorf(setAPITokenMessage)
}

Expand Down
4 changes: 2 additions & 2 deletions app/cmd/publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (

"github.com/briandowns/spinner"
"github.com/gSchool/glearn-cli/api/learn"
appConfig "github.com/gSchool/glearn-cli/app/config"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

const (
Expand All @@ -33,7 +33,7 @@ new block. If the block already exists, it will update the existing block.
`,
Args: cobra.MinimumNArgs(0),
Run: func(cmd *cobra.Command, args []string) {
if viper.Get("api_token") == "" || viper.Get("api_token") == nil {
if token, err := appConfig.GetString("api_token"); token == "" || err != nil {
fmt.Fprintln(os.Stderr, setAPITokenMessage)
os.Exit(1)
}
Expand Down
40 changes: 1 addition & 39 deletions app/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,15 @@ package cmd
import (
"errors"
"fmt"
"io/ioutil"
"net/http"
"os"
"os/user"
"time"

"github.com/Masterminds/semver"
"github.com/gSchool/glearn-cli/api/github"
"github.com/gSchool/glearn-cli/api/learn"
"github.com/gSchool/glearn-cli/app/cmd/markdown"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

const setAPITokenMessage = `
Expand Down Expand Up @@ -53,9 +50,6 @@ Learn more by running 'learn walkthrough' to create sample materials, or visit
},
}

// APIToken is an initialized string used for holding it's flag value
var APIToken string

// UnitsDirectory is a flag for preview command that denotes a location for the units
var UnitsDirectory string

Expand All @@ -73,47 +67,15 @@ var IgnoreLocal bool
var CiCdEnvironment bool

func init() {
u, err := user.Current()
if err != nil {
fmt.Fprintln(os.Stderr, "Error retrieving your user path information")
os.Exit(1)
return
}

viper.AddConfigPath(u.HomeDir)
viper.SetConfigName(".glearn-config")

if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
// Config file not found. Either user's first time using CLI or they deleted it
configPath := fmt.Sprintf("%s/.glearn-config.yaml", u.HomeDir)
initialConfig := []byte(`api_token:`)

// Write a ~/.glearn-config.yaml file with all the needed credential keys to fill in.
err = ioutil.WriteFile(configPath, initialConfig, 0600)
if err != nil {
fmt.Fprintln(os.Stderr, "Error writing your glearn config file")
os.Exit(1)
return
}
} else {
// Config file was found but another error was produced
fmt.Fprintf(os.Stderr, "Error: %s", err)
os.Exit(1)
return
}
}

// Add all the other learn commands defined in cmd/ directory
rootCmd.AddCommand(markdown.NewMarkdownCommand())
rootCmd.AddCommand(NewSetCommand())
rootCmd.AddCommand(previewCmd)
rootCmd.AddCommand(publishCmd)
rootCmd.AddCommand(guideCmd)
rootCmd.AddCommand(setCmd)
rootCmd.AddCommand(versionCmd)

// Check for flags set by the user and hydrate their corresponding variables.
setCmd.Flags().StringVarP(&APIToken, "api_token", "", "", "Your Learn api token")
previewCmd.Flags().StringVarP(&UnitsDirectory, "units", "u", "", "The directory where your units exist")
previewCmd.Flags().BoolVarP(&OpenPreview, "open", "o", false, "Open the preview in the browser")
previewCmd.Flags().BoolVarP(&FileOnly, "fileonly", "x", false, "Excludes images when previewing a single file, defaults false")
Expand Down
62 changes: 41 additions & 21 deletions app/cmd/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,60 @@ import (
"fmt"
"os"

appConfig "github.com/gSchool/glearn-cli/app/config"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

// UpgradeConfig is an initialized Boolean indicating that the user wants to
// upgrade their config
var UpgradeConfig bool

// APIToken is an initialized string used for holding it's flag value
var APIToken string

func NewSetCommand() *cobra.Command {
setCmd.Flags().StringVarP(&APIToken, "api_token", "", "", "Your Learn api token")
setCmd.Flags().BoolVarP(&UpgradeConfig, "upgrade", "", false, "Upgrade your CLI config file")
return setCmd
}

var setCmd = &cobra.Command{
Use: "set --api_token=value",
Short: "Set your your credentials for ~/.glearn-config.yaml",
Long: `
In order to use learn resources through our CLI you must set your
credentials inside ~/.glearn-config.yaml
`,
Use: "set",
Short: fmt.Sprintf("Set your credentials in %s", appConfig.ConfigPath()),
Long: fmt.Sprintf(`In order to use learn resources through our CLI you must set your
credentials inside %s
`, appConfig.ConfigPath()),
Args: cobra.MinimumNArgs(0),
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 0 {
fmt.Fprintln(os.Stderr, "The set command does not take any arguments. Instead set variables with set --api_token=value")
os.Exit(1)
}

// If the --api_token=some_value flag was given, set it in viper
if APIToken == "" {
fmt.Fprintln(os.Stderr, "The set command needs '--api_token' flag.\n\nUse: learn set --api_token=value")
} else if !UpgradeConfig && APIToken == "" {
cmd.Usage()
os.Exit(1)
} else {
viper.Set("api_token", APIToken)
}

// Write any changes made above to the config
err := viper.WriteConfig()
if err != nil {
fmt.Fprintf(os.Stderr, "There was an error writing credentials to your config: %v", err)
os.Exit(1)
return
if UpgradeConfig {
if updated, err := appConfig.Upgrade(); err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
} else if updated {
fmt.Println("Configuration file upgraded")
}
}

fmt.Println("Successfully added credentials!")
// If the --api_token=some_value flag was given, set it in app config
if APIToken != "" {
appConfig.Set("api_token", APIToken)
// Write any changes made above to the config
err := appConfig.Write()
if err != nil {
fmt.Fprintf(os.Stderr, "There was an error writing credentials to your config: %v", err)
os.Exit(1)
return
}

fmt.Println("Successfully added credentials!")
}
},
}
Loading
Loading