diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml deleted file mode 100644 index 4d27f8f..0000000 --- a/.github/workflows/pages.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Simple workflow for deploying static content to GitHub Pages -name: Deploy static content to Pages - -on: - push: - branches: - - main - tags-ignore: - - "*" - pull_request: - branches: - - main - workflow_dispatch: {} - -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write - -# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. -concurrency: - group: "pages" - cancel-in-progress: false - -jobs: - # Single deploy job since we're just deploying - deploy: - if: ${{ github.repository_owner == 'openrewrite' }} - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 - with: - distribution: temurin - java-version: 17 - - uses: gradle/actions/setup-gradle@v4 - - name: build - run: ./gradlew ${{ env.GRADLE_SWITCHES }} run - - - name: Create index.html - run: cp build/docs/SUMMARY_snippet.md build/docs/index.md - - - name: Setup Pages - uses: actions/configure-pages@v5 - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 - with: - # Upload entire repository - path: 'build/docs' - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 diff --git a/src/main/kotlin/org/openrewrite/RecipeDescriptorExtensions.kt b/src/main/kotlin/org/openrewrite/RecipeDescriptorExtensions.kt index d284d29..0813140 100755 --- a/src/main/kotlin/org/openrewrite/RecipeDescriptorExtensions.kt +++ b/src/main/kotlin/org/openrewrite/RecipeDescriptorExtensions.kt @@ -6,11 +6,11 @@ import org.openrewrite.config.RecipeDescriptor fun RecipeDescriptor.asYaml(): String { val s = StringBuilder() s.appendLine(""" - --- - type: specs.openrewrite.org/v1beta/recipe - name: $name - displayName: $displayName - description: $description +--- +type: specs.openrewrite.org/v1beta/recipe +name: $name +displayName: $displayName +description: ${description?.replace("\n", " – ") ?: ""} """.trimIndent()) if (tags.isNotEmpty()) { s.appendLine("tags:") diff --git a/src/main/kotlin/org/openrewrite/RecipeMarkdownGenerator.kt b/src/main/kotlin/org/openrewrite/RecipeMarkdownGenerator.kt index 9034fff..45476d9 100644 --- a/src/main/kotlin/org/openrewrite/RecipeMarkdownGenerator.kt +++ b/src/main/kotlin/org/openrewrite/RecipeMarkdownGenerator.kt @@ -104,7 +104,7 @@ class RecipeMarkdownGenerator : Runnable { override fun run() { val outputPath = Paths.get(destinationDirectoryName) - val recipesPath = outputPath.resolve("reference/recipes") + val recipesPath = outputPath.resolve("recipes") try { Files.createDirectories(recipesPath) } catch (e: IOException) { @@ -119,34 +119,7 @@ class RecipeMarkdownGenerator : Runnable { recipeOrigins = RecipeOrigin.parse(recipeSources) // Write latest-versions-of-every-openrewrite-module.md - val versionsSnippetPath = outputPath.resolve("latest-versions-of-every-openrewrite-module.md") - Files.newBufferedWriter(versionsSnippetPath, StandardOpenOption.CREATE).useAndApply { - val bomLink = "[${rewriteRecipeBomVersion}](https://github.com/openrewrite/rewrite-recipe-bom/releases/tag/v${rewriteRecipeBomVersion})" - val mavenLink = "[${mavenPluginVersion}](https://github.com/openrewrite/rewrite-maven-plugin/releases/tag/v${mavenPluginVersion})" - val gradleLink = "[${gradlePluginVersion}](https://github.com/openrewrite/rewrite-gradle-plugin/releases/tag/v${gradlePluginVersion})" - writeln(""" - # Latest versions of every OpenRewrite module - - OpenRewrite's modules are published to [Maven Central](https://search.maven.org/search?q=org.openrewrite). - Each time a release is made, a bill of materials artifact is also published to correctly align and manage the versions of all published artifacts. - The Gradle plugin is published to the [Gradle Plugin Portal](https://plugins.gradle.org/plugin/org.openrewrite.rewrite). - - It is highly recommended that developers use the [rewrite-recipe-bom](https://github.com/openrewrite/rewrite-recipe-bom) - to align the versions of Rewrite's modules to ensure compatibility. - The use of the "bill of materials" means that a developer will only need to specify explicit versions of the BOM and the build plugins: - - | Module | Version | - |-----------------------------------------------------------------------------------------------------------------------| ---------- | - | [**org.openrewrite.recipe:rewrite-recipe-bom**](https://github.com/openrewrite/rewrite-recipe-bom) | **${bomLink}** | - | [**org.openrewrite:rewrite-maven-plugin**](https://github.com/openrewrite/rewrite-maven-plugin) | **${mavenLink}** | - | [**org.openrewrite:rewrite-gradle-plugin**](https://github.com/openrewrite/rewrite-gradle-plugin) | **${gradleLink}** | - """.trimIndent()) - for (recipeOrigin in recipeOrigins.values) { - val repoLink = "[${recipeOrigin.groupId}:${recipeOrigin.artifactId}](${recipeOrigin.githubUrl()})" - val releaseLink = "[${recipeOrigin.version}](${recipeOrigin.githubUrl()}/releases/tag/v${recipeOrigin.version})" - writeln("| ${repoLink.padEnd(117)} | ${releaseLink} |") - } - } + createLatestVersionsFile(outputPath, recipeOrigins) val classloader = recipeClasspath.split(";") .map(Paths::get) @@ -321,18 +294,6 @@ class RecipeMarkdownGenerator : Runnable { val categories = Category.fromDescriptors(recipeDescriptors, categoryDescriptors).sortedBy { it.simpleName } - // Write SUMMARY_snippet.md - val summarySnippetPath = outputPath.resolve("SUMMARY_snippet.md") - Files.newBufferedWriter(summarySnippetPath, StandardOpenOption.CREATE).useAndApply { - for (category in categories) { - write(category.summarySnippet(0)) - } - write(""" - * [Changelog](changelog/changelog.md) - * [$rewriteBomVersion Release (${getDateFormattedYYYYMMDD()})](/changelog/${rewriteBomVersion.replace('.','-')}-Release.md) - """.trimIndent()) - } - // Write recipes-with-data-tables.md val recipesWithDataTablesPath = outputPath.resolve("recipes-with-data-tables.md") Files.newBufferedWriter(recipesWithDataTablesPath, StandardOpenOption.CREATE).useAndApply { @@ -343,9 +304,21 @@ class RecipeMarkdownGenerator : Runnable { "it won't be included in this list._\n") for (recipe in recipesWithDataTables) { - writeln("**[${recipe.displayName}](https://docs.openrewrite.org/?q=${recipe.name})** ") - writeln("**${recipe.name}** ") + var recipePath = ""; + + if (recipe.name.count { it == '.' } == 2 && + recipe.name.contains("org.openrewrite.")) { + recipePath = "recipes/core/" + recipe.name.removePrefix("org.openrewrite.").lowercase(); + } else if (recipe.name.contains("io.moderne.ai")) { + recipePath = "recipes/ai/" + recipe.name.removePrefix("io.moderne.ai.").replace(".", "/").lowercase(); + } else { + recipePath = "recipes/" + recipe.name.removePrefix("org.openrewrite.").replace(".", "/").lowercase(); + } + + writeln("### [${recipe.displayName}](../${recipePath})\n ") + writeln("_${recipe.name}_\n") writeln("${recipe.description}\n") + writeln("#### Data tables:\n") val filteredDataTables = recipe.dataTables.filter { dataTable -> dataTable.name !in dataTablesToIgnore @@ -361,11 +334,51 @@ class RecipeMarkdownGenerator : Runnable { // Write the README.md for each category for (category in categories) { - val categoryIndexPath = outputPath.resolve("reference/recipes/") + val categoryIndexPath = outputPath.resolve("recipes/") category.writeCategoryIndex(categoryIndexPath) } } + private fun createLatestVersionsFile( + outputPath: Path, + recipeOrigins: Map + ) { + val versionsSnippetPath = outputPath.resolve("latest-versions-of-every-openrewrite-module.md") + Files.newBufferedWriter(versionsSnippetPath, StandardOpenOption.CREATE).useAndApply { + val bomLink = + "[${rewriteRecipeBomVersion}](https://github.com/openrewrite/rewrite-recipe-bom/releases/tag/v${rewriteRecipeBomVersion})" + val mavenLink = + "[${mavenPluginVersion}](https://github.com/openrewrite/rewrite-maven-plugin/releases/tag/v${mavenPluginVersion})" + val gradleLink = + "[${gradlePluginVersion}](https://github.com/openrewrite/rewrite-gradle-plugin/releases/tag/v${gradlePluginVersion})" + writeln( + """ + # Latest versions of every OpenRewrite module + + OpenRewrite's modules are published to [Maven Central](https://search.maven.org/search?q=org.openrewrite). + Each time a release is made, a bill of materials artifact is also published to correctly align and manage the versions of all published artifacts. + The Gradle plugin is published to the [Gradle Plugin Portal](https://plugins.gradle.org/plugin/org.openrewrite.rewrite). + + It is highly recommended that developers use the [rewrite-recipe-bom](https://github.com/openrewrite/rewrite-recipe-bom) + to align the versions of Rewrite's modules to ensure compatibility. + The use of the "bill of materials" means that a developer will only need to specify explicit versions of the BOM and the build plugins: + + | Module | Version | + |-----------------------------------------------------------------------------------------------------------------------| ---------- | + | [**org.openrewrite.recipe:rewrite-recipe-bom**](https://github.com/openrewrite/rewrite-recipe-bom) | **${bomLink}** | + | [**org.openrewrite:rewrite-maven-plugin**](https://github.com/openrewrite/rewrite-maven-plugin) | **${mavenLink}** | + | [**org.openrewrite:rewrite-gradle-plugin**](https://github.com/openrewrite/rewrite-gradle-plugin) | **${gradleLink}** | + """.trimIndent() + ) + for (recipeOrigin in recipeOrigins.values) { + val repoLink = "[${recipeOrigin.groupId}:${recipeOrigin.artifactId}](${recipeOrigin.githubUrl()})" + val releaseLink = + "[${recipeOrigin.version}](${recipeOrigin.githubUrl()}/releases/tag/v${recipeOrigin.version})" + writeln("| ${repoLink.padEnd(117)} | ${releaseLink} |") + } + } + } + private fun getNewArtifacts( markdownArtifacts: TreeMap, oldArtifacts: TreeMap, @@ -490,15 +503,15 @@ class RecipeMarkdownGenerator : Runnable { if (deployType == "snapshot") { changelog.appendText("# Snapshot ($formatted)") - changelog.appendText("\n\n{% hint style=\"info\" %}") + changelog.appendText("\n\n:::info") changelog.appendText("\nWant to learn how to use snapshot versions in your project? Check out our [snapshot version guide](/reference/snapshot-instructions.md).") - changelog.appendText("\n{% endhint %}\n\n") + changelog.appendText("\n:::\n\n") } else { changelog.appendText("# $rewriteBomVersion release ($formatted)") - changelog.appendText("\n\n{% hint style=\"info\" %}") + changelog.appendText("\n\n:::info") changelog.appendText("\nThis changelog only shows what recipes have been added, removed, or changed. OpenRewrite may do releases that do not include these types of changes. To see these changes, please go to the [releases page](https://github.com/openrewrite/rewrite/releases).") - changelog.appendText("\n{% endhint %}\n\n") + changelog.appendText("\n:::\n\n") } // An example of what the changelog could look like after the below statements can be found here: @@ -706,55 +719,23 @@ class RecipeMarkdownGenerator : Runnable { descriptor.displayName.replace("`", "") } - /** - * Produce the snippet for this category to be fitted into Gitbook's SUMMARY.md, which provides the index - * that makes markdown documents accessible through gitbook's interface - */ - fun summarySnippet(indentationDepth: Int): String { - val indentBuilder = StringBuilder(" ") - for (i in 0 until indentationDepth) { - indentBuilder.append(" ") - } - val indent = indentBuilder.toString() - val result = StringBuilder() - - if (path == "") { - // Recipes that don't have a path are part of the "core" set of recipes - result.appendLine("$indent* [Core](reference/recipes/core.md)") - } else { - // Some nested recipes have a `github` path which gets converted into `Github` when it should be `GitHub`. - if (displayName == "Github") { - displayName = "GitHub" - } - - result.appendLine("$indent* [$displayName](reference/recipes/$path/README.md)") - } - - for (recipe in recipes) { - // Section headings will display backticks, rather than rendering as code. Omit them so it doesn't look terrible - result.appendLine( - "$indent * [${ - recipe.displayName.replace( - "`", - "" - ) - }](${getRecipeRelativePath(recipe)}.md)" - ) - } - - for (category in subcategories.sortedBy { it.simpleName }) { - result.append(category.summarySnippet(indentationDepth + 1)) - } - - return result.toString() - } - /** * Produce the contents of the README.md file for this category. */ private fun categoryIndex(): String { return StringBuilder().apply { - appendLine("# $displayName") + // Docusaurus gets confused when parsing C# as the sidebar title. We need to surround it in backticks + // so it displays correctly. + if (displayName == "C#") { + appendLine("# `C#`") + // Ai is not capitalized by default - so let's switch it to be AI + } else if (displayName == "Ai") { + appendLine("# AI") + } + else { + appendLine("# $displayName") + } + // While the description is not _supposed_ to be nullable it has happened before @Suppress("SENSELESS_COMPARISON") if (descriptor != null && descriptor.description != null) { @@ -771,7 +752,7 @@ class RecipeMarkdownGenerator : Runnable { appendLine("## Categories") appendLine() for (subcategory in subcategories) { - appendLine("* [${subcategory.displayName}](/reference/recipes/${subcategory.path})") + appendLine("* [${subcategory.displayName}](/recipes/${subcategory.path})") } appendLine() } @@ -795,11 +776,27 @@ class RecipeMarkdownGenerator : Runnable { appendLine() for (recipe in compositeRecipes) { - val recipeSimpleName = recipe.name.substring(recipe.name.lastIndexOf('.') + 1).lowercase() + var recipeSimpleName = recipe.name.substring(recipe.name.lastIndexOf('.') + 1).lowercase() + val formattedDisplayName = recipe.displayName + .replace("