Skip to content
Snippets Groups Projects
Unverified Commit 47703aab authored by HonkingGoose's avatar HonkingGoose Committed by GitHub
Browse files

docs: improve adding a package manager development (#7704)

parent f5128ab3
No related branches found
No related tags found
No related merge requests found
# Adding a Package Manager # Adding a Package Manager
This document describes the steps to take if you are interested in adding new language/package manager support. This document describes the steps to take if you want to add a new language/package manager.
### Code structure ## Code structure
Each package manager lives under `lib/manager/*`, and are often tightly coupled to datasources under `lib/datasource/*`. Each package manager lives under `lib/manager/*`, and is often tightly coupled to datasources under `lib/datasource/*`.
Versioning logic (e.g. semver, pep440) lives under `lib/versioning/*`. Versioning logic (e.g. SemVer, PEP 440) lives under `lib/versioning/*`.
Common application logic for Renovate - not specific to particular managers - usually lives under `lib/workers/*`. Common application logic for Renovate, not specific to particular managers, usually lives under `lib/workers/*`.
### Manager requirements ## Manager requirements
The manager's `index.ts` file supports the following values/functions: The manager's `index.ts` file supports the following values/functions:
...@@ -20,44 +20,50 @@ The manager's `index.ts` file supports the following values/functions: ...@@ -20,44 +20,50 @@ The manager's `index.ts` file supports the following values/functions:
- language (optional) - language (optional)
- supportsLockFileMaintenance (optional) - supportsLockFileMaintenance (optional)
##### `extractPackageFile(content, packageFile, config)` (async, semi-mandatory) ### `extractPackageFile(content, packageFile, config)` (async, semi-mandatory)
This function is mandatory unless you use `extractAllPackageFiles` instead. This function is mandatory unless you use `extractAllPackageFiles` instead.
It takes as arguments the file's content and optionally the file's full file pathname and config, and returns an array of detected/extracted dependencies, including: It takes as arguments the file's content and optionally the file's full file pathname and config.
The function returns an array of detected/extracted dependencies, including:
- dependency name - dependency name
- dependency type (e.g. dependencies, devDependencies, etc) - dependency type (e.g. dependencies, devDependencies, etc)
- currentValue - currentValue
- versioning used (e.g. semver, pep440) - versioning used (e.g. SemVer, PEP 440)
This function doesn't necessarily need to _understand_ the file or even syntax that it is passed, instead it just needs to understand enough to extract an accurate list of dependencies. The `extractPackageFile` function doesn't need to fully _understand_ the file or syntax that it receives.
It needs to understand enough to extract an accurate list of dependencies.
As a general approach, we want to extract _all_ dependencies from each dependency file, even if they contain values we don't support. As a general approach, we extract _all_ dependencies from each dependency file, even if they contain values we don't support.
For any that have unsupported values that we cannot renovate, this `extractPackageFile` function should set a `skipReason` to a value that would be helpful to someone reading the logs. Any dependency file that has values we cannot renovate, should have a `skipReason` message added to the `extractPackageFile` function.
Make sure the `skipReason` variable string is helpful to someone reading the logs.
Also, if a file is passed to `extractPackageFile` which is a "false match" (e.g. not an actual package file, or contains no dependencies) then this function can return `null` to have it ignored and removed from the list of package files. Also, if a file is passed to `extractPackageFile` which is a "false match" (e.g. not an actual package file, or contains no dependencies) then this function can return `null` to have it ignored and removed from the list of package files.
##### `extractAllPackageFiles(packageFiles)` (async, optional) ### `extractAllPackageFiles(packageFiles)` (async, optional)
You can use this function instead of `extractPackageFile` if the package manager cannot parse/extract all package files in parallel. Use this function instead of `extractPackageFile` if the package manager cannot parse/extract all package files in parallel.
For example, npm/Yarn needs to correlate package files together for features such as Lerna and Workspaces, so it's necessary to iterate through them all together after initial parsing. For example, npm/Yarn needs to correlate package files together for features such as Lerna and Workspaces, so it's necessary to iterate through them all together after initial parsing.
As another example, Gradle needs to call a command via child process in order to extract dependencies, so that must be done first. As another example, Gradle needs to call a command via a child process in order to extract dependencies, so that must be done first.
This function takes an array of filenames as input and returns an array of filenames and dependencies as a result. The `extractAllPackageFiles` function takes an array of filenames as input.
It returns an array of filenames and dependencies.
#### `getRangeStrategy(config)` (optional) ### `getRangeStrategy(config)` (optional)
This optional function should be written if you wish the manager to support "auto" range strategies, e.g. pinning or not pinning depending on other values in the package file. Write this optional function if you want the manager to support "auto" range strategies.
`npm` uses this to pin `devDependencies` but not `dependencies` unless the package file is detected as an app. For example, pinning or not pinning a dependency, depending on other values in the package file.
The `npm` manager uses the `getRangeStrategy` function to pin `devDependencies` but not `dependencies` unless the package file is detected as an app.
If left undefined, then a default `getRangeStrategy` will be used that always returns "replace". If left undefined, then a default `getRangeStrategy` will be used that always returns "replace".
##### `language` (optional) ### `language` (optional)
This is used when more than one package manager share settings from a common language. This is used when more than one package manager shares settings from a common language.
#### `supportsLockFileMaintenance` (optional) ### `supportsLockFileMaintenance` (optional)
Set to true if this package manager needs to update lock files in addition to package files. Set to true if this package manager needs to update lock files in addition to package files.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment