Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: refactor Version selection #257

Merged
merged 4 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions third_party/docfx-doclet-143274/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@
</plugin>

<plugin>
<groupId>com.coveo</groupId>
<groupId>com.spotify.fmt</groupId>
<artifactId>fmt-maven-plugin</artifactId>
<version>2.13</version>
<version>2.23</version>
<configuration>
<style>google</style>
<verbose>true</verbose>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ public class RepoMetadata {
@SerializedName("api_id")
private String apiId;

@SerializedName("recommended_package")
private String recommendedPackage;

private String artifactId;

public String getNamePretty() {
Expand Down Expand Up @@ -80,6 +83,10 @@ public void setProductDocumentationUri(String productDocumentationUri) {
this.productDocumentationUri = productDocumentationUri;
}

public Optional<String> getRecommendedPackage() {
return Optional.ofNullable(this.recommendedPackage);
}

public String getApiDescription() {
return this.apiDescription;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ PackageOverviewFile buildPackageOverviewFile(
PackageElement packageElement,
RepoMetadata repoMetadata,
String artifactVersion,
String recommendedApiVersion) {
String recommendedPackage) {
String status = packageLookup.extractStatus(packageElement);
String fileName = packageElement.getQualifiedName() + ".md";
PackageOverviewFile packageOverviewFile =
Expand All @@ -48,7 +48,7 @@ PackageOverviewFile buildPackageOverviewFile(
packageLookup,
referenceBuilder,
artifactVersion,
recommendedApiVersion);
recommendedPackage);
return packageOverviewFile;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,13 @@ public class PackageOverviewFile {
// This is only set if the package is not a GA package
private String PRERELEASE_IMPLICATIONS = "";

private String recommendedApiVersion;
// Uses the `recommended_package` field set in the RepoMetadata file if set; otherwise computes
// it.
private String recommendedPackage;

// This is only set if the package is not the latest GA package
private String recommendedPackageLink;

// This is only set if the package is not the recommended package
private String RECOMMENDED_VERSION = "";

// This is only set if the package is a stub package
Expand All @@ -81,19 +85,22 @@ public PackageOverviewFile(
PackageLookup packageLookup,
ReferenceBuilder referenceBuilder,
String artifactVersion,
String recommendedApiVersion) {
String recommendedPackage) {
this.outputPath = outputPath;
this.fileName = fileName;
this.packageElement = packageElement;
this.recommendedApiVersion = recommendedApiVersion;
this.recommendedPackage = recommendedPackage;

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

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

// This will always link to the latest version of the package classes
String cloudRADChildElementLinkPrefix =
"https://cloud.google.com/java/docs/reference/" + repoMetadata.getArtifactId() + "/latest/";
"https://cloud.google.com/java/docs/reference/"
+ repoMetadata.getArtifactId()
+ "/"
+ artifactVersion
+ "/";

String packageURIPathGithub = packageURIPath.replace('.', '/');
String githubSourcePackageLink =
Expand All @@ -103,56 +110,49 @@ public PackageOverviewFile(
+ "/src/main/java/"
+ packageURIPathGithub;

String cgcRootUri = "https://cloud.google.com/java/docs/reference/";
this.recommendedPackageLink =
cgcRootUri
+ repoMetadata.getArtifactId()
+ "/"
+ artifactVersion
+ "/"
+ this.recommendedPackage;
// If the package status is not a GA version, then add a disclaimer around prerelease
// implications
if (status != null) {
this.PRERELEASE_IMPLICATIONS =
"## Prerelease Implications\n\n"
+ "This package is a prerelease version! Use with caution.\n"
+ "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"
+ "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"
+ "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"
+ "For example, if a client library has two packages: `v1` and `v2alpha`, then the latest stable version is `v1`.\n"
+ "If you use an unstable release, breaking changes may be introduced when upgrading.\n\n";
+ "This package is a prerelease version! Use with caution.\n\n"
+ "Prerelease versions are considered unstable as they may be shut down and/or subject to breaking changes when upgrading.\n"
+ "Use them only for testing or if you specifically need their experimental features.\n\n";
}

// This regex captures the package path before the version (if it exists) and the version
Pattern pattern = Pattern.compile("(.*?)(v\\d+.*?)(?:\\.|$)");
ImmutableList<Object> packageVersionURIInfo =
extractPackageBaseURIBeforeVersion(packageURIPath, pattern);
String basePackageURI = packageVersionURIInfo.get(0).toString();
String packageVersion = packageVersionURIInfo.get(1).toString();
// Build link to the Cloud RAD link for the recommended package
String recommendedPackageVersionLink =
cloudRADChildElementLinkPrefix + basePackageURI + recommendedApiVersion;

// A package is not the latest GA version if it is a prerelease version, or if it is a GA
// version that is not the same as the recommended Api version
if (basePackageURI != "N/A") {
if (status != null || (!packageVersion.equals(this.recommendedApiVersion))) {
this.RECOMMENDED_VERSION =
"## This package is not the latest GA version! \n\n"
+ " For this library, we recommend using the [package]("
+ recommendedPackageVersionLink
+ ")"
+ " associated with API version "
+ this.recommendedApiVersion
+ " for new applications.\n"
+ "\n";
}
// If a package is not the same as the recommended package, add a disclaimer. If the recommended
// package does not exist, then do not set the disclaimer.
if (!this.recommendedPackage.isEmpty()
&& !packageElement.getQualifiedName().toString().equals(this.recommendedPackage)) {
this.RECOMMENDED_VERSION =
"## This package is not the recommended entry point to using this client library!\n\n"
+ " For this library, we recommend using ["
+ recommendedPackage
+ "]("
+ recommendedPackageLink
+ ")"
+ " for new applications.\n"
+ "\n";
}

// If recommended version package URI exists, link to it for the Stub class as well
if (basePackageURI != "N/A"
// Link to recommended package (if it exists) for the Stub class as well
if (!this.recommendedPackage.isEmpty()
&& String.valueOf(this.packageElement.getQualifiedName()).contains("stub")) {
this.STUB_IMPLICATIONS =
"## Stub Package Implications\n\n"
+ "This package is a a base stub class. It is for advanced usage and reflects the underlying API directly.\n"
+ "We generally recommend using non-stub, latest GA package, such as ["
+ basePackageURI
+ recommendedApiVersion
+ "We generally recommend using the non-stub, latest GA package, such as ["
+ recommendedPackage
+ "]("
+ recommendedPackageVersionLink
+ recommendedPackageLink
+ ")"
+ ". Use with caution.\n";
} else if (String.valueOf(this.packageElement.getQualifiedName()).contains("stub")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@
import com.microsoft.util.ElementUtil;
import com.microsoft.util.FileUtil;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.lang.model.element.PackageElement;
import jdk.javadoc.doclet.DocletEnvironment;
Expand Down Expand Up @@ -105,7 +106,7 @@ public boolean build() {
artifactVersion,
librariesBomVersion,
repoMetadataFilePath,
processor.recommendedApiVersion);
processor.recommendedPackage);
FileUtil.dumpToFile(libraryOverviewFile);
}
return true;
Expand All @@ -131,7 +132,10 @@ class Processor {
private final List<PackageElement> allPackages =
elementUtil.extractPackageElements(environment.getIncludedElements());

private String recommendedApiVersion = "";
private ApiVersion recommendedApiVersion;

// If set in RepoMetadata, use that value. Otherwise, calculate based on recommendedApiVersion
private String recommendedPackage = "";

private RepoMetadata repoMetadata = new RepoMetadata();

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

// Get recommended ApiVersion for new Library Overview
HashSet<ApiVersion> versions = new HashSet<>();
for (PackageElement pkg : allPackages) {
packageLookup.extractApiVersion(pkg).ifPresent(versions::add);
}

if (!versions.isEmpty()) {
recommendedApiVersion = ApiVersion.getRecommended(versions).toString();
}
// Use the provided recommended package in the .repo-metadata.json file, if set
recommendedPackage =
repoMetadata
.getRecommendedPackage()
.orElseGet(
() -> {
// Calculate the recommended package based on the latest stable Version ID.
HashMap<ApiVersion, String> packageVersions = new HashMap<>();
for (PackageElement pkg : allPackages) {
Optional<ApiVersion> apiVersion = packageLookup.extractApiVersion(pkg);
apiVersion.ifPresent(
version ->
packageVersions.put(version, String.valueOf(pkg.getQualifiedName())));
}
if (packageVersions.isEmpty()) return "";

ApiVersion recommended = ApiVersion.getRecommended(packageVersions.keySet());
return packageVersions.get(recommended).toString();
});

for (PackageElement element : organizedPackagesWithoutStubs.get(PackageGroup.VISIBLE)) {
tocFile.addTocItem(buildPackage(element));
Expand Down Expand Up @@ -200,7 +214,7 @@ private TocItem buildPackage(PackageElement element) {
packageTocItem.getItems().add(packageSummary);
packageOverviewFiles.add(
packageBuilder.buildPackageOverviewFile(
element, repoMetadata, artifactVersion, recommendedApiVersion));
element, repoMetadata, artifactVersion, recommendedPackage));

// build classes/interfaces/enums/exceptions/annotations
packageTocItem
Expand Down
Loading