licensed 3.0.0 → 3.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +19 -0
  3. data/.github/workflows/release.yml +4 -4
  4. data/.github/workflows/test.yml +180 -47
  5. data/.ruby-version +1 -1
  6. data/CHANGELOG.md +60 -1
  7. data/README.md +25 -79
  8. data/docker/Dockerfile.build-linux +1 -1
  9. data/docs/adding_a_new_source.md +11 -8
  10. data/docs/commands/README.md +59 -0
  11. data/docs/commands/cache.md +35 -0
  12. data/docs/commands/env.md +10 -0
  13. data/docs/commands/list.md +23 -0
  14. data/docs/commands/migrate.md +10 -0
  15. data/docs/commands/notices.md +12 -0
  16. data/docs/commands/status.md +74 -0
  17. data/docs/commands/version.md +3 -0
  18. data/docs/configuration/README.md +11 -0
  19. data/docs/configuration/allowed_licenses.md +17 -0
  20. data/docs/configuration/application_name.md +63 -0
  21. data/docs/configuration/application_source.md +64 -0
  22. data/docs/configuration/configuration_root.md +27 -0
  23. data/docs/configuration/configuring_multiple_apps.md +58 -0
  24. data/docs/configuration/dependency_source_enumerators.md +28 -0
  25. data/docs/configuration/ignoring_dependencies.md +19 -0
  26. data/docs/configuration/metadata_cache.md +106 -0
  27. data/docs/configuration/reviewing_dependencies.md +18 -0
  28. data/docs/configuration.md +9 -161
  29. data/docs/sources/swift.md +4 -0
  30. data/lib/licensed/cli.rb +2 -2
  31. data/lib/licensed/commands/cache.rb +19 -20
  32. data/lib/licensed/commands/command.rb +104 -72
  33. data/lib/licensed/commands/environment.rb +12 -11
  34. data/lib/licensed/commands/list.rb +0 -19
  35. data/lib/licensed/commands/notices.rb +0 -19
  36. data/lib/licensed/commands/status.rb +13 -15
  37. data/lib/licensed/configuration.rb +105 -12
  38. data/lib/licensed/report.rb +44 -0
  39. data/lib/licensed/reporters/cache_reporter.rb +48 -64
  40. data/lib/licensed/reporters/json_reporter.rb +19 -21
  41. data/lib/licensed/reporters/list_reporter.rb +45 -58
  42. data/lib/licensed/reporters/notices_reporter.rb +33 -46
  43. data/lib/licensed/reporters/reporter.rb +37 -104
  44. data/lib/licensed/reporters/status_reporter.rb +58 -56
  45. data/lib/licensed/reporters/yaml_reporter.rb +19 -21
  46. data/lib/licensed/sources/bundler/definition.rb +36 -0
  47. data/lib/licensed/sources/bundler/missing_specification.rb +1 -1
  48. data/lib/licensed/sources/bundler.rb +38 -86
  49. data/lib/licensed/sources/dep.rb +2 -2
  50. data/lib/licensed/sources/go.rb +3 -3
  51. data/lib/licensed/sources/gradle.rb +2 -2
  52. data/lib/licensed/sources/helpers/content_versioning.rb +2 -1
  53. data/lib/licensed/sources/npm.rb +4 -3
  54. data/lib/licensed/sources/nuget.rb +56 -27
  55. data/lib/licensed/sources/swift.rb +69 -0
  56. data/lib/licensed/sources.rb +1 -0
  57. data/lib/licensed/version.rb +1 -1
  58. data/lib/licensed.rb +1 -0
  59. data/licensed.gemspec +4 -4
  60. data/script/source-setup/go +1 -1
  61. data/script/source-setup/swift +22 -0
  62. metadata +48 -13
  63. data/docs/commands.md +0 -95
@@ -0,0 +1,74 @@
1
+ # `licensed status`
2
+
3
+ The status command finds all dependencies and checks whether each dependency has a valid cached record.
4
+
5
+ A dependency will fail the status checks if:
6
+
7
+ 1. No cached record is found
8
+ 2. The cached record's version is different than the current dependency's version
9
+ 3. The cached record's `licenses` data is empty
10
+ 4. The cached record's `license` metadata doesn't match an `allowed` license from the dependency's application configuration.
11
+ - If `license: other` is specified and all of the `licenses` entries match an `allowed` license a failure will not be logged
12
+ 5. The cached record is flagged for re-review.
13
+ - This occurs when the record's license text has changed since the record was reviewed.
14
+
15
+ ## Options
16
+
17
+ - `--config`/`-c`: the path to the licensed configuration file
18
+ - default value: `./.licensed.yml`
19
+ - `--sources`/`-s`: runtime filter on which dependency sources are run. Sources must also be enabled in the licensed configuration file.
20
+ - default value: not set, all configured sources
21
+ - `--format`/`-f`: the output format
22
+ - default value: `yaml`
23
+ - `--force`: if set, forces all dependency metadata files to be recached
24
+ - default value: not set
25
+
26
+ ## Reported Data
27
+
28
+ The following data is reported for each dependency when the YAML or JSON report formats are used
29
+
30
+ - name: the licensed recognized name for the dependency including the app and source name
31
+ - e.g. the full name for the `thor` bundler dependency used by this tool is `licensed.bundler.thor`
32
+ - allowed: true if the dependency has passed all checks, false otherwise
33
+ - version: the version of the enumerated dependency
34
+ - license: the dependency's SPDX license identifier
35
+ - filename: the full path on disk to the dependency's cached metadata file, if available
36
+ - errors: any error messages from failed status checks, if available
37
+
38
+ ## Status errors and resolutions
39
+
40
+ ### cached dependency record not found
41
+
42
+ **Cause:** A dependency was found while running `licensed status` that does not have a corresponding cached metadata file
43
+ **Resolution:** Run `licensed cache` to update the metadata cache and create the missing metadata file
44
+
45
+ ### cached dependency record out of date
46
+
47
+ **Cause:** A dependency was found while running `licensed status` with a different version than is contained in the dependency's cached metadata file
48
+ **Resolution:** Run `licensed cache` to update the out-of-date metadata files
49
+
50
+ ### missing license text
51
+
52
+ **Cause:** A license determination was made, e.g. from package metadata, but no license text was found.
53
+ **Resolution:** Manually verify whether the dependency includes a file containing license text. If the dependency code that was downloaded locally does not contain the license text, please check the dependency source at the version listed in the dependency's cached metadata file to see if there is license text that can be used.
54
+
55
+ If the dependency does not include license text but does specify that it uses a specific license, please copy the standard license text from a [well known source](https://opensource.org/licenses).
56
+
57
+ ### license text has changed and needs re-review. if the new text is ok, remove the `review_changed_license` flag from the cached record
58
+
59
+ **Cause:** A dependency that is set as [reviewed] in the licensed configuration file has substantially changed and should be re-reviewed.
60
+ **Resolution:** Review the changes to the license text and classification, along with other metadata contained in the cached file for the dependency. If the dependency is still allowable for use in your project, remove the `review_changed_license` key from the cached record file.
61
+
62
+ ### license needs review
63
+
64
+ **Cause:** A dependency is using a license that is not in the configured [allowed list of licenses][allowed], and the dependency has not been marked [ignored] or [reviewed].
65
+ **Resolution:** Review the dependency's usage and specified license with someone familiar with OSS licensing and compliance rules to determine whether the dependency is allowable. Some common resolutions:
66
+
67
+ 1. The dependency's specified license text differed enough from the standard license text that it was not recognized and classified as `other`. If, with human review, the license text is recognizable then update the `license: other` value in the cached metadata file to the correct license.
68
+ - An updated classification will persist through version upgrades until the detected license contents have changed. The determination is made by [licensee/licensee](https://github.com/licensee/licensee), the library which this tool uses to detect and classify license contents.
69
+ 1. The dependency might need to be marked as [ignored] or [reviewed] if either of those scenarios are applicable.
70
+ 1. If the used license should be allowable without review (if your entity has a legal team, they may want to review this assessment), ensure the license SPDX is set as [allowed] in the licensed configuration file.
71
+
72
+ [allowed]: ../configuration/allowed_licenses.md
73
+ [ignored]: ../configuration/ignoring_dependencies.md
74
+ [reviewed]: ../configuration/reviewing_dependencies.md
@@ -0,0 +1,3 @@
1
+ # `licensed version`
2
+
3
+ Displays the current licensed version. Can also be run with `licensed -v` and `licensed --version`.
@@ -0,0 +1,11 @@
1
+ # Configuration options
2
+
3
+ 1. [Application source path](./application_source.md)
4
+ 1. [Dependency metadata cache](./metadata_cache.md)
5
+ 1. [Configuring multiple applications / monorepo support](./configuring_multiple_apps.md)
6
+ 1. [Configuration root](./configuration_root.md)
7
+ 1. [Application name](./application_name.md)
8
+ 1. [Dependency source enumerators](./dependency_source_enumerators.md)
9
+ 1. [Allowed licenses](./allowed_licenses.md)
10
+ 1. [Ignoring dependencies](./ignoring_dependencies.md)
11
+ 1. [Reviewing dependencies](./reviewing_dependencies.md)
@@ -0,0 +1,17 @@
1
+ # Allowed licenses
2
+
3
+ **Key**: allowed
4
+ **Default Value**: none
5
+
6
+ The list of allowed licenses is used with the [status command](../commands/status.md) to detail which licenses are allowable for use in the current project and do not need further review. If a dependency uses a license that is not included in the allowed list, and the dependency is not on the ignored or reviewed dependency lists, it will be flagged and the status command will fail.
7
+
8
+ This configuration value accepts an array of lower-cased [open source license SPDX identifiers](https://spdx.org/licenses/).
9
+
10
+ ```yml
11
+ # accepts lowercase SPDX license identifiers
12
+ allowed:
13
+ - mit
14
+ - bsd-2-clause
15
+ - bsd-3-clause
16
+ - isc
17
+ ```
@@ -0,0 +1,63 @@
1
+ # Application name
2
+
3
+ **Key**: name
4
+ **Default value**: The directory name of the application's source path
5
+
6
+ The name of the application is primarily used for organizational and display purposes. Application names are not included with
7
+ dependency metadata information included in cached files.
8
+
9
+ ```yml
10
+ source_path: path/to/application1
11
+ name: application1
12
+ ```
13
+
14
+ ## Dynamically generated application names
15
+
16
+ ### Source path directory name
17
+
18
+ When not specified, an application's name will be the directory name from the application's source path.
19
+
20
+ ```yml
21
+ # if not explicitly set the name will be inferred from the source path
22
+ source_path: path/to/application1
23
+ # name: application1
24
+
25
+ # or, use the `directory_name` name generator to explicitly set this behavior
26
+ source_path: path/to/application1
27
+ name:
28
+ generator: directory_name
29
+ # name: application1
30
+ ```
31
+
32
+ ### Relative path from configuration root
33
+
34
+ Application names can be created from the path from the configuration root to the application source path.
35
+ This can be useful when specifying multiple applications using a glob pattern in a directory structure where directory names
36
+ are not unique.
37
+
38
+ As an example, given the following directory structure and configuration YML, the resulting application names
39
+ would be `linux.installer`, `windows.installer` and `mac.installer`. The optional arguments `separator` and `depth` are used
40
+ to better control the resulting application name.
41
+
42
+ ```text
43
+ path
44
+ |_to
45
+ |_linux
46
+ |_installer
47
+ |_windows
48
+ |_installer
49
+ |_mac
50
+ |_installer
51
+ ```
52
+
53
+ ```yml
54
+ source_path: '**/installer'
55
+ name:
56
+ generator: relative_path
57
+ # separator controls what character separates path parts in the application name
58
+ # default: "-"
59
+ separator: '.'
60
+ # depth controls how many of the path parts are used in the application name
61
+ # default: 0 / all path parts
62
+ depth: 2
63
+ ```
@@ -0,0 +1,64 @@
1
+ # Application source path
2
+
3
+ **Key**: source_path
4
+ **Default value**:
5
+
6
+ - if the `apps` key is not present, then the current working directory where `licensed` was executed
7
+ - if the `apps` key is present, then `nil`
8
+
9
+ The source path is the directory in which licensed should run to enumerate dependencies. This is often dependent
10
+ on the project type, for example the bundler source should be run from the directory containing a `Gemfile` or `gems.rb`
11
+ while the go source should be run from the directory containing an entrypoint function.
12
+
13
+ The source path is required to run `licensed`. A default value is available only when the configuration file specifies a single application.
14
+ When multiple applications are configured, each application must specify a source path.
15
+
16
+ Paths can be given as absolute or relative paths, and can use special path identifiers. If a relative path is given, it will be based on the application's root path.
17
+
18
+ ```yml
19
+ # when apps is not set, a source path does not need to be specified. it will default to the users current directory
20
+ sources:
21
+ bundler: true
22
+
23
+ # ------
24
+ # or a path can be given as either an absolute or relative path
25
+ sources:
26
+ bundler: true
27
+ source_path: path/to/application1
28
+
29
+ # ------
30
+ # when apps is set, each application must specify a source_path
31
+ sources:
32
+ bundler: true
33
+ apps:
34
+ - source_path: relative/path/to/application1
35
+ - source_path: /absolute/path/to/application2
36
+ - source_path: ~/path/from/home/to/application3
37
+ ```
38
+
39
+ ## Expanding source paths with glob patterns
40
+
41
+ The `source_path` property can use one or more glob patterns to share configuration properties across multiple application entrypoints.
42
+
43
+ For example, there is a common pattern in Go projects to include multiple executable entrypoints under folders in `cmd`. Using a glob pattern allows users to avoid manually configuring and maintaining multiple licensed application `source_path`s. Using a glob pattern will also ensure that any new entrypoints matching the pattern are automatically picked up by licensed commands as they are added.
44
+
45
+ ```yml
46
+ sources:
47
+ go: true
48
+
49
+ # treat all directories under `cmd` as separate apps
50
+ source_path: cmd/*
51
+ ```
52
+
53
+ In order to better filter the results from glob patterns, the `source_path` property also accepts an array of
54
+ inclusion and exclusion glob patterns similar to gitignore files. Inclusion patterns will add matching directory
55
+ paths to resulting set of source paths, while exclusion patterns will remove matching directory paths.
56
+
57
+ ```yml
58
+ source_path:
59
+ - "projects/*" # include by default all directories under "projects"
60
+ - "!projects/*Test" # exclude all projects ending in "Test"
61
+ ```
62
+
63
+ Glob patterns are syntactic sugar for, and provide the same functionality as, manually specifying multiple `source_path` values.
64
+ See the instructions on [specifying multiple apps](../configuration.md#specifying-multiple-apps) below for additional considerations when using multiple apps.
@@ -0,0 +1,27 @@
1
+ # Configuration root
2
+
3
+ **Key**: root
4
+ **Default value**:
5
+
6
+ 1. the root of the local git repository, if run inside a git repository
7
+ 1. the directory that `licensed` is run from
8
+
9
+ An application's root path is used as the base for any relative configuration paths in the application.
10
+
11
+ From a configuration file, the root value can be specified as one of the following. Path string values can contain special path characters.
12
+
13
+ - a relative path from the configuration file location
14
+ - an absolute path
15
+ - `true` to use the configuration file's directory as the root
16
+
17
+ When creating a `Licensed::AppConfiguration` manually with a `root` property, the property must be an absolute path - no path expansion will occur.
18
+
19
+ ```yml
20
+ root: path/from/configuration
21
+ # or
22
+ root: /absolute/path/to/root
23
+ # or
24
+ root: ~/path/from/home/to/root
25
+ # or
26
+ root: true
27
+ ```
@@ -0,0 +1,58 @@
1
+ # Configuring multiple application definitions
2
+
3
+ **Key**: apps
4
+ **Required**: false
5
+
6
+ The configuration file can specify multiple source paths to enumerate metadata, each with their own configuration by using the `apps` key.
7
+ Each source path and any additional configuration make up an "application". Root configuration settings are inherited into each application,
8
+ allowing applications to share a common configuration and reducing the overall size of the configuration file.
9
+
10
+ When the apps key is not given, the root configuration is treated as a single application.
11
+
12
+ ```yml
13
+ apps:
14
+ # application definition for "go-application"
15
+ - source_path: path/to/go-application
16
+ sources:
17
+ go: true
18
+ allowed:
19
+ - mit
20
+
21
+ # application definition for "ruby-application"
22
+ - source_path: path/to/ruby-application
23
+ sources:
24
+ bundler: true
25
+ allowed:
26
+ - bsd-3-clause
27
+ ```
28
+
29
+ ## Inheriting configuration
30
+
31
+ Applications inherit all root configuration settings. Inherited settings will be overridden by any configuration set directly on the application definition.
32
+
33
+ In this example, two apps have been declared. The first app, with `source_path: path/to/application1`, inherits all configuration settings from the root configuration. The second app, with `source_path: path/to/application2`, overrides the `sources` configuration and inherits all other settings.
34
+
35
+ ```yml
36
+ sources:
37
+ go: true
38
+ bundler: false
39
+
40
+ ignored:
41
+ bundler:
42
+ - some-internal-gem
43
+
44
+ reviewed:
45
+ bundler:
46
+ - bcrypt-ruby
47
+
48
+ cache_path: 'path/to/cache'
49
+ apps:
50
+ # inherits all settings from the root configuration
51
+ - source_path: 'path/to/application1'
52
+
53
+ # inherits all settings except for "sources" from the root configuration
54
+ - source_path: 'path/to/application2'
55
+ sources:
56
+ bundler: true
57
+ go: false
58
+ ```
@@ -0,0 +1,28 @@
1
+ # Specifying dependency sources to use in an application
2
+
3
+ **Key**: sources
4
+ **Required**: false
5
+ **Default value**: All sources enabled
6
+
7
+ The sources configuration property specifies which sources `licensed` will use to enumerate dependencies.
8
+ By default, `licensed` will try to enumerate dependencies from all sources. As a result,
9
+ the configuration property should be used to explicitly disable sources rather than to enable a particular source.
10
+
11
+ This configuration value does not guarantee that a source will enumerate dependencies. Each
12
+ configured source's `enabled?` method must return true for licensed to pull dependency information.
13
+
14
+ `licensed` determines which sources will try to enumerate dependencies based on the following rules:
15
+
16
+ 1. If no sources are configured, all sources are enabled
17
+ 2. If no sources are set to true, any unconfigured sources are enabled
18
+ 3. If any sources are set to true, any unconfigured sources are disabled
19
+
20
+ ```yml
21
+ # all other sources are enabled by default since there are no sources set to true
22
+ sources:
23
+ bower: false
24
+
25
+ # all other sources are disabled by default because a source was set to true
26
+ sources:
27
+ bower: true
28
+ ```
@@ -0,0 +1,19 @@
1
+ # Ignoring dependencies
2
+
3
+ **Key**: ignored
4
+ **Default value**: none
5
+
6
+ This configuration property is used to fully ignore a dependency during all `licensed` commands. Any dependency on this list will not
7
+ be enumerated, or have its metadata cached or checked for compliance. This is intended for dependencies that do not require attribution
8
+ or compliance checking - internal or 1st party dependencies, or dependencies that do not ship with the product such as test frameworks.
9
+
10
+ The ignored dependency list is organized based on the dependency source type - `bundler`, `go`, etc. Add a dependency's metadata identifier to the appropriate source type sub-property to cause `licensed` to no longer take action on the dependency. Glob patterns can be used to identify multiple internal dependencies without having to manage a large list.
11
+
12
+ ```yml
13
+ ignored:
14
+ bundler:
15
+ - my-internal-gem
16
+ - my-first-party-gem
17
+ go:
18
+ - github.com/me/my-repo/**/*
19
+ ```
@@ -0,0 +1,106 @@
1
+ # Dependency metadata cache
2
+
3
+ **Key**: cache_path
4
+ **Default value**: .licenses
5
+
6
+ The cache path is the root directory where `licensed` will write cached metadata files for each dependency.
7
+ By default, files will be written to a folder under the cache path in a structure like:
8
+
9
+ ```text
10
+ <cache path>
11
+ |_<source name>
12
+ |_<dependency identifier>.dep.yml
13
+ ```
14
+
15
+ Cache paths can be given as an absolute or relative path and can contain special path characters
16
+
17
+ ```yml
18
+ cache_path: relative/path/to/cache
19
+ # or
20
+ cache_path: /absolute/path/to/cache
21
+ # or
22
+ cache_path: ~/path/from/home/to/cache
23
+ ```
24
+
25
+ ## Configuring caches for multiple applications
26
+
27
+ When multiple applications are specified in a configuration file caches can be shared, inherited and explicitly configured.
28
+ Unless otherwise specified, preference is given based on the locality and intention of the configuration options.
29
+
30
+ 1. explicitly configured cache paths are preferred to inherited or shared cache paths
31
+ 2. shared cache paths are preferred to inherited cache paths
32
+ 3. cache paths that are not otherwise set by an application will be inherited from the root configuration
33
+
34
+ ### Explicit cache usage for multiple applications
35
+
36
+ Individual applications in a multi-application configuration can explicitly set cache paths.
37
+
38
+ ```yml
39
+ apps:
40
+ - source_path: path/to/application1
41
+ cache_path: path/to/application1/.licenses
42
+ - source_path: path/to/application2
43
+ cache_path: path/to/application2/.licenses
44
+ ```
45
+
46
+ ### Sharing a single cache for multiple applications
47
+
48
+ Sharing a cache across multiple applications is possible by setting `cache_path: <path>` and `shared_cache: true` at the root level.
49
+ Individual applications can opt out of sharing a cache by explicitly setting a cache path.
50
+
51
+ ```yml
52
+ shared_cache: true
53
+ cache_path: .cache/shared
54
+ apps:
55
+ # application1 and application2 will share a cache at .cache/shared
56
+ - source_path: path/to/application1
57
+ - source_path: path/to/application2
58
+ # application3 will use a separate cache at .cache/application3
59
+ - source_path: path/to/application3
60
+ cache_path: .cache/application3
61
+ ```
62
+
63
+ This is equivalent to explicitly configuring the same cache for many applications
64
+
65
+ ```yaml
66
+ apps:
67
+ - source_path: "path/to/application1"
68
+ cache_path: ".cache/shared"
69
+ - source_path: "path/to/application2"
70
+ cache_path: ".cache/shared"
71
+ ```
72
+
73
+ Using the `shared_cache` key is primarily useful when specifying `source_path` as a glob pattern.
74
+
75
+ ```yml
76
+ shared_cache: true
77
+ cache_path: .cache/shared
78
+ source_path: path/to/*
79
+ ```
80
+
81
+ ### Inheriting cache usage from the root configuration
82
+
83
+ When not otherwise specified, applications will inherit a cache path from the root configuration.
84
+ If the root configuration does not explicitly set a cache path value, the default cache path value is used.
85
+
86
+ Inherited cache paths are treated as the root location for each application's metadata cache. Each application
87
+ will store metadata in a named subdirectory of the root location to avoid file path clashes between
88
+ applications.
89
+
90
+ ```yml
91
+ # optional. if not specified, the default value `.licenses` will be used
92
+ cache_path: .cache
93
+ apps:
94
+ - source_path: path/to/application1
95
+ - source_path: path/to/application2
96
+ ```
97
+
98
+ ```text
99
+ .cache
100
+ |_application1
101
+ |_<source type>
102
+ |_<dependency identifier>.dep.yml
103
+ |_application2
104
+ |_<source type>
105
+ |_<dependency identifier>.dep.yml
106
+ ```