diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 000000000..fc4202a82 --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,306 @@ +enhancement: +- changed-files: + - all-globs-to-all-files: + - '!archive/*/*/README.md' +- base-branch: main +needs docs: +- changed-files: + - any-glob-to-any-file: + - README.md + - .github/*.md +- base-branch: main +tests: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/testinfo.yml +- base-branch: main +baklava: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/Baklava.* + - archive/*/*/baklava.* +- base-branch: main +base64 encode decode: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/Base64EncodeDecode.* + - archive/*/*/base64-encode-decode.* + - archive/*/*/base64EncodeDecode.* + - archive/*/*/base64_encode_decode.* +- base-branch: main +binary search: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/BinarySearch.* + - archive/*/*/binary-search.* + - archive/*/*/binarySearch.* + - archive/*/*/binary_search.* +- base-branch: main +bubble sort: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/BubbleSort.* + - archive/*/*/bubble-sort.* + - archive/*/*/bubbleSort.* + - archive/*/*/bubble_sort.* +- base-branch: main +capitalize: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/Capitalize.* + - archive/*/*/capitalize.* +- base-branch: main +convex hull: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/ConvexHull.* + - archive/*/*/convex-hull.* + - archive/*/*/convexHull.* + - archive/*/*/convex_hull.* +- base-branch: main +depth first search: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/DepthFirstSearch.* + - archive/*/*/depth-first-search.* + - archive/*/*/depthFirstSearch.* + - archive/*/*/depth_first_search.* +- base-branch: main +dijkstra: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/Dijkstra.* + - archive/*/*/dijkstra.* +- base-branch: main +duplicate character counter: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/DuplicateCharacterCounter.* + - archive/*/*/duplicate-character-counter.* + - archive/*/*/duplicateCharacterCounter.* + - archive/*/*/duplicate_character_counter.* +- base-branch: main +even odd: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/EvenOdd.* + - archive/*/*/even-odd.* + - archive/*/*/evenOdd.* + - archive/*/*/even_odd.* +- base-branch: main +factorial: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/Factorial.* + - archive/*/*/factorial.* +- base-branch: main +fibonacci: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/Fibonacci.* + - archive/*/*/fibonacci.* +- base-branch: main +file input output: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/FileInputOutput.* + - archive/*/*/file-input-output.* + - archive/*/*/fileInputOutput.* + - archive/*/*/file_input_output.* +- base-branch: main +fizz buzz: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/FizzBuzz.* + - archive/*/*/fizz-buzz.* + - archive/*/*/fizzBuzz.* + - archive/*/*/fizz_buzz.* +- base-branch: main +fraction math: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/FractionMath.* + - archive/*/*/fraction-math.* + - archive/*/*/fractionMath.* + - archive/*/*/fraction_math.* +- base-branch: main +hello world: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/HelloWorld.* + - archive/*/*/hello-world.* + - archive/*/*/helloWorld.* + - archive/*/*/hello_world.* +- base-branch: main +insertion sort: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/InsertionSort.* + - archive/*/*/insertion-sort.* + - archive/*/*/insertionSort.* + - archive/*/*/insertion_sort.* +- base-branch: main +job sequencing: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/JobSequencing.* + - archive/*/*/job-sequencing.* + - archive/*/*/jobSequencing.* + - archive/*/*/job_sequencing.* +- base-branch: main +josephus problem: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/JosephusProblem.* + - archive/*/*/josephus-problem.* + - archive/*/*/josephusProblem.* + - archive/*/*/josephus_problem.* +- base-branch: main +linear search: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/LinearSearch.* + - archive/*/*/linear-search.* + - archive/*/*/linearSearch.* + - archive/*/*/linear_search.* +- base-branch: main +longest common subsequence: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/LongestCommonSubsequence.* + - archive/*/*/longest-common-subsequence.* + - archive/*/*/longestCommonSubsequence.* + - archive/*/*/longest_common_subsequence.* +- base-branch: main +longest palindromic substring: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/LongestPalindromicSubstring.* + - archive/*/*/longest-palindromic-substring.* + - archive/*/*/longestPalindromicSubstring.* + - archive/*/*/longest_palindromic_substring.* +- base-branch: main +longest word: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/LongestWord.* + - archive/*/*/longest-word.* + - archive/*/*/longestWord.* + - archive/*/*/longest_word.* +- base-branch: main +maximum array rotation: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/MaximumArrayRotation.* + - archive/*/*/maximum-array-rotation.* + - archive/*/*/maximumArrayRotation.* + - archive/*/*/maximum_array_rotation.* +- base-branch: main +maximum subarray: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/MaximumSubarray.* + - archive/*/*/maximum-subarray.* + - archive/*/*/maximumSubarray.* + - archive/*/*/maximum_subarray.* +- base-branch: main +merge sort: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/MergeSort.* + - archive/*/*/merge-sort.* + - archive/*/*/mergeSort.* + - archive/*/*/merge_sort.* +- base-branch: main +minimum spanning tree: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/MinimumSpanningTree.* + - archive/*/*/minimum-spanning-tree.* + - archive/*/*/minimumSpanningTree.* + - archive/*/*/minimum_spanning_tree.* +- base-branch: main +palindromic number: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/PalindromicNumber.* + - archive/*/*/palindromic-number.* + - archive/*/*/palindromicNumber.* + - archive/*/*/palindromic_number.* +- base-branch: main +prime number: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/PrimeNumber.* + - archive/*/*/prime-number.* + - archive/*/*/primeNumber.* + - archive/*/*/prime_number.* +- base-branch: main +quick sort: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/QuickSort.* + - archive/*/*/quick-sort.* + - archive/*/*/quickSort.* + - archive/*/*/quick_sort.* +- base-branch: main +quine: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/Quine.* + - archive/*/*/quine.* +- base-branch: main +remove all whitespace: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/RemoveAllWhitespace.* + - archive/*/*/remove-all-whitespace.* + - archive/*/*/removeAllWhitespace.* + - archive/*/*/remove_all_whitespace.* +- base-branch: main +reverse string: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/ReverseString.* + - archive/*/*/reverse-string.* + - archive/*/*/reverseString.* + - archive/*/*/reverse_string.* +- base-branch: main +roman numeral: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/RomanNumeral.* + - archive/*/*/roman-numeral.* + - archive/*/*/romanNumeral.* + - archive/*/*/roman_numeral.* +- base-branch: main +rot13: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/Rot13.* + - archive/*/*/rot13.* +- base-branch: main +selection sort: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/SelectionSort.* + - archive/*/*/selection-sort.* + - archive/*/*/selectionSort.* + - archive/*/*/selection_sort.* +- base-branch: main +sleep sort: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/SleepSort.* + - archive/*/*/sleep-sort.* + - archive/*/*/sleepSort.* + - archive/*/*/sleep_sort.* +- base-branch: main +transpose matrix: +- changed-files: + - any-glob-to-any-file: + - archive/*/*/TransposeMatrix.* + - archive/*/*/transpose-matrix.* + - archive/*/*/transposeMatrix.* + - archive/*/*/transpose_matrix.* +- base-branch: main diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml new file mode 100644 index 000000000..b3d5e231a --- /dev/null +++ b/.github/workflows/pr-labeler.yml @@ -0,0 +1,19 @@ +name: "Pull Request Labeler" +on: + pull_request_target: + paths: + - '!archive/*/*/*.md' + +jobs: + pr-labeler: + permissions: + contents: read + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - uses: actions/labeler@v6 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + sync-labels: true diff --git a/scripts/set_up_labeler.py b/scripts/set_up_labeler.py new file mode 100644 index 000000000..93e80f067 --- /dev/null +++ b/scripts/set_up_labeler.py @@ -0,0 +1,92 @@ +""" +Run this to update the labeler workflow: + + poetry run python scripts/set_up_labeler.py + +This should be done when a new project is added +""" + +from pathlib import Path +from typing import Any + +import yaml + +GLOTTER_PATH = Path(".glotter.yml") +LABELER_CONFIG_PATH = Path(".github/labeler.yml") + + +def main(): + projects = read_projects() + config = get_labeler_config(projects) + LABELER_CONFIG_PATH.write_text(yaml.safe_dump(config, sort_keys=False), encoding="utf-8") + + +def read_projects() -> list[str]: + with GLOTTER_PATH.open(encoding="utf-8") as f: + contents = yaml.safe_load(f) + + return sorted(" ".join(project["words"]) for project in contents["projects"].values()) + + +def get_labeler_config(projects: list[str]) -> dict[str, Any]: + # Common labels + config: dict[str, Any] = { + # Not just language READMEs + "enhancement": [ + {"changed-files": [{"all-globs-to-all-files": ["!archive/*/*/README.md"]}]}, + {"base-branch": "main"}, + ], + # README.md and any Markdown file in .github directory + "needs docs": [ + {"changed-files": [{"any-glob-to-any-file": ["README.md", ".github/*.md"]}]}, + {"base-branch": "main"}, + ], + # Any language testinfo.yml files + "tests": [ + {"changed-files": [{"any-glob-to-any-file": ["archive/*/*/testinfo.yml"]}]}, + {"base-branch": "main"}, + ], + } + + # Add project-specific labels + for project in projects: + # Project-specific language files (with all possible variations) + filenames = sorted( + set(func(project.split()) for func in [camel_case, underscore, hyphen, pascal_case]) + ) + config[project] = [ + { + "changed-files": [ + { + "any-glob-to-any-file": [ + f"archive/*/*/{filename}.*" for filename in filenames + ] + } + ] + }, + { + "base-branch": "main", + }, + ] + + return config + + +def camel_case(words: list[str]) -> str: + return "".join([words[0]] + [word.title() for word in words[1:]]) + + +def underscore(words: list[str]) -> str: + return "_".join(words) + + +def hyphen(words: list[str]) -> str: + return "-".join(words) + + +def pascal_case(words: list[str]) -> str: + return "".join(word.title() for word in words) + + +if __name__ == "__main__": + main()