Skip to content
This repository was archived by the owner on Apr 14, 2021. It is now read-only.

Commit 0e21d6d

Browse files
authored
Merge pull request #143 from bpicode/Issue-124-deb-copyright
Write debian copyright file by parsing NOTICE and vendor tree
2 parents 34dc85a + e80fe79 commit 0e21d6d

17 files changed

Lines changed: 554 additions & 6 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*.out
66
coverage-all.html
77
/fritzctl
8+
/notice2copyright
89

910
# Folders
1011
_obj

Makefile

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ FRITZCTL_OUTPUT ?= fritzctl
66
FRITZCTL_REVISION := $(shell git rev-parse HEAD)
77
BASH_COMPLETION_OUTPUT ?= "os/completion/fritzctl"
88
MAN_PAGE_OUTPUT ?= "os/man/fritzctl.1"
9+
COPYRIGHT_OUTPUT ?= "os/doc/copyright"
910
DEPENDENCIES_GRAPH_OUTPUT ?= "dependencies.png"
1011
BUILDFLAGS := -ldflags="-s -w -X github.com/bpicode/fritzctl/config.Version=$(FRITZCTL_VERSION) -X github.com/bpicode/fritzctl/config.Revision=$(FRITZCTL_REVISION)" -gcflags="-trimpath=$(GOPATH)" -asmflags="-trimpath=$(GOPATH)"
1112
TESTFLAGS ?=
1213

13-
all: sysinfo build install test codequality completion_bash man
14+
all: sysinfo build install test codequality completion_bash man copyright
1415

15-
.PHONY: clean build man
16+
.PHONY: clean build man copyright
1617

1718
define ok
1819
@tput setaf 6 2>/dev/null || echo -n ""
@@ -36,6 +37,7 @@ clean:
3637
@go clean -i
3738
@rm -f ./os/completion/fritzctl
3839
@rm -f ./os/man/*.gz
40+
@rm -f ./os/doc/copyright
3941
@rm -f ./coverage-all.html
4042
@rm -f ./coverage-all.out
4143
@rm -f ./coverage.out
@@ -96,6 +98,12 @@ man:
9698
@gzip --force $(MAN_PAGE_OUTPUT)
9799
@$(call ok)
98100

101+
copyright:
102+
@echo -n ">> COPYRIGHT, output = $(COPYRIGHT_OUTPUT)"
103+
@go build github.com/bpicode/fritzctl/tools/notice2copyright
104+
@./notice2copyright ./ "MIT License (Expat)"> $(COPYRIGHT_OUTPUT)
105+
@$(call ok)
106+
99107
codequality:
100108
@echo ">> CODE QUALITY"
101109
@echo -n " FMT"
@@ -179,15 +187,17 @@ pkg_darwin: dist_darwin
179187
@zip -q build/distributions/fritzctl-$(FRITZCTL_VERSION)-darwin-amd64.zip build/distributions/darwin_amd64/fritzctl
180188
@$(call ok)
181189

182-
pkg_linux: dist_linux man completion_bash
190+
pkg_linux: dist_linux man completion_bash copyright
183191
@mkdir -p build/distributions/linux_amd64/usr/bin
184192
@mkdir -p build/distributions/linux_amd64/etc/fritzctl
185193
@mkdir -p build/distributions/linux_amd64/etc/bash_completion.d
186194
@mkdir -p build/distributions/linux_amd64/usr/share/man/man1
195+
@mkdir -p build/distributions/linux_amd64/usr/share/doc/fritzctl
187196
@cp os/completion/fritzctl build/distributions/linux_amd64/etc/bash_completion.d/
188197
@cp os/config/fritzctl.json build/distributions/linux_amd64/etc/fritzctl/
189198
@cp os/config/fritz.pem build/distributions/linux_amd64/etc/fritzctl/
190199
@cp os/man/*.1.gz build/distributions/linux_amd64/usr/share/man/man1/
200+
@cp os/doc/copyright build/distributions/linux_amd64/usr/share/doc/fritzctl/
191201

192202
@echo ">> PACKAGE, linux/amd64/deb"
193203
@echo -n " "
@@ -200,10 +210,12 @@ pkg_linux: dist_linux man completion_bash
200210
@mkdir -p build/distributions/linux_arm/etc/fritzctl
201211
@mkdir -p build/distributions/linux_arm/etc/bash_completion.d
202212
@mkdir -p build/distributions/linux_arm/usr/share/man/man1
213+
@mkdir -p build/distributions/linux_arm/usr/share/doc/fritzctl
203214
@cp os/completion/fritzctl build/distributions/linux_arm/etc/bash_completion.d/
204215
@cp os/config/fritzctl.json build/distributions/linux_arm/etc/fritzctl/
205216
@cp os/config/fritz.pem build/distributions/linux_arm/etc/fritzctl/
206217
@cp os/man/*.1.gz build/distributions/linux_arm/usr/share/man/man1/
218+
@cp os/doc/copyright build/distributions/linux_arm/usr/share/doc/fritzctl/
207219

208220
@echo ">> PACKAGE, linux/armhf/deb"
209221
@echo -n " "

NOTICE

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ The following software have components provided under the terms of this license:
1010

1111
- cobra (from https://github.com/spf13/cobra)
1212
- mousetrap (from https://github.com/inconshreveable/mousetrap)
13-
- yaml (from https://github.com/go-yaml/yaml)
13+
- yaml (from https://gopkg.in/yaml.v2)
1414

1515
========================================================================
1616
MIT License (Expat)
@@ -38,11 +38,11 @@ BSD 3-Clause License (Revised)
3838

3939
The following software have components provided under the terms of this license:
4040

41-
- crypto (from https://github.com/golang/crypto)
41+
- crypto (from https://golang.org/x/crypto)
4242
- httprouter (from https://github.com/julienschmidt/httprouter)
4343
- go-difflib (from https://github.com/pmezard/go-difflib)
4444
- pflag (from https://github.com/spf13/pflag)
45-
- sys (from https://github.com/golang/sys)
45+
- sys (from https://golang.org/x/sys)
4646

4747
========================================================================
4848
BSD 2-Clause License (FreeBSD/Simplified)

os/doc/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
copyright

tools/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Tools of our trade

tools/notice2copyright/README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# notice2copyright
2+
3+
## About
4+
5+
Parse a `NOTICE` file to generate the [debian copyright file](https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/).
6+
7+
## Build
8+
9+
```sh
10+
go build
11+
```
12+
13+
## Usage
14+
15+
```sh
16+
notice2copyright path/to/github.com/user/project "MIT License (Expat)"
17+
```
18+
19+
## Assumptions
20+
21+
* Every dependency is licensed under one license known to this tool.
22+
* The project has a `NOTICE` file in the following format:
23+
```text
24+
...
25+
26+
========================================================================
27+
Apache License 2.0 (Apache-2.0)
28+
========================================================================
29+
30+
The following software have components provided under the terms of this license:
31+
32+
- cobra (from https://github.com/spf13/cobra)
33+
34+
========================================================================
35+
MIT License (Expat)
36+
========================================================================
37+
38+
The following software have components provided under the terms of this license:
39+
40+
- color (from https://github.com/fatih/color)
41+
42+
...
43+
```
44+
The file needs to reside at the top-level directory of the project.
45+
* Vendoring. All dependencies need to be in the vendor folder including their `LICENSE` files.
46+
A dependency referenced via `- cobra (from https://github.com/spf13/cobra)` in the `NOTICE`
47+
file has to be present in the vendor folder as `vendor/github.com/spf13/cobra)`.

tools/notice2copyright/assert.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"log"
6+
)
7+
8+
func assertOrFatal(val bool, f string, v ...interface{}) {
9+
assertTrue(log.Fatalln, val, fmt.Sprintf(f, v...))
10+
}
11+
12+
func assertTrue(fat func(v ...interface{}), val bool, f string) {
13+
if !val {
14+
fat(f)
15+
}
16+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package main
2+
3+
import (
4+
"log"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func Test_assertTrue(t *testing.T) {
11+
assert.NotPanics(t, func() {
12+
assertTrue(log.Fatalln, true, "err")
13+
})
14+
assert.Panics(t, func() {
15+
assertTrue(func(v ...interface{}) {
16+
panic("panic")
17+
}, false, "err")
18+
})
19+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"fmt"
6+
"io"
7+
"os"
8+
"path/filepath"
9+
"regexp"
10+
"strings"
11+
)
12+
13+
var copyrightRegex = regexp.MustCompile(`^>*\s*[Cc]opyright\s(\([Cc]\)|©)*(?P<CLINE>.*)`)
14+
15+
var copyrightNoAuthorRegex = regexp.MustCompile(`([Cc]opyright notice|[Cc]opyright license to reproduce)`)
16+
17+
func findCopyrightHolders(projects []project, dir string) []project {
18+
withCpHolders := make([]project, len(projects))
19+
for i, p := range projects {
20+
withCpHolders[i] = findCopyrightHoldersOf(p, dir)
21+
}
22+
return withCpHolders
23+
}
24+
25+
func findCopyrightHoldersOf(p project, dir string) project {
26+
srcDir := filepath.Join(dir, p.dir())
27+
lf, err := openFirst(srcDir, "LICENSE", "LICENSE.md", "LICENSE.txt", "LICENSE.rst")
28+
assertOrFatal(err == nil, "unable to open license file for project '%s' (%s): %v", p.name, p.url, err)
29+
defer lf.Close()
30+
p.copyrightHolders = readCopyrightHolders(lf)
31+
return p
32+
}
33+
34+
func openFirst(dir string, names ...string) (*os.File, error) {
35+
for _, name := range names {
36+
f, err := os.Open(filepath.Join(dir, name))
37+
if err == nil {
38+
return f, nil
39+
}
40+
}
41+
return nil, fmt.Errorf("no license file [%s] found in directory '%s'", names, dir)
42+
}
43+
44+
func readCopyrightHolders(r io.Reader) []string {
45+
var holders []string
46+
s := bufio.NewScanner(r)
47+
for s.Scan() {
48+
line := s.Text()
49+
holders = addCopyRightHolder(line, holders)
50+
}
51+
if len(holders) == 0 {
52+
holders = append(holders, "unknown")
53+
}
54+
return holders
55+
}
56+
57+
func addCopyRightHolder(text string, holders []string) []string {
58+
if copyrightRegex.MatchString(text) && !copyrightNoAuthorRegex.MatchString(text) {
59+
holders = append(holders, parseCopyrightHolder(text))
60+
}
61+
return holders
62+
}
63+
64+
func parseCopyrightHolder(text string) string {
65+
matches := copyrightRegex.FindStringSubmatch(text)
66+
return strings.TrimSpace(matches[len(matches)-1])
67+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func Test_openFirst(t *testing.T) {
10+
_, err := openFirst("/that/should/not/work/ever", "asdfagag.txt", "asasgdsg.md")
11+
assert.Error(t, err)
12+
}
13+
14+
func Test_parseCopyrightHolder(t *testing.T) {
15+
assert.Equal(t, "2016 bpicode", parseCopyrightHolder("Copyright (c) 2016 bpicode"))
16+
assert.Equal(t, "John Doe <john.d@example.com>", parseCopyrightHolder("Copyright (c) John Doe <john.d@example.com>"))
17+
assert.Equal(t, "2009 The Go Authors. All rights reserved.", parseCopyrightHolder("Copyright (c) 2009 The Go Authors. All rights reserved."))
18+
assert.Equal(t, "2011 John Doe <john.d@example.com>", parseCopyrightHolder("Copyright © 2011 John Doe <john.d@example.com>"))
19+
}

0 commit comments

Comments
 (0)