Merge ~dviererbe/ubuntu/+source/dh-make-golang:lp2046369 into ubuntu/+source/dh-make-golang:ubuntu/devel

Proposed by Dominik Viererbe
Status: Merged
Merge reported by: Dominik Viererbe
Merged at revision: 0b036a097be51a70929463d03e311e58b84ccd06
Proposed branch: ~dviererbe/ubuntu/+source/dh-make-golang:lp2046369
Merge into: ubuntu/+source/dh-make-golang:ubuntu/devel
Diff against target: 1435 lines (+1309/-2)
11 files modified
debian/changelog (+12/-0)
debian/control (+2/-1)
debian/copyright (+4/-0)
debian/go/src/golang.org/x/tools/go/vcs/discovery.go (+83/-0)
debian/go/src/golang.org/x/tools/go/vcs/env.go (+39/-0)
debian/go/src/golang.org/x/tools/go/vcs/go.mod (+7/-0)
debian/go/src/golang.org/x/tools/go/vcs/http.go (+80/-0)
debian/go/src/golang.org/x/tools/go/vcs/vcs.go (+764/-0)
debian/go/src/golang.org/x/tools/go/vcs/vcs_test.go (+309/-0)
debian/rules (+9/-0)
dev/null (+0/-1)
Reviewer Review Type Date Requested Status
Simon Chopin Pending
git-ubuntu import Pending
Review via email: mp+463019@code.launchpad.net

Description of the change

Fixes FTBFS of 0.6.0-2build1 (LP: #2046369) by backporting changes from 0.7.0-1 in debian sid.

Syncing 0.7.0-1 is currently undesirable, because it requires a sync of golang-github-google-go-github 60.0.0-1 from debian sid, which causes reverse dependencies to FTBFS. We can address this issue and remove the delta next cycle, but the Beta release is too close address it now.

To post a comment you must log in.
Revision history for this message
Dominik Viererbe (dviererbe) wrote :

* Builds in a PPA with proposed enabled: https://launchpad.net/~dviererbe/+archive/ubuntu/lp2046369-ppa2/+packages
* The package has no autopkgtests.

Revision history for this message
Dominik Viererbe (dviererbe) wrote :

Someone synced 0.7.0-1 and golang-github-google-go-github 60.0.0-1 anyway. Therefore this merge is not needed anymore.

Note: I set the state to "merged" even though this MP never got merged, because there is no state to "reject" the merge.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/debian/changelog b/debian/changelog
index c231f11..77e461b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,15 @@
1dh-make-golang (0.6.0-2ubuntu1) noble; urgency=medium
2
3 * Disable lto.
4 * Include copy of golang.org/x/tools/go/vcs@v0.1.0-deprecated (LP: #2046369);
5 backported from 0.7.0-1 in debian unstable (see debian bug: #1043070):
6 - debian/go/src/golang.org/x/tools/go/vcs
7 - debian/copyright: add copiright information
8 - debian/rules: add execute_after_dh_auto_configure target to configure copy
9 - debian/patches/*: removed
10
11 -- Dominik Viererbe <dominik.viererbe@canonical.com> Mon, 25 Mar 2024 13:27:14 +0200
12
1dh-make-golang (0.6.0-2build1) mantic; urgency=medium13dh-make-golang (0.6.0-2build1) mantic; urgency=medium
214
3 * No-change rebuild with Go 1.21.15 * No-change rebuild with Go 1.21.
diff --git a/debian/control b/debian/control
index 553d6f6..bd69f19 100644
--- a/debian/control
+++ b/debian/control
@@ -1,5 +1,6 @@
1Source: dh-make-golang1Source: dh-make-golang
2Maintainer: Debian Go Packaging Team <team+pkg-go@tracker.debian.org>2Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
3XSBC-Original-Maintainer: Debian Go Packaging Team <team+pkg-go@tracker.debian.org>
3Uploaders: Michael Stapelberg <stapelberg@debian.org>,4Uploaders: Michael Stapelberg <stapelberg@debian.org>,
4 Dr. Tobias Quathamer <toddy@debian.org>,5 Dr. Tobias Quathamer <toddy@debian.org>,
5 Anthony Fok <foka@debian.org>,6 Anthony Fok <foka@debian.org>,
diff --git a/debian/copyright b/debian/copyright
index d05ed52..a7307d5 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -16,6 +16,10 @@ Copyright:
16License: BSD-3-clause16License: BSD-3-clause
17Comment: Debian packaging is licensed under the same terms as upstream17Comment: Debian packaging is licensed under the same terms as upstream
1818
19Files: debian/go/src/golang.org/x/tools/go/vcs/*
20Copyright: 2009 The Go Authors
21License: BSD-3-clause
22
19License: BSD-3-clause23License: BSD-3-clause
20 Copyright © 2015, Michael Stapelberg, Google Inc. and contributors24 Copyright © 2015, Michael Stapelberg, Google Inc. and contributors
21 All rights reserved.25 All rights reserved.
diff --git a/debian/go/src/golang.org/x/tools/go/vcs/discovery.go b/debian/go/src/golang.org/x/tools/go/vcs/discovery.go
22new file mode 10064426new file mode 100644
index 0000000..7d179bc
--- /dev/null
+++ b/debian/go/src/golang.org/x/tools/go/vcs/discovery.go
@@ -0,0 +1,83 @@
1// Copyright 2012 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package vcs
6
7import (
8 "encoding/xml"
9 "fmt"
10 "io"
11 "strings"
12)
13
14// charsetReader returns a reader for the given charset. Currently
15// it only supports UTF-8 and ASCII. Otherwise, it returns a meaningful
16// error which is printed by go get, so the user can find why the package
17// wasn't downloaded if the encoding is not supported. Note that, in
18// order to reduce potential errors, ASCII is treated as UTF-8 (i.e. characters
19// greater than 0x7f are not rejected).
20func charsetReader(charset string, input io.Reader) (io.Reader, error) {
21 switch strings.ToLower(charset) {
22 case "ascii":
23 return input, nil
24 default:
25 return nil, fmt.Errorf("can't decode XML document using charset %q", charset)
26 }
27}
28
29// parseMetaGoImports returns meta imports from the HTML in r.
30// Parsing ends at the end of the <head> section or the beginning of the <body>.
31//
32// This copy of cmd/go/internal/vcs.parseMetaGoImports always operates
33// in IgnoreMod ModuleMode.
34func parseMetaGoImports(r io.Reader) (imports []metaImport, err error) {
35 d := xml.NewDecoder(r)
36 d.CharsetReader = charsetReader
37 d.Strict = false
38 var t xml.Token
39 for {
40 t, err = d.RawToken()
41 if err != nil {
42 if err == io.EOF || len(imports) > 0 {
43 err = nil
44 }
45 return
46 }
47 if e, ok := t.(xml.StartElement); ok && strings.EqualFold(e.Name.Local, "body") {
48 return
49 }
50 if e, ok := t.(xml.EndElement); ok && strings.EqualFold(e.Name.Local, "head") {
51 return
52 }
53 e, ok := t.(xml.StartElement)
54 if !ok || !strings.EqualFold(e.Name.Local, "meta") {
55 continue
56 }
57 if attrValue(e.Attr, "name") != "go-import" {
58 continue
59 }
60 if f := strings.Fields(attrValue(e.Attr, "content")); len(f) == 3 {
61 // Ignore VCS type "mod", which is applicable only in module mode.
62 if f[1] == "mod" {
63 continue
64 }
65 imports = append(imports, metaImport{
66 Prefix: f[0],
67 VCS: f[1],
68 RepoRoot: f[2],
69 })
70 }
71 }
72}
73
74// attrValue returns the attribute value for the case-insensitive key
75// `name', or the empty string if nothing is found.
76func attrValue(attrs []xml.Attr, name string) string {
77 for _, a := range attrs {
78 if strings.EqualFold(a.Name.Local, name) {
79 return a.Value
80 }
81 }
82 return ""
83}
diff --git a/debian/go/src/golang.org/x/tools/go/vcs/env.go b/debian/go/src/golang.org/x/tools/go/vcs/env.go
0new file mode 10064484new file mode 100644
index 0000000..189210c
--- /dev/null
+++ b/debian/go/src/golang.org/x/tools/go/vcs/env.go
@@ -0,0 +1,39 @@
1// Copyright 2013 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package vcs
6
7import (
8 "os"
9 "strings"
10)
11
12// envForDir returns a copy of the environment
13// suitable for running in the given directory.
14// The environment is the current process's environment
15// but with an updated $PWD, so that an os.Getwd in the
16// child will be faster.
17func envForDir(dir string) []string {
18 env := os.Environ()
19 // Internally we only use rooted paths, so dir is rooted.
20 // Even if dir is not rooted, no harm done.
21 return mergeEnvLists([]string{"PWD=" + dir}, env)
22}
23
24// mergeEnvLists merges the two environment lists such that
25// variables with the same name in "in" replace those in "out".
26func mergeEnvLists(in, out []string) []string {
27NextVar:
28 for _, inkv := range in {
29 k := strings.SplitAfterN(inkv, "=", 2)[0]
30 for i, outkv := range out {
31 if strings.HasPrefix(outkv, k) {
32 out[i] = inkv
33 continue NextVar
34 }
35 }
36 out = append(out, inkv)
37 }
38 return out
39}
diff --git a/debian/go/src/golang.org/x/tools/go/vcs/go.mod b/debian/go/src/golang.org/x/tools/go/vcs/go.mod
0new file mode 10064440new file mode 100644
index 0000000..74da6cb
--- /dev/null
+++ b/debian/go/src/golang.org/x/tools/go/vcs/go.mod
@@ -0,0 +1,7 @@
1// Deprecated: This module contains one deprecated package.
2// See the package deprecation notice for more information.
3module golang.org/x/tools/go/vcs
4
5go 1.19
6
7require golang.org/x/sys v0.9.0
diff --git a/debian/go/src/golang.org/x/tools/go/vcs/http.go b/debian/go/src/golang.org/x/tools/go/vcs/http.go
0new file mode 1006448new file mode 100644
index 0000000..5836511
--- /dev/null
+++ b/debian/go/src/golang.org/x/tools/go/vcs/http.go
@@ -0,0 +1,80 @@
1// Copyright 2012 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package vcs
6
7import (
8 "fmt"
9 "io"
10 "io/ioutil"
11 "log"
12 "net/http"
13 "net/url"
14)
15
16// httpClient is the default HTTP client, but a variable so it can be
17// changed by tests, without modifying http.DefaultClient.
18var httpClient = http.DefaultClient
19
20// httpGET returns the data from an HTTP GET request for the given URL.
21func httpGET(url string) ([]byte, error) {
22 resp, err := httpClient.Get(url)
23 if err != nil {
24 return nil, err
25 }
26 defer resp.Body.Close()
27 if resp.StatusCode != 200 {
28 return nil, fmt.Errorf("%s: %s", url, resp.Status)
29 }
30 b, err := ioutil.ReadAll(resp.Body)
31 if err != nil {
32 return nil, fmt.Errorf("%s: %v", url, err)
33 }
34 return b, nil
35}
36
37// httpsOrHTTP returns the body of either the importPath's
38// https resource or, if unavailable, the http resource.
39func httpsOrHTTP(importPath string) (urlStr string, body io.ReadCloser, err error) {
40 fetch := func(scheme string) (urlStr string, res *http.Response, err error) {
41 u, err := url.Parse(scheme + "://" + importPath)
42 if err != nil {
43 return "", nil, err
44 }
45 u.RawQuery = "go-get=1"
46 urlStr = u.String()
47 if Verbose {
48 log.Printf("Fetching %s", urlStr)
49 }
50 res, err = httpClient.Get(urlStr)
51 return
52 }
53 closeBody := func(res *http.Response) {
54 if res != nil {
55 res.Body.Close()
56 }
57 }
58 urlStr, res, err := fetch("https")
59 if err != nil || res.StatusCode != 200 {
60 if Verbose {
61 if err != nil {
62 log.Printf("https fetch failed.")
63 } else {
64 log.Printf("ignoring https fetch with status code %d", res.StatusCode)
65 }
66 }
67 closeBody(res)
68 urlStr, res, err = fetch("http")
69 }
70 if err != nil {
71 closeBody(res)
72 return "", nil, err
73 }
74 // Note: accepting a non-200 OK here, so people can serve a
75 // meta import in their http 404 page.
76 if Verbose {
77 log.Printf("Parsing meta tags from %s (status code %d)", urlStr, res.StatusCode)
78 }
79 return urlStr, res.Body, nil
80}
diff --git a/debian/go/src/golang.org/x/tools/go/vcs/vcs.go b/debian/go/src/golang.org/x/tools/go/vcs/vcs.go
0new file mode 10064481new file mode 100644
index 0000000..232177d
--- /dev/null
+++ b/debian/go/src/golang.org/x/tools/go/vcs/vcs.go
@@ -0,0 +1,764 @@
1// Copyright 2012 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package vcs exposes functions for resolving import paths
6// and using version control systems, which can be used to
7// implement behavior similar to the standard "go get" command.
8//
9// Deprecated: Use the go list command with -json flag instead,
10// which implements up-to-date import path resolution behavior,
11// module support, and includes the latest security fixes.
12//
13// This package was a copy of internal code in package cmd/go/internal/get
14// before module support, modified to make the identifiers exported.
15// It was provided here for developers who wanted to write tools with similar semantics.
16// It needed to be manually kept in sync with upstream when changes were
17// made to cmd/go/internal/get, as tracked in go.dev/issue/11490.
18// By now, it has diverged significantly from upstream cmd/go/internal/get
19// behavior and will not receive any further updates.
20package vcs // import "golang.org/x/tools/go/vcs"
21
22import (
23 "bytes"
24 "encoding/json"
25 "errors"
26 "fmt"
27 exec "golang.org/x/sys/execabs"
28 "log"
29 "net/url"
30 "os"
31 "path/filepath"
32 "regexp"
33 "strconv"
34 "strings"
35)
36
37// Verbose enables verbose operation logging.
38var Verbose bool
39
40// ShowCmd controls whether VCS commands are printed.
41var ShowCmd bool
42
43// A Cmd describes how to use a version control system
44// like Mercurial, Git, or Subversion.
45type Cmd struct {
46 Name string
47 Cmd string // name of binary to invoke command
48
49 CreateCmd string // command to download a fresh copy of a repository
50 DownloadCmd string // command to download updates into an existing repository
51
52 TagCmd []TagCmd // commands to list tags
53 TagLookupCmd []TagCmd // commands to lookup tags before running tagSyncCmd
54 TagSyncCmd string // command to sync to specific tag
55 TagSyncDefault string // command to sync to default tag
56
57 LogCmd string // command to list repository changelogs in an XML format
58
59 Scheme []string
60 PingCmd string
61}
62
63// A TagCmd describes a command to list available tags
64// that can be passed to Cmd.TagSyncCmd.
65type TagCmd struct {
66 Cmd string // command to list tags
67 Pattern string // regexp to extract tags from list
68}
69
70// vcsList lists the known version control systems
71var vcsList = []*Cmd{
72 vcsHg,
73 vcsGit,
74 vcsSvn,
75 vcsBzr,
76}
77
78// ByCmd returns the version control system for the given
79// command name (hg, git, svn, bzr).
80func ByCmd(cmd string) *Cmd {
81 for _, vcs := range vcsList {
82 if vcs.Cmd == cmd {
83 return vcs
84 }
85 }
86 return nil
87}
88
89// vcsHg describes how to use Mercurial.
90var vcsHg = &Cmd{
91 Name: "Mercurial",
92 Cmd: "hg",
93
94 CreateCmd: "clone -U {repo} {dir}",
95 DownloadCmd: "pull",
96
97 // We allow both tag and branch names as 'tags'
98 // for selecting a version. This lets people have
99 // a go.release.r60 branch and a go1 branch
100 // and make changes in both, without constantly
101 // editing .hgtags.
102 TagCmd: []TagCmd{
103 {"tags", `^(\S+)`},
104 {"branches", `^(\S+)`},
105 },
106 TagSyncCmd: "update -r {tag}",
107 TagSyncDefault: "update default",
108
109 LogCmd: "log --encoding=utf-8 --limit={limit} --template={template}",
110
111 Scheme: []string{"https", "http", "ssh"},
112 PingCmd: "identify {scheme}://{repo}",
113}
114
115// vcsGit describes how to use Git.
116var vcsGit = &Cmd{
117 Name: "Git",
118 Cmd: "git",
119
120 CreateCmd: "clone {repo} {dir}",
121 DownloadCmd: "pull --ff-only",
122
123 TagCmd: []TagCmd{
124 // tags/xxx matches a git tag named xxx
125 // origin/xxx matches a git branch named xxx on the default remote repository
126 {"show-ref", `(?:tags|origin)/(\S+)$`},
127 },
128 TagLookupCmd: []TagCmd{
129 {"show-ref tags/{tag} origin/{tag}", `((?:tags|origin)/\S+)$`},
130 },
131 TagSyncCmd: "checkout {tag}",
132 TagSyncDefault: "checkout master",
133
134 Scheme: []string{"git", "https", "http", "git+ssh"},
135 PingCmd: "ls-remote {scheme}://{repo}",
136}
137
138// vcsBzr describes how to use Bazaar.
139var vcsBzr = &Cmd{
140 Name: "Bazaar",
141 Cmd: "bzr",
142
143 CreateCmd: "branch {repo} {dir}",
144
145 // Without --overwrite bzr will not pull tags that changed.
146 // Replace by --overwrite-tags after http://pad.lv/681792 goes in.
147 DownloadCmd: "pull --overwrite",
148
149 TagCmd: []TagCmd{{"tags", `^(\S+)`}},
150 TagSyncCmd: "update -r {tag}",
151 TagSyncDefault: "update -r revno:-1",
152
153 Scheme: []string{"https", "http", "bzr", "bzr+ssh"},
154 PingCmd: "info {scheme}://{repo}",
155}
156
157// vcsSvn describes how to use Subversion.
158var vcsSvn = &Cmd{
159 Name: "Subversion",
160 Cmd: "svn",
161
162 CreateCmd: "checkout {repo} {dir}",
163 DownloadCmd: "update",
164
165 // There is no tag command in subversion.
166 // The branch information is all in the path names.
167
168 LogCmd: "log --xml --limit={limit}",
169
170 Scheme: []string{"https", "http", "svn", "svn+ssh"},
171 PingCmd: "info {scheme}://{repo}",
172}
173
174func (v *Cmd) String() string {
175 return v.Name
176}
177
178// run runs the command line cmd in the given directory.
179// keyval is a list of key, value pairs. run expands
180// instances of {key} in cmd into value, but only after
181// splitting cmd into individual arguments.
182// If an error occurs, run prints the command line and the
183// command's combined stdout+stderr to standard error.
184// Otherwise run discards the command's output.
185func (v *Cmd) run(dir string, cmd string, keyval ...string) error {
186 _, err := v.run1(dir, cmd, keyval, true)
187 return err
188}
189
190// runVerboseOnly is like run but only generates error output to standard error in verbose mode.
191func (v *Cmd) runVerboseOnly(dir string, cmd string, keyval ...string) error {
192 _, err := v.run1(dir, cmd, keyval, false)
193 return err
194}
195
196// runOutput is like run but returns the output of the command.
197func (v *Cmd) runOutput(dir string, cmd string, keyval ...string) ([]byte, error) {
198 return v.run1(dir, cmd, keyval, true)
199}
200
201// run1 is the generalized implementation of run and runOutput.
202func (v *Cmd) run1(dir string, cmdline string, keyval []string, verbose bool) ([]byte, error) {
203 m := make(map[string]string)
204 for i := 0; i < len(keyval); i += 2 {
205 m[keyval[i]] = keyval[i+1]
206 }
207 args := strings.Fields(cmdline)
208 for i, arg := range args {
209 args[i] = expand(m, arg)
210 }
211
212 _, err := exec.LookPath(v.Cmd)
213 if err != nil {
214 fmt.Fprintf(os.Stderr,
215 "go: missing %s command. See http://golang.org/s/gogetcmd\n",
216 v.Name)
217 return nil, err
218 }
219
220 cmd := exec.Command(v.Cmd, args...)
221 cmd.Dir = dir
222 cmd.Env = envForDir(cmd.Dir)
223 if ShowCmd {
224 fmt.Printf("cd %s\n", dir)
225 fmt.Printf("%s %s\n", v.Cmd, strings.Join(args, " "))
226 }
227 var buf bytes.Buffer
228 cmd.Stdout = &buf
229 cmd.Stderr = &buf
230 err = cmd.Run()
231 out := buf.Bytes()
232 if err != nil {
233 if verbose || Verbose {
234 fmt.Fprintf(os.Stderr, "# cd %s; %s %s\n", dir, v.Cmd, strings.Join(args, " "))
235 os.Stderr.Write(out)
236 }
237 return nil, err
238 }
239 return out, nil
240}
241
242// Ping pings the repo to determine if scheme used is valid.
243// This repo must be pingable with this scheme and VCS.
244func (v *Cmd) Ping(scheme, repo string) error {
245 return v.runVerboseOnly(".", v.PingCmd, "scheme", scheme, "repo", repo)
246}
247
248// Create creates a new copy of repo in dir.
249// The parent of dir must exist; dir must not.
250func (v *Cmd) Create(dir, repo string) error {
251 return v.run(".", v.CreateCmd, "dir", dir, "repo", repo)
252}
253
254// CreateAtRev creates a new copy of repo in dir at revision rev.
255// The parent of dir must exist; dir must not.
256// rev must be a valid revision in repo.
257func (v *Cmd) CreateAtRev(dir, repo, rev string) error {
258 if err := v.Create(dir, repo); err != nil {
259 return err
260 }
261 return v.run(dir, v.TagSyncCmd, "tag", rev)
262}
263
264// Download downloads any new changes for the repo in dir.
265// dir must be a valid VCS repo compatible with v.
266func (v *Cmd) Download(dir string) error {
267 return v.run(dir, v.DownloadCmd)
268}
269
270// Tags returns the list of available tags for the repo in dir.
271// dir must be a valid VCS repo compatible with v.
272func (v *Cmd) Tags(dir string) ([]string, error) {
273 var tags []string
274 for _, tc := range v.TagCmd {
275 out, err := v.runOutput(dir, tc.Cmd)
276 if err != nil {
277 return nil, err
278 }
279 re := regexp.MustCompile(`(?m-s)` + tc.Pattern)
280 for _, m := range re.FindAllStringSubmatch(string(out), -1) {
281 tags = append(tags, m[1])
282 }
283 }
284 return tags, nil
285}
286
287// TagSync syncs the repo in dir to the named tag, which is either a
288// tag returned by Tags or the empty string (the default tag).
289// dir must be a valid VCS repo compatible with v and the tag must exist.
290func (v *Cmd) TagSync(dir, tag string) error {
291 if v.TagSyncCmd == "" {
292 return nil
293 }
294 if tag != "" {
295 for _, tc := range v.TagLookupCmd {
296 out, err := v.runOutput(dir, tc.Cmd, "tag", tag)
297 if err != nil {
298 return err
299 }
300 re := regexp.MustCompile(`(?m-s)` + tc.Pattern)
301 m := re.FindStringSubmatch(string(out))
302 if len(m) > 1 {
303 tag = m[1]
304 break
305 }
306 }
307 }
308 if tag == "" && v.TagSyncDefault != "" {
309 return v.run(dir, v.TagSyncDefault)
310 }
311 return v.run(dir, v.TagSyncCmd, "tag", tag)
312}
313
314// Log logs the changes for the repo in dir.
315// dir must be a valid VCS repo compatible with v.
316func (v *Cmd) Log(dir, logTemplate string) ([]byte, error) {
317 if err := v.Download(dir); err != nil {
318 return []byte{}, err
319 }
320
321 const N = 50 // how many revisions to grab
322 return v.runOutput(dir, v.LogCmd, "limit", strconv.Itoa(N), "template", logTemplate)
323}
324
325// LogAtRev logs the change for repo in dir at the rev revision.
326// dir must be a valid VCS repo compatible with v.
327// rev must be a valid revision for the repo in dir.
328func (v *Cmd) LogAtRev(dir, rev, logTemplate string) ([]byte, error) {
329 if err := v.Download(dir); err != nil {
330 return []byte{}, err
331 }
332
333 // Append revision flag to LogCmd.
334 logAtRevCmd := v.LogCmd + " --rev=" + rev
335 return v.runOutput(dir, logAtRevCmd, "limit", strconv.Itoa(1), "template", logTemplate)
336}
337
338// A vcsPath describes how to convert an import path into a
339// version control system and repository name.
340type vcsPath struct {
341 prefix string // prefix this description applies to
342 re string // pattern for import path
343 repo string // repository to use (expand with match of re)
344 vcs string // version control system to use (expand with match of re)
345 check func(match map[string]string) error // additional checks
346 ping bool // ping for scheme to use to download repo
347
348 regexp *regexp.Regexp // cached compiled form of re
349}
350
351// FromDir inspects dir and its parents to determine the
352// version control system and code repository to use.
353// On return, root is the import path
354// corresponding to the root of the repository.
355func FromDir(dir, srcRoot string) (vcs *Cmd, root string, err error) {
356 // Clean and double-check that dir is in (a subdirectory of) srcRoot.
357 dir = filepath.Clean(dir)
358 srcRoot = filepath.Clean(srcRoot)
359 if len(dir) <= len(srcRoot) || dir[len(srcRoot)] != filepath.Separator {
360 return nil, "", fmt.Errorf("directory %q is outside source root %q", dir, srcRoot)
361 }
362
363 var vcsRet *Cmd
364 var rootRet string
365
366 origDir := dir
367 for len(dir) > len(srcRoot) {
368 for _, vcs := range vcsList {
369 if _, err := os.Stat(filepath.Join(dir, "."+vcs.Cmd)); err == nil {
370 root := filepath.ToSlash(dir[len(srcRoot)+1:])
371 // Record first VCS we find, but keep looking,
372 // to detect mistakes like one kind of VCS inside another.
373 if vcsRet == nil {
374 vcsRet = vcs
375 rootRet = root
376 continue
377 }
378 // Allow .git inside .git, which can arise due to submodules.
379 if vcsRet == vcs && vcs.Cmd == "git" {
380 continue
381 }
382 // Otherwise, we have one VCS inside a different VCS.
383 return nil, "", fmt.Errorf("directory %q uses %s, but parent %q uses %s",
384 filepath.Join(srcRoot, rootRet), vcsRet.Cmd, filepath.Join(srcRoot, root), vcs.Cmd)
385 }
386 }
387
388 // Move to parent.
389 ndir := filepath.Dir(dir)
390 if len(ndir) >= len(dir) {
391 // Shouldn't happen, but just in case, stop.
392 break
393 }
394 dir = ndir
395 }
396
397 if vcsRet != nil {
398 return vcsRet, rootRet, nil
399 }
400
401 return nil, "", fmt.Errorf("directory %q is not using a known version control system", origDir)
402}
403
404// RepoRoot represents a version control system, a repo, and a root of
405// where to put it on disk.
406type RepoRoot struct {
407 VCS *Cmd
408
409 // Repo is the repository URL, including scheme.
410 Repo string
411
412 // Root is the import path corresponding to the root of the
413 // repository.
414 Root string
415}
416
417// RepoRootForImportPath analyzes importPath to determine the
418// version control system, and code repository to use.
419func RepoRootForImportPath(importPath string, verbose bool) (*RepoRoot, error) {
420 rr, err := RepoRootForImportPathStatic(importPath, "")
421 if err == errUnknownSite {
422 rr, err = RepoRootForImportDynamic(importPath, verbose)
423
424 // RepoRootForImportDynamic returns error detail
425 // that is irrelevant if the user didn't intend to use a
426 // dynamic import in the first place.
427 // Squelch it.
428 if err != nil {
429 if Verbose {
430 log.Printf("import %q: %v", importPath, err)
431 }
432 err = fmt.Errorf("unrecognized import path %q", importPath)
433 }
434 }
435
436 if err == nil && strings.Contains(importPath, "...") && strings.Contains(rr.Root, "...") {
437 // Do not allow wildcards in the repo root.
438 rr = nil
439 err = fmt.Errorf("cannot expand ... in %q", importPath)
440 }
441 return rr, err
442}
443
444var errUnknownSite = errors.New("dynamic lookup required to find mapping")
445
446// RepoRootForImportPathStatic attempts to map importPath to a
447// RepoRoot using the commonly-used VCS hosting sites in vcsPaths
448// (github.com/user/dir), or from a fully-qualified importPath already
449// containing its VCS type (foo.com/repo.git/dir)
450//
451// If scheme is non-empty, that scheme is forced.
452func RepoRootForImportPathStatic(importPath, scheme string) (*RepoRoot, error) {
453 if strings.Contains(importPath, "://") {
454 return nil, fmt.Errorf("invalid import path %q", importPath)
455 }
456 for _, srv := range vcsPaths {
457 if !strings.HasPrefix(importPath, srv.prefix) {
458 continue
459 }
460 m := srv.regexp.FindStringSubmatch(importPath)
461 if m == nil {
462 if srv.prefix != "" {
463 return nil, fmt.Errorf("invalid %s import path %q", srv.prefix, importPath)
464 }
465 continue
466 }
467
468 // Build map of named subexpression matches for expand.
469 match := map[string]string{
470 "prefix": srv.prefix,
471 "import": importPath,
472 }
473 for i, name := range srv.regexp.SubexpNames() {
474 if name != "" && match[name] == "" {
475 match[name] = m[i]
476 }
477 }
478 if srv.vcs != "" {
479 match["vcs"] = expand(match, srv.vcs)
480 }
481 if srv.repo != "" {
482 match["repo"] = expand(match, srv.repo)
483 }
484 if srv.check != nil {
485 if err := srv.check(match); err != nil {
486 return nil, err
487 }
488 }
489 vcs := ByCmd(match["vcs"])
490 if vcs == nil {
491 return nil, fmt.Errorf("unknown version control system %q", match["vcs"])
492 }
493 if srv.ping {
494 if scheme != "" {
495 match["repo"] = scheme + "://" + match["repo"]
496 } else {
497 for _, scheme := range vcs.Scheme {
498 if vcs.Ping(scheme, match["repo"]) == nil {
499 match["repo"] = scheme + "://" + match["repo"]
500 break
501 }
502 }
503 }
504 }
505 rr := &RepoRoot{
506 VCS: vcs,
507 Repo: match["repo"],
508 Root: match["root"],
509 }
510 return rr, nil
511 }
512 return nil, errUnknownSite
513}
514
515// RepoRootForImportDynamic finds a *RepoRoot for a custom domain that's not
516// statically known by RepoRootForImportPathStatic.
517//
518// This handles custom import paths like "name.tld/pkg/foo" or just "name.tld".
519func RepoRootForImportDynamic(importPath string, verbose bool) (*RepoRoot, error) {
520 slash := strings.Index(importPath, "/")
521 if slash < 0 {
522 slash = len(importPath)
523 }
524 host := importPath[:slash]
525 if !strings.Contains(host, ".") {
526 return nil, errors.New("import path doesn't contain a hostname")
527 }
528 urlStr, body, err := httpsOrHTTP(importPath)
529 if err != nil {
530 return nil, fmt.Errorf("http/https fetch: %v", err)
531 }
532 defer body.Close()
533 imports, err := parseMetaGoImports(body)
534 if err != nil {
535 return nil, fmt.Errorf("parsing %s: %v", importPath, err)
536 }
537 metaImport, err := matchGoImport(imports, importPath)
538 if err != nil {
539 if err != errNoMatch {
540 return nil, fmt.Errorf("parse %s: %v", urlStr, err)
541 }
542 return nil, fmt.Errorf("parse %s: no go-import meta tags", urlStr)
543 }
544 if verbose {
545 log.Printf("get %q: found meta tag %#v at %s", importPath, metaImport, urlStr)
546 }
547 // If the import was "uni.edu/bob/project", which said the
548 // prefix was "uni.edu" and the RepoRoot was "evilroot.com",
549 // make sure we don't trust Bob and check out evilroot.com to
550 // "uni.edu" yet (possibly overwriting/preempting another
551 // non-evil student). Instead, first verify the root and see
552 // if it matches Bob's claim.
553 if metaImport.Prefix != importPath {
554 if verbose {
555 log.Printf("get %q: verifying non-authoritative meta tag", importPath)
556 }
557 urlStr0 := urlStr
558 urlStr, body, err = httpsOrHTTP(metaImport.Prefix)
559 if err != nil {
560 return nil, fmt.Errorf("fetch %s: %v", urlStr, err)
561 }
562 imports, err := parseMetaGoImports(body)
563 if err != nil {
564 return nil, fmt.Errorf("parsing %s: %v", importPath, err)
565 }
566 if len(imports) == 0 {
567 return nil, fmt.Errorf("fetch %s: no go-import meta tag", urlStr)
568 }
569 metaImport2, err := matchGoImport(imports, importPath)
570 if err != nil || metaImport != metaImport2 {
571 return nil, fmt.Errorf("%s and %s disagree about go-import for %s", urlStr0, urlStr, metaImport.Prefix)
572 }
573 }
574
575 if err := validateRepoRoot(metaImport.RepoRoot); err != nil {
576 return nil, fmt.Errorf("%s: invalid repo root %q: %v", urlStr, metaImport.RepoRoot, err)
577 }
578 rr := &RepoRoot{
579 VCS: ByCmd(metaImport.VCS),
580 Repo: metaImport.RepoRoot,
581 Root: metaImport.Prefix,
582 }
583 if rr.VCS == nil {
584 return nil, fmt.Errorf("%s: unknown vcs %q", urlStr, metaImport.VCS)
585 }
586 return rr, nil
587}
588
589// validateRepoRoot returns an error if repoRoot does not seem to be
590// a valid URL with scheme.
591func validateRepoRoot(repoRoot string) error {
592 url, err := url.Parse(repoRoot)
593 if err != nil {
594 return err
595 }
596 if url.Scheme == "" {
597 return errors.New("no scheme")
598 }
599 return nil
600}
601
602// metaImport represents the parsed <meta name="go-import"
603// content="prefix vcs reporoot" /> tags from HTML files.
604type metaImport struct {
605 Prefix, VCS, RepoRoot string
606}
607
608// errNoMatch is returned from matchGoImport when there's no applicable match.
609var errNoMatch = errors.New("no import match")
610
611// pathPrefix reports whether sub is a prefix of s,
612// only considering entire path components.
613func pathPrefix(s, sub string) bool {
614 // strings.HasPrefix is necessary but not sufficient.
615 if !strings.HasPrefix(s, sub) {
616 return false
617 }
618 // The remainder after the prefix must either be empty or start with a slash.
619 rem := s[len(sub):]
620 return rem == "" || rem[0] == '/'
621}
622
623// matchGoImport returns the metaImport from imports matching importPath.
624// An error is returned if there are multiple matches.
625// errNoMatch is returned if none match.
626func matchGoImport(imports []metaImport, importPath string) (_ metaImport, err error) {
627 match := -1
628 for i, im := range imports {
629 if !pathPrefix(importPath, im.Prefix) {
630 continue
631 }
632
633 if match != -1 {
634 err = fmt.Errorf("multiple meta tags match import path %q", importPath)
635 return
636 }
637 match = i
638 }
639 if match == -1 {
640 err = errNoMatch
641 return
642 }
643 return imports[match], nil
644}
645
646// expand rewrites s to replace {k} with match[k] for each key k in match.
647func expand(match map[string]string, s string) string {
648 for k, v := range match {
649 s = strings.Replace(s, "{"+k+"}", v, -1)
650 }
651 return s
652}
653
654// vcsPaths lists the known vcs paths.
655var vcsPaths = []*vcsPath{
656 // Github
657 {
658 prefix: "github.com/",
659 re: `^(?P<root>github\.com/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(/[\p{L}0-9_.\-]+)*$`,
660 vcs: "git",
661 repo: "https://{root}",
662 check: noVCSSuffix,
663 },
664
665 // Bitbucket
666 {
667 prefix: "bitbucket.org/",
668 re: `^(?P<root>bitbucket\.org/(?P<bitname>[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`,
669 repo: "https://{root}",
670 check: bitbucketVCS,
671 },
672
673 // Launchpad
674 {
675 prefix: "launchpad.net/",
676 re: `^(?P<root>launchpad\.net/((?P<project>[A-Za-z0-9_.\-]+)(?P<series>/[A-Za-z0-9_.\-]+)?|~[A-Za-z0-9_.\-]+/(\+junk|[A-Za-z0-9_.\-]+)/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`,
677 vcs: "bzr",
678 repo: "https://{root}",
679 check: launchpadVCS,
680 },
681
682 // Git at OpenStack
683 {
684 prefix: "git.openstack.org",
685 re: `^(?P<root>git\.openstack\.org/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(\.git)?(/[A-Za-z0-9_.\-]+)*$`,
686 vcs: "git",
687 repo: "https://{root}",
688 check: noVCSSuffix,
689 },
690
691 // General syntax for any server.
692 {
693 re: `^(?P<root>(?P<repo>([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?/[A-Za-z0-9_.\-/]*?)\.(?P<vcs>bzr|git|hg|svn))(/[A-Za-z0-9_.\-]+)*$`,
694 ping: true,
695 },
696}
697
698func init() {
699 // fill in cached regexps.
700 // Doing this eagerly discovers invalid regexp syntax
701 // without having to run a command that needs that regexp.
702 for _, srv := range vcsPaths {
703 srv.regexp = regexp.MustCompile(srv.re)
704 }
705}
706
707// noVCSSuffix checks that the repository name does not
708// end in .foo for any version control system foo.
709// The usual culprit is ".git".
710func noVCSSuffix(match map[string]string) error {
711 repo := match["repo"]
712 for _, vcs := range vcsList {
713 if strings.HasSuffix(repo, "."+vcs.Cmd) {
714 return fmt.Errorf("invalid version control suffix in %s path", match["prefix"])
715 }
716 }
717 return nil
718}
719
720// bitbucketVCS determines the version control system for a
721// Bitbucket repository, by using the Bitbucket API.
722func bitbucketVCS(match map[string]string) error {
723 if err := noVCSSuffix(match); err != nil {
724 return err
725 }
726
727 var resp struct {
728 SCM string `json:"scm"`
729 }
730 url := expand(match, "https://api.bitbucket.org/2.0/repositories/{bitname}?fields=scm")
731 data, err := httpGET(url)
732 if err != nil {
733 return err
734 }
735 if err := json.Unmarshal(data, &resp); err != nil {
736 return fmt.Errorf("decoding %s: %v", url, err)
737 }
738
739 if ByCmd(resp.SCM) != nil {
740 match["vcs"] = resp.SCM
741 if resp.SCM == "git" {
742 match["repo"] += ".git"
743 }
744 return nil
745 }
746
747 return fmt.Errorf("unable to detect version control system for bitbucket.org/ path")
748}
749
750// launchpadVCS solves the ambiguity for "lp.net/project/foo". In this case,
751// "foo" could be a series name registered in Launchpad with its own branch,
752// and it could also be the name of a directory within the main project
753// branch one level up.
754func launchpadVCS(match map[string]string) error {
755 if match["project"] == "" || match["series"] == "" {
756 return nil
757 }
758 _, err := httpGET(expand(match, "https://code.launchpad.net/{project}{series}/.bzr/branch-format"))
759 if err != nil {
760 match["root"] = expand(match, "launchpad.net/{project}")
761 match["repo"] = expand(match, "https://{root}")
762 }
763 return nil
764}
diff --git a/debian/go/src/golang.org/x/tools/go/vcs/vcs_test.go b/debian/go/src/golang.org/x/tools/go/vcs/vcs_test.go
0new file mode 100644765new file mode 100644
index 0000000..a17b50d
--- /dev/null
+++ b/debian/go/src/golang.org/x/tools/go/vcs/vcs_test.go
@@ -0,0 +1,309 @@
1// Copyright 2013 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package vcs
6
7import (
8 "errors"
9 "io/ioutil"
10 "os"
11 "path"
12 "path/filepath"
13 "reflect"
14 "runtime"
15 "strings"
16 "testing"
17)
18
19// Test that RepoRootForImportPath creates the correct RepoRoot for a given importPath.
20// TODO(cmang): Add tests for SVN and BZR.
21func TestRepoRootForImportPath(t *testing.T) {
22 if runtime.GOOS == "android" {
23 t.Skipf("incomplete source tree on %s", runtime.GOOS)
24 }
25
26 tests := []struct {
27 path string
28 want *RepoRoot
29 }{
30 {
31 "github.com/golang/groupcache",
32 &RepoRoot{
33 VCS: vcsGit,
34 Repo: "https://github.com/golang/groupcache",
35 },
36 },
37 // Unicode letters in directories (issue 18660).
38 {
39 "github.com/user/unicode/испытание",
40 &RepoRoot{
41 VCS: vcsGit,
42 Repo: "https://github.com/user/unicode",
43 },
44 },
45 }
46
47 for _, test := range tests {
48 got, err := RepoRootForImportPath(test.path, false)
49 if err != nil {
50 t.Errorf("RepoRootForImportPath(%q): %v", test.path, err)
51 continue
52 }
53 want := test.want
54 if got.VCS.Name != want.VCS.Name || got.Repo != want.Repo {
55 t.Errorf("RepoRootForImportPath(%q) = VCS(%s) Repo(%s), want VCS(%s) Repo(%s)", test.path, got.VCS, got.Repo, want.VCS, want.Repo)
56 }
57 }
58}
59
60// Test that FromDir correctly inspects a given directory and returns the right VCS and root.
61func TestFromDir(t *testing.T) {
62 tempDir, err := ioutil.TempDir("", "vcstest")
63 if err != nil {
64 t.Fatal(err)
65 }
66 defer os.RemoveAll(tempDir)
67
68 for j, vcs := range vcsList {
69 dir := filepath.Join(tempDir, "example.com", vcs.Name, "."+vcs.Cmd)
70 if j&1 == 0 {
71 err := os.MkdirAll(dir, 0755)
72 if err != nil {
73 t.Fatal(err)
74 }
75 } else {
76 err := os.MkdirAll(filepath.Dir(dir), 0755)
77 if err != nil {
78 t.Fatal(err)
79 }
80 f, err := os.Create(dir)
81 if err != nil {
82 t.Fatal(err)
83 }
84 f.Close()
85 }
86
87 want := RepoRoot{
88 VCS: vcs,
89 Root: path.Join("example.com", vcs.Name),
90 }
91 var got RepoRoot
92 got.VCS, got.Root, err = FromDir(dir, tempDir)
93 if err != nil {
94 t.Errorf("FromDir(%q, %q): %v", dir, tempDir, err)
95 continue
96 }
97 if got.VCS.Name != want.VCS.Name || got.Root != want.Root {
98 t.Errorf("FromDir(%q, %q) = VCS(%s) Root(%s), want VCS(%s) Root(%s)", dir, tempDir, got.VCS, got.Root, want.VCS, want.Root)
99 }
100 }
101}
102
103var parseMetaGoImportsTests = []struct {
104 in string
105 out []metaImport
106}{
107 {
108 `<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">`,
109 []metaImport{{"foo/bar", "git", "https://github.com/rsc/foo/bar"}},
110 },
111 {
112 `<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">
113 <meta name="go-import" content="baz/quux git http://github.com/rsc/baz/quux">`,
114 []metaImport{
115 {"foo/bar", "git", "https://github.com/rsc/foo/bar"},
116 {"baz/quux", "git", "http://github.com/rsc/baz/quux"},
117 },
118 },
119 {
120 `<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">
121 <meta name="go-import" content="foo/bar mod http://github.com/rsc/baz/quux">`,
122 []metaImport{
123 {"foo/bar", "git", "https://github.com/rsc/foo/bar"},
124 },
125 },
126 {
127 `<meta name="go-import" content="foo/bar mod http://github.com/rsc/baz/quux">
128 <meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">`,
129 []metaImport{
130 {"foo/bar", "git", "https://github.com/rsc/foo/bar"},
131 },
132 },
133 {
134 `<head>
135 <meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">
136 </head>`,
137 []metaImport{{"foo/bar", "git", "https://github.com/rsc/foo/bar"}},
138 },
139 {
140 `<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">
141 <body>`,
142 []metaImport{{"foo/bar", "git", "https://github.com/rsc/foo/bar"}},
143 },
144 {
145 `<!doctype html><meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">`,
146 []metaImport{{"foo/bar", "git", "https://github.com/rsc/foo/bar"}},
147 },
148 {
149 // XML doesn't like <div style=position:relative>.
150 `<!doctype html><title>Page Not Found</title><meta name=go-import content="chitin.io/chitin git https://github.com/chitin-io/chitin"><div style=position:relative>DRAFT</div>`,
151 []metaImport{{"chitin.io/chitin", "git", "https://github.com/chitin-io/chitin"}},
152 },
153 {
154 `<meta name="go-import" content="myitcv.io git https://github.com/myitcv/x">
155 <meta name="go-import" content="myitcv.io/blah2 mod https://raw.githubusercontent.com/myitcv/pubx/master">
156 `,
157 []metaImport{{"myitcv.io", "git", "https://github.com/myitcv/x"}},
158 },
159}
160
161func TestParseMetaGoImports(t *testing.T) {
162 for i, tt := range parseMetaGoImportsTests {
163 out, err := parseMetaGoImports(strings.NewReader(tt.in))
164 if err != nil {
165 t.Errorf("test#%d: %v", i, err)
166 continue
167 }
168 if !reflect.DeepEqual(out, tt.out) {
169 t.Errorf("test#%d:\n\thave %q\n\twant %q", i, out, tt.out)
170 }
171 }
172}
173
174func TestValidateRepoRoot(t *testing.T) {
175 tests := []struct {
176 root string
177 ok bool
178 }{
179 {
180 root: "",
181 ok: false,
182 },
183 {
184 root: "http://",
185 ok: true,
186 },
187 {
188 root: "git+ssh://",
189 ok: true,
190 },
191 {
192 root: "http#://",
193 ok: false,
194 },
195 {
196 root: "-config",
197 ok: false,
198 },
199 {
200 root: "-config://",
201 ok: false,
202 },
203 }
204
205 for _, test := range tests {
206 err := validateRepoRoot(test.root)
207 ok := err == nil
208 if ok != test.ok {
209 want := "error"
210 if test.ok {
211 want = "nil"
212 }
213 t.Errorf("validateRepoRoot(%q) = %q, want %s", test.root, err, want)
214 }
215 }
216}
217
218func TestMatchGoImport(t *testing.T) {
219 tests := []struct {
220 imports []metaImport
221 path string
222 mi metaImport
223 err error
224 }{
225 {
226 imports: []metaImport{
227 {Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
228 },
229 path: "example.com/user/foo",
230 mi: metaImport{Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
231 },
232 {
233 imports: []metaImport{
234 {Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
235 },
236 path: "example.com/user/foo/",
237 mi: metaImport{Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
238 },
239 {
240 imports: []metaImport{
241 {Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
242 {Prefix: "example.com/user/fooa", VCS: "git", RepoRoot: "https://example.com/repo/target"},
243 },
244 path: "example.com/user/foo",
245 mi: metaImport{Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
246 },
247 {
248 imports: []metaImport{
249 {Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
250 {Prefix: "example.com/user/fooa", VCS: "git", RepoRoot: "https://example.com/repo/target"},
251 },
252 path: "example.com/user/fooa",
253 mi: metaImport{Prefix: "example.com/user/fooa", VCS: "git", RepoRoot: "https://example.com/repo/target"},
254 },
255 {
256 imports: []metaImport{
257 {Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
258 {Prefix: "example.com/user/foo/bar", VCS: "git", RepoRoot: "https://example.com/repo/target"},
259 },
260 path: "example.com/user/foo/bar",
261 err: errors.New("should not be allowed to create nested repo"),
262 },
263 {
264 imports: []metaImport{
265 {Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
266 {Prefix: "example.com/user/foo/bar", VCS: "git", RepoRoot: "https://example.com/repo/target"},
267 },
268 path: "example.com/user/foo/bar/baz",
269 err: errors.New("should not be allowed to create nested repo"),
270 },
271 {
272 imports: []metaImport{
273 {Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
274 {Prefix: "example.com/user/foo/bar", VCS: "git", RepoRoot: "https://example.com/repo/target"},
275 },
276 path: "example.com/user/foo/bar/baz/qux",
277 err: errors.New("should not be allowed to create nested repo"),
278 },
279 {
280 imports: []metaImport{
281 {Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
282 {Prefix: "example.com/user/foo/bar", VCS: "git", RepoRoot: "https://example.com/repo/target"},
283 },
284 path: "example.com/user/foo/bar/baz/",
285 err: errors.New("should not be allowed to create nested repo"),
286 },
287 {
288 imports: []metaImport{
289 {Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
290 {Prefix: "example.com/user/foo/bar", VCS: "git", RepoRoot: "https://example.com/repo/target"},
291 },
292 path: "example.com",
293 err: errors.New("pathologically short path"),
294 },
295 }
296
297 for _, test := range tests {
298 mi, err := matchGoImport(test.imports, test.path)
299 if mi != test.mi {
300 t.Errorf("unexpected metaImport; got %v, want %v", mi, test.mi)
301 }
302
303 got := err
304 want := test.err
305 if (got == nil) != (want == nil) {
306 t.Errorf("unexpected error; got %v, want %v", got, want)
307 }
308 }
309}
diff --git a/debian/patches/01-Update-the-import-path-of-golang-github-google-go-github.patch b/debian/patches/01-Update-the-import-path-of-golang-github-google-go-github.patch
0deleted file mode 100644310deleted file mode 100644
index 8d3467b..0000000
--- a/debian/patches/01-Update-the-import-path-of-golang-github-google-go-github.patch
+++ /dev/null
@@ -1,34 +0,0 @@
1From: Roger Shimizu <rosh@debian.org>
2Date: Fri, 17 Jul 2020 22:55:35 +0900
3Subject: Update the import path of golang-github-google-go-github
4
5---
6 main.go | 2 +-
7 1 file changed, 1 insertion(+), 1 deletion(-)
8
9Index: dh-make-golang/main.go
10===================================================================
11--- dh-make-golang.orig/main.go 2022-11-18 12:45:52.035957432 +0100
12+++ dh-make-golang/main.go 2022-11-18 12:45:52.035957432 +0100
13@@ -4,7 +4,7 @@
14 "fmt"
15 "os"
16
17- "github.com/google/go-github/v38/github"
18+ "github.com/google/go-github/github"
19 "github.com/gregjones/httpcache"
20 )
21
22Index: dh-make-golang/go.mod
23===================================================================
24--- dh-make-golang.orig/go.mod 2022-11-18 12:43:54.600226791 +0100
25+++ dh-make-golang/go.mod 2022-11-18 12:46:09.780533980 +0100
26@@ -4,7 +4,7 @@
27
28 require (
29 github.com/charmbracelet/glamour v0.3.0
30- github.com/google/go-github/v38 v38.1.0
31+ github.com/google/go-github v38.1.0
32 github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79
33 github.com/mattn/go-isatty v0.0.12
34 golang.org/x/mod v0.5.1 // indirect
diff --git a/debian/patches/series b/debian/patches/series
35deleted file mode 1006440deleted file mode 100644
index c2ce9b0..0000000
--- a/debian/patches/series
+++ /dev/null
@@ -1 +0,0 @@
101-Update-the-import-path-of-golang-github-google-go-github.patch
diff --git a/debian/rules b/debian/rules
index 71be22f..c93b44f 100755
--- a/debian/rules
+++ b/debian/rules
@@ -1,10 +1,19 @@
1#!/usr/bin/make -f1#!/usr/bin/make -f
22
3export DEB_BUILD_MAINT_OPTIONS = optimize=-lto
3export DH_GOLANG_INSTALL_EXTRA := description.json4export DH_GOLANG_INSTALL_EXTRA := description.json
45
5%:6%:
6 dh $@ --builddirectory=_build --buildsystem=golang --with=golang7 dh $@ --builddirectory=_build --buildsystem=golang --with=golang
78
9execute_after_dh_auto_configure:
10 # golang.org/x/tools/go/vcs v0.1.0-deprecated
11 ln -s $(CURDIR)/debian/go/src \
12 _build/src/github.com/Debian/dh-make-golang/vendor
13 # github.com/google/go-github/github (with Go modules disabled)
14 sed -i -e 's#go-github/v[0-9]\+/github#go-github/github#' \
15 _build/src/github.com/Debian/dh-make-golang/main.go
16
8override_dh_auto_install:17override_dh_auto_install:
9 dh_auto_install -- --no-source18 dh_auto_install -- --no-source
1019

Subscribers

People subscribed via source and target branches