commit e80961fe8ae238bac3883d9cffc9fe1941ae7bb6
parent ca426ad963867dc9a8223817e4f70d5a96bb5d5a
Author: Oliver Lowe <oliver.lowe@audinate.com>
Date: Wed, 11 Jun 2025 14:06:56 +1000
jira: common config file
Diffstat:
4 files changed, 125 insertions(+), 54 deletions(-)
diff --git a/cmd/jiraexport/config.go b/cmd/jiraexport/config.go
@@ -0,0 +1,54 @@
+package main
+
+import (
+ "bufio"
+ "fmt"
+ "net/url"
+ "os"
+ "strings"
+)
+
+type Config struct {
+ BaseURL *url.URL
+ Username string
+ Password string
+}
+
+func readConfig(name string) (*Config, error) {
+ f, err := os.Open(name)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ var conf Config
+ sc := bufio.NewScanner(f)
+ for sc.Scan() {
+ line := strings.TrimSpace(sc.Text())
+ if strings.HasPrefix(line, "#") {
+ continue
+ } else if line == "" {
+ continue
+ }
+ k, v, ok := strings.Cut(line, " ")
+ if !ok {
+ return nil, fmt.Errorf("key %s: expected whitespace after configuration key", k)
+ } else if v == "" {
+ return nil, fmt.Errorf("key %s: missing parameter", k)
+ }
+ switch k {
+ case "url":
+ u, err := url.Parse(v)
+ if err != nil {
+ return nil, fmt.Errorf("parse base url: %w", err)
+ }
+ conf.BaseURL = u
+ case "username":
+ conf.Username = v
+ case "password":
+ conf.Password = v
+ default:
+ return nil, fmt.Errorf("unknown configuration key %q", k)
+ }
+ }
+ return &conf, sc.Err()
+}
diff --git a/cmd/jiraexport/jiraexport.go b/cmd/jiraexport/jiraexport.go
@@ -29,14 +29,12 @@
package main
import (
- "bytes"
"flag"
"fmt"
"io"
"io/fs"
"log"
"net/mail"
- "net/url"
"os"
"path"
"strings"
@@ -45,23 +43,6 @@ import (
"olowe.co/issues/jira"
)
-func readJiraAuth() (user, pass string, err error) {
- confDir, err := os.UserConfigDir()
- if err != nil {
- return "", "", err
- }
- b, err := os.ReadFile(path.Join(confDir, "atlassian/jira"))
- if err != nil {
- return "", "", err
- }
- b = bytes.TrimSpace(b)
- u, p, ok := strings.Cut(string(b), ":")
- if !ok {
- return "", "", fmt.Errorf(`missing ":" between username and password`)
- }
- return u, p, nil
-}
-
func copyMessage(w io.Writer, msg *mail.Message) (n int, err error) {
for k, v := range msg.Header {
for i := range v {
@@ -98,19 +79,19 @@ func main() {
log.Fatal(usage)
}
- user, pass, err := readJiraAuth()
+ confDir, err := os.UserConfigDir()
if err != nil {
- log.Fatalf("read jira auth credentials: %v", err)
+ log.Fatal(err)
}
- u, err := url.Parse(*apiRoot)
+ confDir = path.Join(confDir, "atlassian/jira")
+ config, err := readConfig(confDir)
if err != nil {
- log.Fatalln("parse api url:", err)
+ log.Fatalln("read config:", err)
}
- u.Path = path.Join(u.Path, "rest/api/2")
jclient := &jira.Client{
- APIRoot: u,
- Username: user,
- Password: pass,
+ APIRoot: config.BaseURL,
+ Username: config.Username,
+ Password: config.Password,
Debug: false,
}
fsys := &jira.FS{Client: jclient}
diff --git a/cmd/jiraq/config.go b/cmd/jiraq/config.go
@@ -0,0 +1,54 @@
+package main
+
+import (
+ "bufio"
+ "fmt"
+ "net/url"
+ "os"
+ "strings"
+)
+
+type Config struct {
+ BaseURL *url.URL
+ Username string
+ Password string
+}
+
+func readConfig(name string) (*Config, error) {
+ f, err := os.Open(name)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ var conf Config
+ sc := bufio.NewScanner(f)
+ for sc.Scan() {
+ line := strings.TrimSpace(sc.Text())
+ if strings.HasPrefix(line, "#") {
+ continue
+ } else if line == "" {
+ continue
+ }
+ k, v, ok := strings.Cut(line, " ")
+ if !ok {
+ return nil, fmt.Errorf("key %s: expected whitespace after configuration key", k)
+ } else if v == "" {
+ return nil, fmt.Errorf("key %s: missing parameter", k)
+ }
+ switch k {
+ case "url":
+ u, err := url.Parse(v)
+ if err != nil {
+ return nil, fmt.Errorf("parse base url: %w", err)
+ }
+ conf.BaseURL = u
+ case "username":
+ conf.Username = v
+ case "password":
+ conf.Password = v
+ default:
+ return nil, fmt.Errorf("unknown configuration key %q", k)
+ }
+ }
+ return &conf, sc.Err()
+}
diff --git a/cmd/jiraq/jiraq.go b/cmd/jiraq/jiraq.go
@@ -30,11 +30,9 @@
package main
import (
- "bytes"
"flag"
"fmt"
"log"
- "net/url"
"os"
"path"
"strings"
@@ -42,23 +40,6 @@ import (
"olowe.co/issues/jira"
)
-func readJiraAuth() (user, pass string, err error) {
- confDir, err := os.UserConfigDir()
- if err != nil {
- return "", "", err
- }
- b, err := os.ReadFile(path.Join(confDir, "atlassian/jira"))
- if err != nil {
- return "", "", err
- }
- b = bytes.TrimSpace(b)
- u, p, ok := strings.Cut(string(b), ":")
- if !ok {
- return "", "", fmt.Errorf(`missing ":" between username and password`)
- }
- return u, p, nil
-}
-
var apiRoot = flag.String("u", "http://[::1]:8080", "base URL for the JIRA API")
const usage = "usage: jiraq [-u url] query"
@@ -74,19 +55,20 @@ func main() {
log.Fatal(usage)
}
- user, pass, err := readJiraAuth()
+ confDir, err := os.UserConfigDir()
if err != nil {
- log.Fatalf("read jira auth credentials: %v", err)
+ log.Fatal(err)
}
- u, err := url.Parse(*apiRoot)
+ confDir = path.Join(confDir, "atlassian/jira")
+ config, err := readConfig(confDir)
if err != nil {
- log.Fatalln("parse api url:", err)
+ log.Fatalln("read config:", err)
}
- u.Path = path.Join(u.Path, "rest/api/2")
+
client := &jira.Client{
- APIRoot: u,
- Username: user,
- Password: pass,
+ APIRoot: config.BaseURL,
+ Username: config.Username,
+ Password: config.Password,
}
issues, err := client.SearchIssues(strings.Join(flag.Args(), " "))