wip(installer): stub experimental "installer"

Stubs out an experimental "installer" that will help new users to
quickly configure `cheat`.
This commit is contained in:
Chris Lane 2020-03-04 19:31:13 -05:00
parent ecac5a0971
commit ebd9ec6287
6 changed files with 127 additions and 4 deletions

View File

@ -5,13 +5,16 @@ package main
import (
"fmt"
"os"
"path"
"runtime"
"strings"
"github.com/docopt/docopt-go"
"github.com/mitchellh/go-homedir"
"github.com/cheat/cheat/internal/cheatpath"
"github.com/cheat/cheat/internal/config"
"github.com/cheat/cheat/internal/installer"
)
const version = "3.6.0"
@ -50,6 +53,64 @@ func main() {
confpath, err := config.Path(confpaths)
if err != nil {
// prompt the user to create a config file
yes, err := installer.Prompt(
"A config file was not found. Would you like to create one now? [Y/n]",
true,
)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to create config: %v\n", err)
os.Exit(1)
}
// exit early on a negative answer
if !yes {
os.Exit(0)
}
// prompt the user to create a config file
yes, err = installer.Prompt(
"Would you like to download the community cheatsheets? [Y/n]",
true,
)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to create config: %v\n", err)
os.Exit(1)
}
// clone the community cheatsheets if so instructed
if yes {
// get the user's home directory
home, err := homedir.Dir()
if err != nil {
fmt.Fprintf(
os.Stderr,
"failed to create config: failed to get user home directory: %v\n",
err,
)
os.Exit(1)
}
// clone the community cheatsheets
community := path.Join(home, ".config/cheat/cheatsheets/community")
if err := installer.Clone(community); err != nil {
fmt.Fprintf(os.Stderr, "failed to create config: %v\n", err)
os.Exit(1)
}
// create a directory for personal cheatsheets too
personal := path.Join(home, ".config/cheat/cheatsheets/personal")
if err := os.MkdirAll(personal, os.ModePerm); err != nil {
fmt.Fprintf(
os.Stderr,
"failed to create config: failed to create directory: %s: %v\n",
personal,
err)
os.Exit(1)
}
}
// the config file does not exist, so we'll try to create one
if err = config.Init(confpaths[0], configs()); err != nil {
fmt.Fprintf(

View File

@ -52,14 +52,14 @@ cheatpaths:
# Once downloaded, ensure that 'path' below points to the location at which
# you downloaded the community cheatsheets.
- name: community
path: ~/cheat/cheatsheets/community
path: ~/.config/cheat/cheatsheets/community
tags: [ community ]
readonly: true
# If you have personalized cheatsheets, list them last. They will take
# precedence over the more global cheatsheets.
- name: personal
path: ~/cheat/cheatsheets/personal
path: ~/.config/cheat/cheatsheets/personal
tags: [ personal ]
readonly: false

View File

@ -43,14 +43,14 @@ cheatpaths:
# Once downloaded, ensure that 'path' below points to the location at which
# you downloaded the community cheatsheets.
- name: community
path: ~/cheat/cheatsheets/community
path: ~/.config/cheat/cheatsheets/community
tags: [ community ]
readonly: true
# If you have personalized cheatsheets, list them last. They will take
# precedence over the more global cheatsheets.
- name: personal
path: ~/cheat/cheatsheets/personal
path: ~/.config/cheat/cheatsheets/personal
tags: [ personal ]
readonly: false

View File

@ -0,0 +1,24 @@
package installer
import (
"fmt"
"os"
"os/exec"
)
const cloneURL = "https://github.com/cheat/cheatsheets.git"
// Clone clones the community cheatsheets
func Clone(path string) error {
// perform the clone in a shell
cmd := exec.Command("git", "clone", cloneURL, path)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
return fmt.Errorf("failed to clone cheatsheets: %v", err)
}
return nil
}

View File

@ -0,0 +1 @@
package installer

View File

@ -0,0 +1,37 @@
package installer
import (
"bufio"
"fmt"
"os"
"strings"
)
// Prompt prompts the user for a answer
func Prompt(prompt string, def bool) (bool, error) {
// initialize a line reader
reader := bufio.NewReader(os.Stdin)
// display the prompt
fmt.Print(fmt.Sprintf("%s: ", prompt))
// read the answer
ans, err := reader.ReadString('\n')
if err != nil {
return false, fmt.Errorf("failed to parse input: %v", err)
}
// normalize the answer
ans = strings.ToLower(strings.TrimRight(ans, "\n"))
// return the appropriate response
switch ans {
case "y":
return true, nil
case "":
return def, nil
default:
return false, nil
}
}