-
Notifications
You must be signed in to change notification settings - Fork 124
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #138 from github/v2
Release licensed v2
- Loading branch information
Showing
106 changed files
with
9,776 additions
and
1,640 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
# Adding a new source dependency enumerator | ||
|
||
## Implement new `Source` class | ||
|
||
Dependency enumerators inherit and override the [`Licensed::Sources::Source`](../lib/licensed/sources/source.rb) class. | ||
|
||
#### Required method overrides | ||
1. `Licensed::Sources::Source#enabled?` | ||
- Returns whether dependencies can be enumerated in the current environment. | ||
2. `Licensed::Sources::Source#enumerate_dependencies` | ||
- Returns an enumeration of `Licensed::Dependency` objects found which map to the dependencies of the current project. | ||
|
||
#### Optional method overrides | ||
1. `Licensed::Sources::Source.type` | ||
- Returns the name of the current dependency enumerator as it is found in a licensed configuration file. | ||
|
||
## Determining if dependencies should be enumerated | ||
|
||
This section covers the `Licensed::Sources::Source#enabled?` method. This method should return a truthy/falsey value indicating | ||
whether `Licensed::Source::Sources#enumerate_dependencies` should be called on the current dependency source object. | ||
|
||
Determining whether dependencies should be enumerated depends on whether all the tools or files needed to find dependencies are present. | ||
For example, to enumerate `npm` dependencies the `npm` CLI tool must be found with `Licensed::Shell.tool_available?` and a `package.json` file needs to exist in the licensed app's configured [`source_path`](./configuration.md#configuration-paths). | ||
|
||
#### Gating functionality when required tools are not available. | ||
|
||
When adding new dependency sources, ensure that `script/bootstrap` scripting and tests are only run if the required tooling is available on the development machine. | ||
|
||
* See `script/bootstrap` for examples of gating scripting based on whether tooling executables are found. | ||
* Use `Licensed::Shell.tool_available?` when writing test files to gate running a test suite when tooling executables aren't available. | ||
```ruby | ||
if Licensed::Shell.tool_available?('bundle') | ||
describe Licensed::Source::Bundler do | ||
... | ||
end | ||
end | ||
``` | ||
|
||
## Enumerating dependencies | ||
|
||
This section covers the `Licensed::Sources::Source#enumerate_dependencies` method. This method should return an enumeration of | ||
`Licensed::Dependency` objects. | ||
|
||
Enumerating dependencies will require some knowledge of the package manager, language or framework that manages the dependencies. | ||
|
||
Relying on external tools always has a risk that the tool could change. It's generally preferred to not rely on package manager files | ||
or other implementation details as these could change over time. CLI tools that provides the necessary information are generally preferred | ||
as they will more likely have requirements for backwards compatibility. | ||
|
||
#### Creating dependency objects | ||
|
||
Creating a new `Licensed::Dependency` object requires name, version, and path arguments. Dependency objects optionally accept a path to use as search root when finding licenses along with any other metadata that is useful to identify the dependency. | ||
|
||
##### `Licensed::Dependency` arguments | ||
|
||
1. name (required) | ||
- The name of the dependency. Together with the version, this should uniquely identify the dependency. | ||
2. version (required) | ||
- The current version of the dependency, used to determine when a dependency has changed. Together with the name, this should uniquely identify the dependency. | ||
3. path (required) | ||
- A path used by [`Licensee`](https://github.com/benbalter/licensee) to find dependency license content. Can be either a folder or a file. | ||
4. search_root (optional) | ||
- The root of the directory hierarchy to search for a license file. | ||
5. metadata (optional) | ||
- Any additional metadata that would be useful in identifying the dependency. | ||
- suggested metadata | ||
1. summary | ||
- A short description of the dependencies purpose. | ||
2. homepage | ||
- The dependency's homepage. | ||
6. errors (optional) | ||
- Any errors found when loading dependency information. | ||
|
||
#### Finding licenses | ||
|
||
In some cases, license content will be in a parent directory of the specified location. For instance, this can happen with Golang packages | ||
that share a license file, e.g. `github.com/go/pkg/1` and `github.com/go/pkg/2` might share a license at `github.com/go/pkg`. In this case, create a `Licensed::Dependency` with the optional `search_root` property, which denotes the root of the directory hierarchy that should be searched. Directories will be examined in order from the given license location to the `search_root` location to prefer license files with more specificity, i.e. `github.com/go/pkg/1` will be searched before `github.com/go/pkg`. | ||
|
||
#### Handling errors when enumerating dependencies | ||
|
||
External tools have their own error handling which, if left unhandled, can cause dependency enumeration as a whole to fail either for an individual dependency source or for licensed as a whole. These errors should be gracefully handled to allow for the best possible user experience. | ||
|
||
##### Handling errors related to a specific dependency | ||
|
||
`Licensed::Dependency#initialize` will already set errors related to `nil` or empty `path:` arguments, as well as paths that don't exist. Additional errors can be set to a dependency using the `errors:` argument, e.g. `Licensed::Dependency.new(errors: ["error"])`. | ||
|
||
When a dependency contains errors, all errors will be reported to the user and `Licensed::Command::Command#evaluate_dependency` will be not be called. | ||
|
||
##### Handling errors related to source evaluation | ||
|
||
When an error occurs related to a specific source, raise a `Licensed::Sources::Source::Error` with an informative message. The error will be caught and reported to the user, and further evaluation of the source will be halted. | ||
|
||
As an example, this could be useful if a source is enabled but incorrectly configured. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
# Commands | ||
|
||
Run `licensed -h` to see help content for running licensed commands. | ||
|
||
## `list` | ||
|
||
Running the list command finds the dependencies for all sources in all configured applications. No additional actions are taken on each dependency. | ||
|
||
## `cache` | ||
|
||
The cache command finds all dependencies and ensures that each dependency has an up-to-date cached record. | ||
|
||
Dependency records will be saved if: | ||
1. The `force` option is set | ||
2. No cached record is found | ||
3. The cached record's version is different than the current dependency's version | ||
- If the cached record's license text contents matches the current dependency's license text then the `license` metadata from the cached record is retained for the new saved record. | ||
|
||
After the cache command is run, any cached records that don't match up to a current application dependency will be deleted. | ||
|
||
## `status` | ||
|
||
The status command finds all dependencies and checks whether each dependency has a valid cached record. | ||
|
||
A dependency will fail the status checks if: | ||
1. No cached record is found | ||
2. The cached record's version is different than the current dependency's version | ||
3. The cached record doesn't contain any license text | ||
4. The cached record's `license` metadata doesn't match an `allowed` license from the dependency's application configuration. | ||
|
||
## `version` | ||
|
||
Displays the current licensed version. | ||
|
||
# Adding a new command | ||
|
||
## Implement new `Command` class | ||
|
||
Licensed commands inherit and override the [`Licensed::Sources::Command`](../lib/licensed/commands/command.rb) class. | ||
|
||
#### Required method overrides | ||
1. `Licensed::Commands::Command#evaluate_dependency` | ||
- Runs a command execution on an application dependency. | ||
|
||
The `evaluate_dependency` method should contain the specific command logic. This method has access to the application configuration, dependency source enumerator and dependency currently being evaluated as well as a reporting hash to contain information about the command execution. | ||
|
||
#### Optional method overrides | ||
|
||
The following methods break apart the different levels of command execution. Each method wraps lower levels of command execution in a corresponding reporter method. | ||
|
||
1. `Licensed::Commands::Command#run` | ||
- Runs `run_app` for each application configuration found. Wraps the execution of all applications in `Reporter#report_run`. | ||
2. `Licensed::Commands::Command#run_app` | ||
- Runs `run_source` for each dependency source enumerator enabled for the application configuration. Wraps the execution of all sources in `Reporter#report_app`. | ||
3. `Licensed::Commands::Command#run_source` | ||
- Runs `run_dependency` for each dependency found in the source. Wraps the execution of all dependencies in `Reporter#report_source`. | ||
4. `Licensed::Commands::Command#run_dependency` | ||
- Runs `evaluate_dependency` for the dependency. Wraps the execution of all dependencies in `Reporter#report_dependency`. | ||
|
||
As an example, `Licensed::Commands::Command#run_app` calls `Reporter#report_app` to wrap every call to `Licensed::Commands::Command#run_source`. | ||
|
||
##### Overriding optional methods | ||
|
||
The `run` methods can be overridden to provide additional reporting data or functionality. Overriding a method should call the original method with a block for the additional logic. | ||
|
||
```ruby | ||
def run_app(app) | ||
super do |report| | ||
result = yield report | ||
|
||
# do other thing | ||
call_additional_functionality(app) | ||
|
||
# add reporting information | ||
report["result"] = result | ||
|
||
# return the result | ||
result | ||
end | ||
end | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Migrating your licensed configuration and cached records to the latest version of licensed | ||
|
||
Licensed v2+ ships with an additional executable, `licensed-migrator`, that can be used to update your licensed files to the format expected by the currently installed version. To run, execute `licensed migrate --from v1 -c <path to licensed configuration file>`, replacing `v1` with the major version of licensed to migrate from. |
Oops, something went wrong.