Skip to content

Instantly share code, notes, and snippets.

@suntong
Last active September 2, 2024 16:13
Show Gist options
  • Save suntong/bded5b6e2d53059ee003f6241b40f48d to your computer and use it in GitHub Desktop.
Save suntong/bded5b6e2d53059ee003f6241b40f48d to your computer and use it in GitHub Desktop.
gistpost create
////////////////////////////////////////////////////////////////////////////
// Program: gistpost
// Purpose: GH gist post/update tool
// Authors: Tong Sun (c) 2024-2024, All rights reserved
////////////////////////////////////////////////////////////////////////////
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"time"
"github.com/go-easygen/go-flags/clis"
)
////////////////////////////////////////////////////////////////////////////
// Constant and data type/structure definitions
type gistFile struct {
Content string `json:"content"`
}
type gistT struct {
Description string `json:"description"`
Files map[string]gistFile `json:"files"`
}
type gistCreate struct {
gistT
Public bool `json:"public"`
}
type gistOp struct {
method, url string
gistJson []byte
}
////////////////////////////////////////////////////////////////////////////
// Global variables definitions
////////////////////////////////////////////////////////////////////////////
// Function definitions
func optsCheck() {
// == Sanity check on variables from environment
if opts.Token == "" {
gfParser.WriteHelp(os.Stdout)
fmt.Println("\nError: The GISTPOST_TOKEN environment variable is required")
os.Exit(1)
}
if opts.Description == "" {
t := time.Now()
opts.Description = "Archived on " + t.Format(time.DateOnly)
}
if opts.Filename == "" {
opts.Filename = "archive.md"
}
// == Sanity check on stdin
// Get file information about stdin
info, err := os.Stdin.Stat()
if err != nil {
fmt.Println("Error checking stdin:", err)
os.Exit(1)
}
// Check if stdin is from a pipe
if info.Mode()&os.ModeCharDevice != 0 {
gfParser.WriteHelp(os.Stdout)
fmt.Println("\nError: This program reads input from pipe.")
os.Exit(1)
}
}
// // Exec implements the business logic of command `create`
func (x *CreateCommand) Exec(args []string) error {
// err := ...
// clis.WarnOn("create::Exec", err)
// or,
// clis.AbortOn("create::Exec", err)
optsCheck()
gop := x.gistPrep(readStdin())
return gistAction(gop)
}
func readStdin() []byte {
// Read content from stdin
content, err := ioutil.ReadAll(os.Stdin)
if err != nil {
log.Fatalf("Error reading stdin: %v", err)
}
if opts.Wrap {
content = []byte("```\n" + string(content) + "\n```\n")
}
return content
}
func (x *CreateCommand) gistPrep(content []byte) gistOp {
gist := gistT{
Description: opts.Description,
Files: map[string]gistFile{
opts.Filename: {Content: string(content)},
},
}
// Create-gist
gc := gistCreate{gist, x.Public}
// Convert gist to JSON
gistJson, err := json.Marshal(gc)
if err != nil {
log.Fatalf("Error marshaling Gist JSON: %v", err)
}
return gistOp{"POST", "https://api.github.com/gists", gistJson}
}
func gistAction(gop gistOp) error {
clis.Verbose(2, "%s Requesting to GitHub %s with %+v", gop.method, gop.url, string(gop.gistJson))
// Make the request to GitHub Gist API
client := &http.Client{}
req, err := http.NewRequest(gop.method, gop.url, bytes.NewBuffer(gop.gistJson))
if err != nil {
log.Fatalf("Error creating %s request: %v", gop.method, err)
}
req.Header.Set("Authorization", "token "+opts.Token)
req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
log.Fatalf("Error posting to GitHub Gist: %v", err)
}
defer resp.Body.Close()
if !(resp.StatusCode == http.StatusCreated ||
resp.StatusCode == http.StatusOK) {
log.Fatalf("Failed to %s to gist, status: %s", gop.method, resp.Status)
}
// Print the URL of the created gist
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Println("Gist url: ", result["html_url"])
return nil
}
//==========================================================================
// support functions
/*
Usage example:
export GP_GIST_T_TOKEN=github_pat_...
$ cat gistpost_main.go | gistpost -d 'gistpost main' -f main.go -p
Gist created: https://gist.github.com/suntong/923dabcb17c73e7ba435c0067eee3b19
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment