Merge branch 'master' into flags-language
This commit is contained in:
commit
ae2e8f057c
7 changed files with 66 additions and 40 deletions
15
README.md
15
README.md
|
|
@ -14,23 +14,24 @@ _warning, gh is in a very alpha phase_
|
|||
|
||||
## Debian/Ubuntu Linux
|
||||
|
||||
1. Download the latest `.deb` file from the [releases page](https://github.com/github/gh-cli/releases)
|
||||
2. Install it with `sudo dpkg -i gh_0.2.2_linux_amd64.deb`, changing version number accordingly
|
||||
1. `sudo apt install git` if you don't already have git
|
||||
2. Download the `.deb` file from the [releases page](https://github.com/github/gh-cli/releases/latest)
|
||||
3. `sudo dpkg -i gh_*_linux_amd64.deb` install the downloaded file
|
||||
|
||||
_(Uninstall with `sudo apt remove gh`)_
|
||||
|
||||
## Fedora/Centos Linux
|
||||
|
||||
1. Download the latest `.rpm` file from the [releases page](https://github.com/github/gh-cli/releases)
|
||||
2. Install it with `sudo yum localinstall gh_0.2.2_linux_amd64.rpm`, changing version number accordingly
|
||||
1. Download the `.rpm` file from the [releases page](https://github.com/github/gh-cli/releases/latest)
|
||||
2. `sudo yum localinstall gh_*_linux_amd64.rpm` install the downloaded file
|
||||
|
||||
_(Uninstall with `sudo yum remove gh`)_
|
||||
|
||||
## Other Linux
|
||||
|
||||
1. Download the latest `_linux_amd64.tar.gz` file from the [releases page](https://github.com/github/gh-cli/releases)
|
||||
2. `tar -xvf gh_0.2.2_linux_amd64.tar.gz`, changing version number accordingly
|
||||
3. Copy the uncompressed `gh` somewhere on your `$PATH` (e.g. `sudo cp gh /usr/local/bin/`)
|
||||
1. Download the `_linux_amd64.tar.gz` file from the [releases page](https://github.com/github/gh-cli/releases/latest)
|
||||
2. `tar -xf gh_*_linux_amd64.tar.gz`
|
||||
3. Copy the uncompressed `gh` somewhere on your `$PATH` (e.g. `sudo cp gh_*_linux_amd64/bin/gh /usr/local/bin/`)
|
||||
|
||||
_(Uninstall with `rm`)_
|
||||
|
||||
|
|
|
|||
|
|
@ -2,13 +2,12 @@ package api
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type IssuesPayload struct {
|
||||
Assigned []Issue
|
||||
Mentioned []Issue
|
||||
Recent []Issue
|
||||
Authored []Issue
|
||||
}
|
||||
|
||||
type Issue struct {
|
||||
|
|
@ -91,11 +90,11 @@ func IssueStatus(client *Client, ghRepo Repo, currentUsername string) (*IssuesPa
|
|||
type response struct {
|
||||
Assigned apiIssues
|
||||
Mentioned apiIssues
|
||||
Recent apiIssues
|
||||
Authored apiIssues
|
||||
}
|
||||
|
||||
query := fragments + `
|
||||
query($owner: String!, $repo: String!, $since: DateTime!, $viewer: String!, $per_page: Int = 10) {
|
||||
query($owner: String!, $repo: String!, $viewer: String!, $per_page: Int = 10) {
|
||||
assigned: repository(owner: $owner, name: $repo) {
|
||||
issues(filterBy: {assignee: $viewer, states: OPEN}, first: $per_page, orderBy: {field: CREATED_AT, direction: DESC}) {
|
||||
nodes {
|
||||
|
|
@ -110,8 +109,8 @@ func IssueStatus(client *Client, ghRepo Repo, currentUsername string) (*IssuesPa
|
|||
}
|
||||
}
|
||||
}
|
||||
recent: repository(owner: $owner, name: $repo) {
|
||||
issues(filterBy: {since: $since, states: OPEN}, first: $per_page, orderBy: {field: CREATED_AT, direction: DESC}) {
|
||||
authored: repository(owner: $owner, name: $repo) {
|
||||
issues(filterBy: {createdBy: $viewer, states: OPEN}, first: $per_page, orderBy: {field: CREATED_AT, direction: DESC}) {
|
||||
nodes {
|
||||
...issue
|
||||
}
|
||||
|
|
@ -122,12 +121,10 @@ func IssueStatus(client *Client, ghRepo Repo, currentUsername string) (*IssuesPa
|
|||
|
||||
owner := ghRepo.RepoOwner()
|
||||
repo := ghRepo.RepoName()
|
||||
since := time.Now().UTC().Add(time.Hour * -24).Format("2006-01-02T15:04:05-0700")
|
||||
variables := map[string]interface{}{
|
||||
"owner": owner,
|
||||
"repo": repo,
|
||||
"viewer": currentUsername,
|
||||
"since": since,
|
||||
}
|
||||
|
||||
var resp response
|
||||
|
|
@ -139,7 +136,7 @@ func IssueStatus(client *Client, ghRepo Repo, currentUsername string) (*IssuesPa
|
|||
payload := IssuesPayload{
|
||||
Assigned: resp.Assigned.Issues.Nodes,
|
||||
Mentioned: resp.Mentioned.Issues.Nodes,
|
||||
Recent: resp.Recent.Issues.Nodes,
|
||||
Authored: resp.Authored.Issues.Nodes,
|
||||
}
|
||||
|
||||
return &payload, nil
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func randomString(length int) (string, error) {
|
||||
|
|
@ -101,11 +102,14 @@ func openInBrowser(url string) error {
|
|||
args = []string{"open"}
|
||||
case "windows":
|
||||
args = []string{"cmd", "/c", "start"}
|
||||
r := strings.NewReplacer("&", "^&")
|
||||
url = r.Replace(url)
|
||||
default:
|
||||
args = []string{"xdg-open"}
|
||||
}
|
||||
|
||||
args = append(args, url)
|
||||
cmd := exec.Command(args[0], args[1:]...)
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,20 +14,9 @@ import (
|
|||
|
||||
func init() {
|
||||
RootCmd.AddCommand(issueCmd)
|
||||
issueCmd.AddCommand(
|
||||
&cobra.Command{
|
||||
Use: "status",
|
||||
Short: "Show status of relevant issues",
|
||||
RunE: issueStatus,
|
||||
},
|
||||
&cobra.Command{
|
||||
Use: "view <issue-number>",
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Short: "View an issue in the browser",
|
||||
RunE: issueView,
|
||||
},
|
||||
)
|
||||
issueCmd.AddCommand(issueCreateCmd)
|
||||
issueCmd.AddCommand(issueStatusCmd)
|
||||
issueCmd.AddCommand(issueViewCmd)
|
||||
issueCreateCmd.Flags().StringP("title", "t", "",
|
||||
"Supply a title. Will prompt for one otherwise.")
|
||||
issueCreateCmd.Flags().StringP("body", "b", "",
|
||||
|
|
@ -56,6 +45,17 @@ var issueCreateCmd = &cobra.Command{
|
|||
Short: "Create a new issue",
|
||||
RunE: issueCreate,
|
||||
}
|
||||
var issueStatusCmd = &cobra.Command{
|
||||
Use: "status",
|
||||
Short: "Show status of relevant issues",
|
||||
RunE: issueStatus,
|
||||
}
|
||||
var issueViewCmd = &cobra.Command{
|
||||
Use: "view <issue-number>",
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Short: "View an issue in the browser",
|
||||
RunE: issueView,
|
||||
}
|
||||
|
||||
func issueList(cmd *cobra.Command, args []string) error {
|
||||
ctx := contextForCommand(cmd)
|
||||
|
|
@ -158,11 +158,11 @@ func issueStatus(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
fmt.Println()
|
||||
|
||||
printHeader("Recent issues")
|
||||
if len(issuePayload.Recent) > 0 {
|
||||
printIssues(" ", issuePayload.Recent...)
|
||||
printHeader("Issues opened by you")
|
||||
if len(issuePayload.Authored) > 0 {
|
||||
printIssues(" ", issuePayload.Authored...)
|
||||
} else {
|
||||
printMessage(" There are no recent issues")
|
||||
printMessage(" There are no issues opened by you")
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package command
|
|||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/github/gh-cli/api"
|
||||
"github.com/github/gh-cli/context"
|
||||
|
|
@ -17,8 +18,10 @@ var Version = "DEV"
|
|||
var BuildDate = "YYYY-MM-DD"
|
||||
|
||||
func init() {
|
||||
RootCmd.Version = fmt.Sprintf("%s (%s)", Version, BuildDate)
|
||||
RootCmd.PersistentFlags().StringP("repo", "R", "", "Current GitHub repository")
|
||||
RootCmd.Version = fmt.Sprintf("%s (%s)", strings.TrimPrefix(Version, "v"), BuildDate)
|
||||
RootCmd.AddCommand(versionCmd)
|
||||
|
||||
RootCmd.PersistentFlags().StringP("repo", "R", "", "Current GitHub repository")
|
||||
RootCmd.PersistentFlags().Bool("help", false, "Show help for command")
|
||||
RootCmd.Flags().Bool("version", false, "Print gh version")
|
||||
// TODO:
|
||||
|
|
@ -38,11 +41,20 @@ type FlagError struct {
|
|||
var RootCmd = &cobra.Command{
|
||||
Use: "gh",
|
||||
Short: "GitHub CLI",
|
||||
Long: `Work seamlessly with GitHub from the command line`,
|
||||
Long: `Work seamlessly with GitHub from the command line`,
|
||||
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
}
|
||||
|
||||
var versionCmd = &cobra.Command{
|
||||
Use: "version",
|
||||
Hidden: true,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Printf("gh version %s\n", RootCmd.Version)
|
||||
},
|
||||
}
|
||||
|
||||
// overriden in tests
|
||||
var initContext = func() context.Context {
|
||||
ctx := context.New()
|
||||
|
|
|
|||
2
test/fixtures/issueStatus.json
vendored
2
test/fixtures/issueStatus.json
vendored
|
|
@ -28,7 +28,7 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"recent": {
|
||||
"authored": {
|
||||
"issues": {
|
||||
"nodes": []
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,11 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/mattn/go-isatty"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
)
|
||||
|
||||
|
|
@ -17,11 +21,19 @@ type TablePrinter interface {
|
|||
|
||||
func NewTablePrinter(w io.Writer) TablePrinter {
|
||||
if outFile, isFile := w.(*os.File); isFile {
|
||||
fd := int(outFile.Fd())
|
||||
if terminal.IsTerminal(fd) {
|
||||
isCygwin := isatty.IsCygwinTerminal(outFile.Fd())
|
||||
if isatty.IsTerminal(outFile.Fd()) || isCygwin {
|
||||
ttyWidth := 80
|
||||
if w, _, err := terminal.GetSize(fd); err == nil {
|
||||
if w, _, err := terminal.GetSize(int(outFile.Fd())); err == nil {
|
||||
ttyWidth = w
|
||||
} else if isCygwin {
|
||||
tputCmd := exec.Command("tput", "cols")
|
||||
tputCmd.Stdin = os.Stdin
|
||||
if out, err := tputCmd.Output(); err == nil {
|
||||
if w, err := strconv.Atoi(strings.TrimSpace(string(out))); err == nil {
|
||||
ttyWidth = w
|
||||
}
|
||||
}
|
||||
}
|
||||
return &ttyTablePrinter{
|
||||
out: w,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue