Skip to content

Commit

Permalink
docs: partial rewrite of developer docs (#22977)
Browse files Browse the repository at this point in the history
  • Loading branch information
HonkingGoose authored Jun 26, 2023
1 parent fbf9d59 commit f12576e
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 25 deletions.
52 changes: 30 additions & 22 deletions docs/development/adding-a-package-manager.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
# Adding a Package Manager

This document describes the steps to take if you want to add a new language/package manager.
This document explains how to add a new language/package manager.

## Code structure

Each package manager lives under `lib/modules/manager/*`, and is often tightly coupled to datasources under `lib/modules/datasource/*`.
Code for package managers goes in the `lib/modules/manager/*` directory.
The package manager code is often tightly coupled to the datasource code in `lib/modules/datasource/*`.

Versioning logic (e.g. SemVer, PEP 440) lives under `lib/modules/versioning/*`.
Versioning logic like Semver or PEP 440 goes in `lib/modules/versioning/*`.

Common application logic for Renovate, not specific to particular managers, usually lives under `lib/workers/*`.

## Manager requirements

The manager's `index.ts` file supports the following values/functions:
The manager's `index.ts` file supports the following values or functions:

| Value/function | Optional | Async |
| ----------------------------- | -------- | ----- |
Expand All @@ -29,46 +30,53 @@ The manager's `index.ts` file supports the following values/functions:
### `bumpPackageVersion` (optional)

Use this function to allow version bumps of updated packages.
For example, to increase the version of a Maven module if a package has been updated.
Another example would be to bump the Helm chart version, if a subchart version has been updated.
For example:

- to increase the version of a Maven module if a package has been updated
- to bump the Helm chart version, if a subchart version has been updated

### `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.
The function returns an array of detected/extracted dependencies, including:
The function returns an array of detected or extracted dependencies, including the:

- dependency name
- dependency type (e.g. dependencies, devDependencies, etc)
- dependency type (dependencies, devDependencies, etc)
- currentValue
- versioning used (e.g. SemVer, PEP 440)
- versioning used (like SemVer, PEP 440)

The `extractPackageFile` function doesn't need to fully _understand_ the file or syntax that it gets.
It needs to understand enough to extract an accurate list of dependencies.
It needs to understand enough to extract a correct list of dependencies.

In general, we extract _all_ dependencies from each dependency file, even if they have values we don't support.

As a general approach, we extract _all_ dependencies from each dependency file, even if they have values we don't support.
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.
If the function reads parts of a dependency file that it can't parse, it should give a `skipReason` message to the `extractPackageFile` function.
Make sure the `skipReason` message 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 has no dependencies) then this function can return `null` to have it ignored and removed from the list of package files.
If `extractPackageFile` is passed a file which is a "false match", so not a package file, or a file with no dependencies then it can return `null`.
Downstream this results in the file being ignored and removed from the list of package files.

### `extractAllPackageFiles(packageFiles)` (async, optional)

Use this function instead of `extractPackageFile` if the package manager cannot parse/extract all package files in parallel.
Normally a package manager parses or extracts all package files in _parallel_, and can thus use the `extractPackageFile` function.
If the package manager you're adding works in _serial_, use this function instead.

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 the npm and Yarn package manager must process the `package.json` and `package-lock` or `yarn.lock` files together.
This allows features like Lerna and Workspaces to work.
This means that for npm or Yarn we need to iterate through all package files after the initial parsing.

As another example, Gradle needs to call a command via a 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. //Unclear what that must be done first refers to here...

The `extractAllPackageFiles` function takes an array of filenames as input.
It returns an array of filenames and dependencies.

### `getRangeStrategy(config)` (optional)

Write this optional function if you want the manager to support "auto" range strategies.
For example, pinning or not pinning a dependency, depending on other values in the package file.
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.
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".

Expand All @@ -78,12 +86,12 @@ This is used when more than one package manager shares settings from a common la

### `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.

### `updateArtifacts` (async, optional)

Use `updateArtifacts` to run binaries that in turn will update files.
`updateArtifacts` is often used to indirectly update lock files.
We often use `updateArtifacts` to update lock files indirectly.

To _directly_ update dependencies in lock files: use `updateLockedDependency` instead.

Expand Down
9 changes: 6 additions & 3 deletions docs/development/readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Renovate Developer Docs

This directory is intended to provide documentation for developers/contributors on the Renovate project.
For information on how to configure Renovate as an end-user, please see the [Renovate bot documentation](https://docs.renovatebot.com).
> **Note**
> If you're an end-user of Renovate, please read the [Renovate documentation](https://docs.renovatebot.com).
If you want to contribute to Renovate or get it running locally for some other reason, please check out [contributing guidelines](../../.github/contributing.md) for steps on how to set up the project locally.
The `docs/development` directory is for developers and contributors.
The Markdown files explain how to work on Renovate's code.

If you need to get Renovate running locally, to contribute, or for some other reason, please read our [contributing guidelines](../../.github/contributing.md) to learn how.

0 comments on commit f12576e

Please sign in to comment.