Skip to content

Commit 991e2a9

Browse files
authored
feat: refactor Version selection (#257)
* feat: refactor Version selection * update fmt-maven-plugin and lint * refactor to not pre-calculate the version unnecessarily
1 parent 0487d2a commit 991e2a9

17 files changed

Lines changed: 329 additions & 241 deletions

third_party/docfx-doclet-143274/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,9 @@
9494
</plugin>
9595

9696
<plugin>
97-
<groupId>com.coveo</groupId>
97+
<groupId>com.spotify.fmt</groupId>
9898
<artifactId>fmt-maven-plugin</artifactId>
99-
<version>2.13</version>
99+
<version>2.23</version>
100100
<configuration>
101101
<style>google</style>
102102
<verbose>true</verbose>

third_party/docfx-doclet-143274/src/main/java/com/google/docfx/doclet/RepoMetadata.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ public class RepoMetadata {
4646
@SerializedName("api_id")
4747
private String apiId;
4848

49+
@SerializedName("recommended_package")
50+
private String recommendedPackage;
51+
4952
private String artifactId;
5053

5154
public String getNamePretty() {
@@ -80,6 +83,10 @@ public void setProductDocumentationUri(String productDocumentationUri) {
8083
this.productDocumentationUri = productDocumentationUri;
8184
}
8285

86+
public Optional<String> getRecommendedPackage() {
87+
return Optional.ofNullable(this.recommendedPackage);
88+
}
89+
8390
public String getApiDescription() {
8491
return this.apiDescription;
8592
}

third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/PackageBuilder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ PackageOverviewFile buildPackageOverviewFile(
3535
PackageElement packageElement,
3636
RepoMetadata repoMetadata,
3737
String artifactVersion,
38-
String recommendedApiVersion) {
38+
String recommendedPackage) {
3939
String status = packageLookup.extractStatus(packageElement);
4040
String fileName = packageElement.getQualifiedName() + ".md";
4141
PackageOverviewFile packageOverviewFile =
@@ -48,7 +48,7 @@ PackageOverviewFile buildPackageOverviewFile(
4848
packageLookup,
4949
referenceBuilder,
5050
artifactVersion,
51-
recommendedApiVersion);
51+
recommendedPackage);
5252
return packageOverviewFile;
5353
}
5454
}

third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/PackageOverviewFile.java

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,13 @@ public class PackageOverviewFile {
5555
// This is only set if the package is not a GA package
5656
private String PRERELEASE_IMPLICATIONS = "";
5757

58-
private String recommendedApiVersion;
58+
// Uses the `recommended_package` field set in the RepoMetadata file if set; otherwise computes
59+
// it.
60+
private String recommendedPackage;
5961

60-
// This is only set if the package is not the latest GA package
62+
private String recommendedPackageLink;
63+
64+
// This is only set if the package is not the recommended package
6165
private String RECOMMENDED_VERSION = "";
6266

6367
// This is only set if the package is a stub package
@@ -81,19 +85,22 @@ public PackageOverviewFile(
8185
PackageLookup packageLookup,
8286
ReferenceBuilder referenceBuilder,
8387
String artifactVersion,
84-
String recommendedApiVersion) {
88+
String recommendedPackage) {
8589
this.outputPath = outputPath;
8690
this.fileName = fileName;
8791
this.packageElement = packageElement;
88-
this.recommendedApiVersion = recommendedApiVersion;
92+
this.recommendedPackage = recommendedPackage;
8993

9094
String packageURIPath = fileName.replace(".md", "");
9195

9296
this.PACKAGE_HEADER = "# Package " + packageURIPath + " (" + artifactVersion + ")\n";
9397

94-
// This will always link to the latest version of the package classes
9598
String cloudRADChildElementLinkPrefix =
96-
"https://cloud.google.com/java/docs/reference/" + repoMetadata.getArtifactId() + "/latest/";
99+
"https://cloud.google.com/java/docs/reference/"
100+
+ repoMetadata.getArtifactId()
101+
+ "/"
102+
+ artifactVersion
103+
+ "/";
97104

98105
String packageURIPathGithub = packageURIPath.replace('.', '/');
99106
String githubSourcePackageLink =
@@ -103,56 +110,49 @@ public PackageOverviewFile(
103110
+ "/src/main/java/"
104111
+ packageURIPathGithub;
105112

113+
String cgcRootUri = "https://cloud.google.com/java/docs/reference/";
114+
this.recommendedPackageLink =
115+
cgcRootUri
116+
+ repoMetadata.getArtifactId()
117+
+ "/"
118+
+ artifactVersion
119+
+ "/"
120+
+ this.recommendedPackage;
106121
// If the package status is not a GA version, then add a disclaimer around prerelease
107122
// implications
108123
if (status != null) {
109124
this.PRERELEASE_IMPLICATIONS =
110125
"## Prerelease Implications\n\n"
111-
+ "This package is a prerelease version! Use with caution.\n"
112-
+ "Prerelease versions are considered unstable as they may be shut down. You can read more about [Cloud API versioning strategy here](https://cloud.google.com/apis/design/versioning).\n"
113-
+ "Each Cloud Java client library may contain multiple packages. Each package containing a version number in its name corresponds to a published version of the service.\n"
114-
+ "We recommend using the latest stable version for new production applications, which can be identified by the largest numeric version that does not contain a suffix.\n"
115-
+ "For example, if a client library has two packages: `v1` and `v2alpha`, then the latest stable version is `v1`.\n"
116-
+ "If you use an unstable release, breaking changes may be introduced when upgrading.\n\n";
126+
+ "This package is a prerelease version! Use with caution.\n\n"
127+
+ "Prerelease versions are considered unstable as they may be shut down and/or subject to breaking changes when upgrading.\n"
128+
+ "Use them only for testing or if you specifically need their experimental features.\n\n";
117129
}
118130

119-
// This regex captures the package path before the version (if it exists) and the version
120-
Pattern pattern = Pattern.compile("(.*?)(v\\d+.*?)(?:\\.|$)");
121-
ImmutableList<Object> packageVersionURIInfo =
122-
extractPackageBaseURIBeforeVersion(packageURIPath, pattern);
123-
String basePackageURI = packageVersionURIInfo.get(0).toString();
124-
String packageVersion = packageVersionURIInfo.get(1).toString();
125-
// Build link to the Cloud RAD link for the recommended package
126-
String recommendedPackageVersionLink =
127-
cloudRADChildElementLinkPrefix + basePackageURI + recommendedApiVersion;
128-
129-
// A package is not the latest GA version if it is a prerelease version, or if it is a GA
130-
// version that is not the same as the recommended Api version
131-
if (basePackageURI != "N/A") {
132-
if (status != null || (!packageVersion.equals(this.recommendedApiVersion))) {
133-
this.RECOMMENDED_VERSION =
134-
"## This package is not the latest GA version! \n\n"
135-
+ " For this library, we recommend using the [package]("
136-
+ recommendedPackageVersionLink
137-
+ ")"
138-
+ " associated with API version "
139-
+ this.recommendedApiVersion
140-
+ " for new applications.\n"
141-
+ "\n";
142-
}
131+
// If a package is not the same as the recommended package, add a disclaimer. If the recommended
132+
// package does not exist, then do not set the disclaimer.
133+
if (!this.recommendedPackage.isEmpty()
134+
&& !packageElement.getQualifiedName().toString().equals(this.recommendedPackage)) {
135+
this.RECOMMENDED_VERSION =
136+
"## This package is not the recommended entry point to using this client library!\n\n"
137+
+ " For this library, we recommend using ["
138+
+ recommendedPackage
139+
+ "]("
140+
+ recommendedPackageLink
141+
+ ")"
142+
+ " for new applications.\n"
143+
+ "\n";
143144
}
144145

145-
// If recommended version package URI exists, link to it for the Stub class as well
146-
if (basePackageURI != "N/A"
146+
// Link to recommended package (if it exists) for the Stub class as well
147+
if (!this.recommendedPackage.isEmpty()
147148
&& String.valueOf(this.packageElement.getQualifiedName()).contains("stub")) {
148149
this.STUB_IMPLICATIONS =
149150
"## Stub Package Implications\n\n"
150151
+ "This package is a a base stub class. It is for advanced usage and reflects the underlying API directly.\n"
151-
+ "We generally recommend using non-stub, latest GA package, such as ["
152-
+ basePackageURI
153-
+ recommendedApiVersion
152+
+ "We generally recommend using the non-stub, latest GA package, such as ["
153+
+ recommendedPackage
154154
+ "]("
155-
+ recommendedPackageVersionLink
155+
+ recommendedPackageLink
156156
+ ")"
157157
+ ". Use with caution.\n";
158158
} else if (String.valueOf(this.packageElement.getQualifiedName()).contains("stub")) {

third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/YmlFilesBuilder.java

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@
1919
import com.microsoft.util.ElementUtil;
2020
import com.microsoft.util.FileUtil;
2121
import java.util.ArrayList;
22-
import java.util.HashSet;
22+
import java.util.HashMap;
2323
import java.util.List;
24+
import java.util.Optional;
2425
import java.util.stream.Collectors;
2526
import javax.lang.model.element.PackageElement;
2627
import jdk.javadoc.doclet.DocletEnvironment;
@@ -105,7 +106,7 @@ public boolean build() {
105106
artifactVersion,
106107
librariesBomVersion,
107108
repoMetadataFilePath,
108-
processor.recommendedApiVersion);
109+
processor.recommendedPackage);
109110
FileUtil.dumpToFile(libraryOverviewFile);
110111
}
111112
return true;
@@ -131,7 +132,10 @@ class Processor {
131132
private final List<PackageElement> allPackages =
132133
elementUtil.extractPackageElements(environment.getIncludedElements());
133134

134-
private String recommendedApiVersion = "";
135+
private ApiVersion recommendedApiVersion;
136+
137+
// If set in RepoMetadata, use that value. Otherwise, calculate based on recommendedApiVersion
138+
private String recommendedPackage = "";
135139

136140
private RepoMetadata repoMetadata = new RepoMetadata();
137141

@@ -143,15 +147,25 @@ void process() {
143147
.filter(pkg -> !packageLookup.isApiVersionStubPackage(pkg))
144148
.collect(Collectors.toList()));
145149

146-
// Get recommended ApiVersion for new Library Overview
147-
HashSet<ApiVersion> versions = new HashSet<>();
148-
for (PackageElement pkg : allPackages) {
149-
packageLookup.extractApiVersion(pkg).ifPresent(versions::add);
150-
}
151-
152-
if (!versions.isEmpty()) {
153-
recommendedApiVersion = ApiVersion.getRecommended(versions).toString();
154-
}
150+
// Use the provided recommended package in the .repo-metadata.json file, if set
151+
recommendedPackage =
152+
repoMetadata
153+
.getRecommendedPackage()
154+
.orElseGet(
155+
() -> {
156+
// Calculate the recommended package based on the latest stable Version ID.
157+
HashMap<ApiVersion, String> packageVersions = new HashMap<>();
158+
for (PackageElement pkg : allPackages) {
159+
Optional<ApiVersion> apiVersion = packageLookup.extractApiVersion(pkg);
160+
apiVersion.ifPresent(
161+
version ->
162+
packageVersions.put(version, String.valueOf(pkg.getQualifiedName())));
163+
}
164+
if (packageVersions.isEmpty()) return "";
165+
166+
ApiVersion recommended = ApiVersion.getRecommended(packageVersions.keySet());
167+
return packageVersions.get(recommended).toString();
168+
});
155169

156170
for (PackageElement element : organizedPackagesWithoutStubs.get(PackageGroup.VISIBLE)) {
157171
tocFile.addTocItem(buildPackage(element));
@@ -200,7 +214,7 @@ private TocItem buildPackage(PackageElement element) {
200214
packageTocItem.getItems().add(packageSummary);
201215
packageOverviewFiles.add(
202216
packageBuilder.buildPackageOverviewFile(
203-
element, repoMetadata, artifactVersion, recommendedApiVersion));
217+
element, repoMetadata, artifactVersion, recommendedPackage));
204218

205219
// build classes/interfaces/enums/exceptions/annotations
206220
packageTocItem

0 commit comments

Comments
 (0)