File: flags.go

package info (click to toggle)
addchain 0.4.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,396 kB
  • sloc: sh: 428; makefile: 10
file content (171 lines) | stat: -rw-r--r-- 3,702 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package main

import (
	"crypto/tls"
	"crypto/x509"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"

	"github.com/mmcloughlin/addchain/internal/metavars"
	"github.com/mmcloughlin/addchain/internal/zenodo"
)

// VarsFile represents a meta variables file.
type VarsFile struct {
	path string
}

// SetFlags registers command-line flags to configure the meta variables file.
func (v *VarsFile) SetFlags(f *flag.FlagSet) {
	f.StringVar(&v.path, "vars", v.DefaultPath(), "path to meta variables file")
}

// DefaultPath returns the path to the default variables file in the meta
// package. Returns the empty string if the path cannot be determined.
func (v *VarsFile) DefaultPath() string {
	return RepoPath("meta/vars.go")
}

// Get variable from the meta variables file.
func (v *VarsFile) Get(name string) (string, error) {
	f, err := metavars.ReadFile(v.path)
	if err != nil {
		return "", err
	}

	value, ok := f.Get(name)
	if !ok {
		return "", fmt.Errorf("unknown property %q", name)
	}

	return value, nil
}

// Set variable in the meta variables file.
func (v *VarsFile) Set(name, value string) error {
	f, err := metavars.ReadFile(v.path)
	if err != nil {
		return err
	}

	if err := f.Set(name, value); err != nil {
		return err
	}

	if err := metavars.WriteFile(v.path, f); err != nil {
		return err
	}

	return nil
}

// Zenodo configures a zenodo client.
type Zenodo struct {
	base    string
	sandbox bool
	token   string
}

const zenodoTokenEnvVar = "ZENODO_TOKEN"

// SetFlags registers command-line flags to configure the zenodo client.
func (z *Zenodo) SetFlags(f *flag.FlagSet) {
	f.StringVar(&z.base, "url", zenodo.BaseURL, "zenodo api base url")
	f.BoolVar(&z.sandbox, "sandbox", false, "use zenodo sandbox")
	f.StringVar(&z.token, "token", "", fmt.Sprintf("zenodo token (uses %q environment variable if empty)", zenodoTokenEnvVar))
}

// Token returns the configured zenodo token, either from the command-line or
// environment variable.
func (z *Zenodo) Token() (string, error) {
	if z.token != "" {
		return z.token, nil
	}
	if token, ok := os.LookupEnv(zenodoTokenEnvVar); ok {
		return token, nil
	}
	return "", errors.New("zenodo token not specified")
}

// URL to connect to.
func (z *Zenodo) URL() string {
	if z.sandbox {
		return zenodo.SandboxBaseURL
	}
	return z.base
}

// Client builds the configured client.
func (z *Zenodo) Client(c *http.Client) (*zenodo.Client, error) {
	// Token.
	token, err := z.Token()
	if err != nil {
		return nil, err
	}

	// Zenodo client.
	return zenodo.NewClient(c, z.URL(), token), nil
}

// HTTPClient configures a HTTP client.
type HTTPClient struct {
	cert string
}

// SetFlags registers command-line flags to configure the HTTP client.
func (h *HTTPClient) SetFlags(f *flag.FlagSet) {
	f.StringVar(&h.cert, "cert", "", "trust additional certificate authority certificate")
}

// Client builds a HTTP client according to configuration.
func (h *HTTPClient) Client() (*http.Client, error) {
	// CAs.
	roots, err := h.RootCAs()
	if err != nil {
		return nil, err
	}

	// Transport.
	tr := &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		TLSClientConfig: &tls.Config{
			MinVersion: tls.VersionTLS12,
			RootCAs:    roots,
		},
	}

	// Client.
	return &http.Client{
		Transport: tr,
	}, nil
}

// RootCAs returns the configured certificate pool.
func (h *HTTPClient) RootCAs() (*x509.CertPool, error) {
	roots, err := x509.SystemCertPool()
	if err != nil {
		return nil, err
	}

	if h.cert == "" {
		return roots, nil
	}

	data, err := ioutil.ReadFile(h.cert)
	if err != nil {
		return nil, err
	}

	cert, err := x509.ParseCertificate(data)
	if err != nil {
		return nil, err
	}

	roots.AddCert(cert)

	return roots, nil
}