Skip to content

Commit

Permalink
feat: introduce generic updater (#1157)
Browse files Browse the repository at this point in the history
This introduces a new `Generic` updater class that scans the file line by line for annotations.

You can annotate a line (inline) via:
* `x-release-please-version`
* `x-release-please-major`
* `x-release-please-minor`
* `x-release-please-patch`

For these annotations, we will try to replace the value on that line only.

You can annotate a block by starting with a line containing:
* `x-release-please-start-version`
* `x-release-please-start-major`
* `x-release-please-start-minor`
* `x-release-please-start-patch`

and close the block with a line containing `x-release-please-end`. Within the block, we will attempt to replace version values.

Additionally, all basic strategies now support the `extra-files` option which will apply this generic updater class.

Fixes #435
Fixes #305
Fixes #1139
Fixes #1174
  • Loading branch information
chingor13 committed Dec 29, 2021
1 parent 956d315 commit c97598c
Show file tree
Hide file tree
Showing 13 changed files with 405 additions and 45 deletions.
42 changes: 42 additions & 0 deletions __snapshots__/generic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
exports['Generic updateContent updates generic version markers 1'] = `
/*
* Copyright 2021 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.cloud.example;
public final class Version {
// {x-release-please-start-version}
public static String VERSION = "2.3.4";
// {x-release-please-end}
// {x-release-please-start-major}
public static String MAJOR = "2";
// {x-release-please-end}
// {x-release-please-start-minor}
public static String MINOR = "3";
// {x-release-please-end}
// {x-release-please-start-patch}
public static String PATCH = "4";
// {x-release-please-end}
public static String INLINE_VERSION = "2.3.4"; // {x-release-please-version}
public static String INLINE_MAJOR = "2"; // {x-release-please-major}
public static String INLINE_MINOR = "3"; // {x-release-please-minor}
public static String INLINE_PATCH = "4"; // {x-release-please-patch}
}
`
29 changes: 29 additions & 0 deletions docs/customizing.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,32 @@ option or the `label` option in the manifest configuration.
You can customize the "tagged" pull request label(s) via the
`--release-label` CLI option or the `release-label` option in the manifest
configuration.

## Updating arbitrary files

For most release strategies, you can provide additional files to update
using the [Generic](src/updaters/generic.ts) updater. You can specify
a comma separated list of file paths with the `--extra-files` CLI option
or the `extra-files` option in the manifest configuration.

To mark versions needing update in those files, you will add annotations
(usually in comments).

You can annotate a line (inline) via:

* `x-release-please-version`
* `x-release-please-major`
* `x-release-please-minor`
* `x-release-please-patch`

For these annotations, we will try to replace the value on that line only.

You can annotate a block by starting with a line containing:

* `x-release-please-start-version`
* `x-release-please-start-major`
* `x-release-please-start-minor`
* `x-release-please-start-patch`

and close the block with a line containing `x-release-please-end`. Within
the block, we will attempt to replace version values.
11 changes: 2 additions & 9 deletions src/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ type Releasers = Record<string, ReleaseBuilder>;
const releasers: Releasers = {
go: options => new Go(options),
'go-yoshi': options => new GoYoshi(options),
'java-yoshi': options => new JavaYoshi(options),
'krm-blueprint': options => new KRMBlueprint(options),
node: options => new Node(options),
ocaml: options => new OCaml(options),
Expand Down Expand Up @@ -140,6 +141,7 @@ export async function buildStrategy(
includeComponentInTag: options.includeComponentInTag,
changelogNotes,
pullRequestTitlePattern: options.pullRequestTitlePattern,
extraFiles: options.extraFiles,
};
switch (options.releaseType) {
case 'ruby': {
Expand All @@ -154,23 +156,15 @@ export async function buildStrategy(
versionFile: options.versionFile,
});
}
case 'java-yoshi': {
return new JavaYoshi({
...strategyOptions,
extraFiles: options.extraFiles,
});
}
case 'java-backport': {
return new JavaYoshi({
...strategyOptions,
extraFiles: options.extraFiles,
versioningStrategy: new AlwaysBumpPatch(),
});
}
case 'java-bom': {
return new JavaYoshi({
...strategyOptions,
extraFiles: options.extraFiles,
versioningStrategy: new DependencyManifest({
bumpMinorPreMajor: options.bumpMinorPreMajor,
bumpPatchForMinorPreMajor: options.bumpPatchForMinorPreMajor,
Expand All @@ -180,7 +174,6 @@ export async function buildStrategy(
case 'java-lts': {
return new JavaYoshi({
...strategyOptions,
extraFiles: options.extraFiles,
versioningStrategy: new ServicePackVersioningStrategy(),
});
}
Expand Down
27 changes: 4 additions & 23 deletions src/plugins/merge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {PullRequestTitle} from '../util/pull-request-title';
import {PullRequestBody, ReleaseData} from '../util/pull-request-body';
import {BranchName} from '../util/branch-name';
import {Update} from '../update';
import {CompositeUpdater} from '../updaters/composite';
import {mergeUpdates} from '../updaters/composite';

/**
* This plugin merges multiple pull requests into a single
Expand All @@ -38,37 +38,18 @@ export class Merge extends ManifestPlugin {
return candidates;
}

const updatesByPath: Record<string, Update[]> = {};
const releaseData: ReleaseData[] = [];
const labels = new Set<string>();
let rawUpdates: Update[] = [];
for (const candidate of candidates) {
const pullRequest = candidate.pullRequest;
for (const update of pullRequest.updates) {
if (updatesByPath[update.path]) {
updatesByPath[update.path].push(update);
} else {
updatesByPath[update.path] = [update];
}
}
rawUpdates = rawUpdates.concat(...pullRequest.updates);
for (const label of pullRequest.labels) {
labels.add(label);
}
releaseData.push(...pullRequest.body.releaseData);
}

const updates: Update[] = [];
for (const path in updatesByPath) {
const update = updatesByPath[path];
const updaters = update.map(u => u.updater);
updates.push({
path,
createIfMissing: update[0].createIfMissing,
updater:
updaters.length === 1
? updaters[0]
: new CompositeUpdater(...updaters),
});
}
const updates = mergeUpdates(rawUpdates);

const pullRequest = {
title: PullRequestTitle.ofTargetBranch(
Expand Down
21 changes: 20 additions & 1 deletion src/strategies/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import {PullRequestTitle} from '../util/pull-request-title';
import {BranchName} from '../util/branch-name';
import {PullRequestBody} from '../util/pull-request-body';
import {PullRequest} from '../pull-request';
import {mergeUpdates} from '../updaters/composite';
import {Generic} from '../updaters/generic';

const DEFAULT_CHANGELOG_PATH = 'CHANGELOG.md';

Expand Down Expand Up @@ -63,6 +65,7 @@ export interface BaseStrategyOptions {
changelogNotes?: ChangelogNotes;
includeComponentInTag?: boolean;
pullRequestTitlePattern?: string;
extraFiles?: string[];
}

/**
Expand All @@ -83,6 +86,7 @@ export abstract class BaseStrategy implements Strategy {
private releaseAs?: string;
private includeComponentInTag: boolean;
private pullRequestTitlePattern?: string;
readonly extraFiles: string[];

readonly changelogNotes: ChangelogNotes;

Expand All @@ -108,6 +112,7 @@ export abstract class BaseStrategy implements Strategy {
options.changelogNotes || new DefaultChangelogNotes(options);
this.includeComponentInTag = options.includeComponentInTag ?? true;
this.pullRequestTitlePattern = options.pullRequestTitlePattern;
this.extraFiles = options.extraFiles || [];
}

/**
Expand Down Expand Up @@ -239,6 +244,9 @@ export abstract class BaseStrategy implements Strategy {
versionsMap,
latestVersion: latestRelease?.tag.version,
});
const updatesWithExtras = mergeUpdates(
updates.concat(...this.extraFileUpdates(newVersion))
);
const pullRequestBody = new PullRequestBody([
{
component,
Expand All @@ -250,14 +258,25 @@ export abstract class BaseStrategy implements Strategy {
return {
title: pullRequestTitle,
body: pullRequestBody,
updates,
updates: updatesWithExtras,
labels,
headRefName: branchName.toString(),
version: newVersion,
draft: draft ?? false,
};
}

private extraFileUpdates(version: Version): Update[] {
const genericUpdater = new Generic({version});
return this.extraFiles.map(path => {
return {
path,
createIfMissing: false,
updater: genericUpdater,
};
});
}

protected changelogEmpty(changelogEntry: string): boolean {
return changelogEntry.split('\n').length <= 1;
}
Expand Down
8 changes: 1 addition & 7 deletions src/strategies/java-yoshi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,17 @@ const CHANGELOG_SECTIONS = [
{type: 'ci', section: 'Continuous Integration', hidden: true},
];

interface JavaStrategyOptions extends BaseStrategyOptions {
extraFiles?: string[];
}

export class JavaYoshi extends BaseStrategy {
readonly extraFiles: string[];
private versionsContent?: GitHubFileContents;
private snapshotVersioning: VersioningStrategy;

constructor(options: JavaStrategyOptions) {
constructor(options: BaseStrategyOptions) {
options.changelogSections = options.changelogSections ?? CHANGELOG_SECTIONS;
// wrap the configured versioning strategy with snapshotting
const parentVersioningStrategy =
options.versioningStrategy || new DefaultVersioningStrategy();
options.versioningStrategy = new JavaSnapshot(parentVersioningStrategy);
super(options);
this.extraFiles = options.extraFiles || [];
this.snapshotVersioning = new JavaAddSnapshot(parentVersioningStrategy);
}

Expand Down
28 changes: 26 additions & 2 deletions src/updaters/composite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {Updater} from '../update';
import {Updater, Update} from '../update';

/**
* The CompositeUpdater chains 0...n updaters and updates
* the content in order.
*/
export class CompositeUpdater implements Updater {
updaters: Updater[];
readonly updaters: Updater[];
/**
* Instantiate a new CompositeUpdater
* @param {Updater[]} updaters The updaters to chain together
Expand All @@ -40,3 +40,27 @@ export class CompositeUpdater implements Updater {
return content || '';
}
}

export function mergeUpdates(updates: Update[]): Update[] {
const updatesByPath: Record<string, Update[]> = {};
for (const update of updates) {
if (updatesByPath[update.path]) {
updatesByPath[update.path].push(update);
} else {
updatesByPath[update.path] = [update];
}
}

const newUpdates: Update[] = [];
for (const path in updatesByPath) {
const update = updatesByPath[path];
const updaters = update.map(u => u.updater);
newUpdates.push({
path,
createIfMissing: update[0].createIfMissing,
updater:
updaters.length === 1 ? updaters[0] : new CompositeUpdater(...updaters),
});
}
return newUpdates;
}

0 comments on commit c97598c

Please sign in to comment.