Skip to content

Commit

Permalink
Script to Check the Table of Contents in the Wiki and CI workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
Rd4dev committed Apr 10, 2024
1 parent bf80719 commit 13efcfa
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 0 deletions.
18 changes: 18 additions & 0 deletions .github/workflows/wiki.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,24 @@ on:
gollum:

jobs:
table_of_contents_check:
name: Wiki Check Table of Contents match Headers
runs-on: ubuntu-20.04
env:
CACHE_DIRECTORY: ~/.bazel_cache
steps:
- uses: actions/checkout@v2

- name: Set up Bazel
uses: abhinavsingh/setup-bazel@v3
with:
version: 4.0.0

- name: Wiki Check Table of Contents
id: wikichecktoc
run: |
bazel run //scripts:wiki_table_of_contents_check -- ${GITHUB_WORKSPACE}
wiki-deploy:
runs-on: ${{ matrix.os }}
strategy:
Expand Down
7 changes: 7 additions & 0 deletions scripts/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,13 @@ kt_jvm_binary(
],
)

kt_jvm_binary(
name = "wiki_table_of_contents_check",
testonly = True,
main_class = "org.oppia.android.scripts.wiki.WikiTableOfContentsCheckKt",
runtime_deps = ["//scripts/src/java/org/oppia/android/scripts/wiki:wiki_table_of_contents_check_lib"],
)

# Note that this is intentionally not test-only since it's used by the app build pipeline. Also,
# this apparently needs to be a java_binary to set up runfiles correctly when executed within a
# Starlark rule as a tool.
Expand Down
18 changes: 18 additions & 0 deletions scripts/src/java/org/oppia/android/scripts/wiki/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""
Libraries corresponding to scripting tools that help with continuous integration workflows.
"""

load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library")

kt_jvm_library(
name = "wiki_table_of_contents_check_lib",
testonly = True,
srcs = [
"WikiTableOfContentsCheck.kt",
],
visibility = ["//scripts:oppia_script_binary_visibility"],
deps = [
"//scripts/src/java/org/oppia/android/scripts/common:bazel_client",
"//scripts/src/java/org/oppia/android/scripts/common:git_client",
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package org.oppia.android.scripts.wiki

import java.io.File

/**
* Script for ensuring that the table of contents in each wiki page matches with its respective headers.
*
* Usage:
* bazel run //scripts:wiki_sample -- <path_to_default_working_directory>
*
* Arguments:
* - path_to_default_working_directory: The default working directory on the runner for steps, and the default location of repository.
*
* Example:
* bazel run //scripts:wiki_sample -- ${GITHUB_WORKSPACE}
*/
fun main(vararg args: String) {
// Path to the repo's wiki.
val githubWorkspace = "${args[0]}/wiki/"
val wikiDirectory = File(githubWorkspace)

// Check if the wiki directory exists
if (wikiDirectory.exists() && wikiDirectory.isDirectory) {
processWikiDirectory(wikiDirectory)
} else {
println("No contents found in the Wiki directory.")
}
}

/**
* Checks every file in the wiki repo
*
* @param wikiDirectory the default working directory
*/
fun processWikiDirectory(wikiDirectory: File) {
wikiDirectory.listFiles()?.forEach { file ->
processWikiFile(file)
}
}

/**
* Processes the contents of a single wiki file to ensure the accuracy of the Table of Contents.
*
* @param file The wiki file to process.
*/
fun processWikiFile(file: File) {
var inTableOfContents = false
var skipBlankLine = false

file.forEachLine { line ->
when {
// Checking for Table of Contents section
line.trim() == "## Table of Contents" -> {
inTableOfContents = true
skipBlankLine = true
}
// Checking to skip the blank line immediately after the ## Table of Contents
skipBlankLine && line.isBlank() -> skipBlankLine = false
// Validating the contents in the Table of Content
inTableOfContents && line.trimStart().startsWith("- [") && !line.contains("https://") -> {
validateTableOfContents(file, line)
}
// Checking for end of Table of Contents section
inTableOfContents && line.isBlank() -> inTableOfContents = false
}
}
}

/**
* Validates the accuracy of a Table of Contents entry in a wiki file.
*
* @param file The wiki file being validated.
* @param line The line containing the Table of Contents entry.
*/
fun validateTableOfContents(file: File, line: String) {
val titleRegex = "\\[(.*?)\\]".toRegex()
val title = titleRegex.find(line)?.groupValues?.get(1)?.replace('-', ' ')
?.replace(Regex("[?&./:’'*!,(){}\\[\\]+]"), "")
?.trim()

val linkRegex = "\\(#(.*?)\\)".toRegex()
val link = linkRegex.find(line)?.groupValues?.get(1)?.removePrefix("#")?.replace('-', ' ')
?.replace(Regex("[?&./:’'*!,(){}\\[\\]+]"), "")
?.replace("confetti_ball", "")?.trim()

// Checks if the table of content title matches with the header link text
val matches = title.equals(link, ignoreCase = true)
if (!matches) {
throw Exception("\nMismatch of Table of Content with headers in the File: ${file.name}. " +
"\nThe Title: '${titleRegex.find(line)?.groupValues?.get(1)}' " +
"doesn't match with its corresponding Link: '${linkRegex.find(line)?.groupValues?.get(1)}'.")
}
}

0 comments on commit 13efcfa

Please sign in to comment.