#!/usr/bin/env python3 """ POMMER.PY THIS IS PROPRIETARY SOFTWARE DO NOT DISTRIBUTE TO OUTSIDERS! This Python File is distributed with every Kotlin Plugin Repository! If you find this to be confusing to use look at the Documentation in "rattatwinko/pommer" Run this Script with Python 3.11 ; 3.9 This YET only works with Maven! """ import os import xml.etree.ElementTree as ET import re from pathlib import Path import argparse import glob def parse_pom_xml(pom_path): """ Parse a pom.xml file and extract relevant information """ try: print(f"Parsing POM file: {pom_path}") # Register the default namespace ET.register_namespace('', "http://maven.apache.org/POM/4.0.0") # Parse the XML file tree = ET.parse(pom_path) root = tree.getroot() # Define namespace for easier XPath queries ns = {'mvn': "http://maven.apache.org/POM/4.0.0"} # Extract project info artifact_id = root.find('./mvn:artifactId', ns).text group_id = root.find('./mvn:groupId', ns).text if root.find('./mvn:groupId', ns) is not None else "unknown" version = root.find('./mvn:version', ns).text if root.find('./mvn:version', ns) is not None else "unknown" name = root.find('./mvn:name', ns).text if root.find('./mvn:name', ns) is not None else artifact_id # Extract Java version java_version_elem = root.find('./mvn:properties/mvn:java.version', ns) java_version = java_version_elem.text if java_version_elem is not None else "17" # Default to Java 17 if not specified # Extract packaging type (default to jar if not specified) packaging = root.find('./mvn:packaging', ns) packaging = packaging.text if packaging is not None else "jar" # Check if Kotlin is used kotlin_version_elem = root.find('./mvn:properties/mvn:kotlin.version', ns) kotlin_version = kotlin_version_elem.text if kotlin_version_elem is not None else None # Check for Kotlin plugin or dependency kotlin_plugin = None kotlin_dep = None # Check for Kotlin plugin plugins = root.findall('.//mvn:plugin', ns) for plugin in plugins: plugin_group = plugin.find('./mvn:groupId', ns) if plugin_group is not None and plugin_group.text == 'org.jetbrains.kotlin': kotlin_plugin = plugin break # Check for Kotlin dependency deps = root.findall('.//mvn:dependency', ns) for dep in deps: dep_group = dep.find('./mvn:groupId', ns) dep_artifact = dep.find('./mvn:artifactId', ns) if (dep_group is not None and dep_group.text == 'org.jetbrains.kotlin' and dep_artifact is not None and 'kotlin-stdlib' in dep_artifact.text): kotlin_dep = dep break # Determine if this is a Kotlin project is_kotlin = kotlin_version is not None or kotlin_plugin is not None or kotlin_dep is not None # Check for source directories source_dir = None source_dirs = root.findall('.//mvn:sourceDirectory', ns) if source_dirs: source_dir = source_dirs[0].text # Check for default goal (to use the same command as IntelliJ) default_goal = None default_goal_elem = root.find('./mvn:build/mvn:defaultGoal', ns) if default_goal_elem is not None: default_goal = default_goal_elem.text return { "artifact_id": artifact_id, "group_id": group_id, "version": version, "name": name, "java_version": java_version, "packaging": packaging, "is_kotlin": is_kotlin, "kotlin_version": kotlin_version, "source_dir": source_dir, "default_goal": default_goal, "pom_path": pom_path } except Exception as e: print(f"Error parsing {pom_path}: {e}") return None def generate_gitea_workflow(pom_infos): """ Generate a Gitea workflow YAML file based on multiple POM information """ if not pom_infos: print("No valid POM files found") return None # Get the highest Java version required java_version = max([info["java_version"] for info in pom_infos]) # Check if any project uses Kotlin uses_kotlin = any(info["is_kotlin"] for info in pom_infos) # Kotlin version (if any) kotlin_version = None for info in pom_infos: if info["kotlin_version"]: kotlin_version = info["kotlin_version"] break # Construct the workflow content workflow_content = f"""name: Maven Build on: push: branches: [ main, master, dev ] pull_request: branches: [ main, master ] workflow_dispatch: jobs: build: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up JDK {java_version} uses: actions/setup-java@v3 with: distribution: 'temurin' java-version: '{java_version}' cache: 'maven' - name: Install Maven run: | if ! command -v mvn &> /dev/null; then echo "Maven not found, installing..." sudo apt-get update sudo apt-get install -y maven fi mvn --version - name: Debug Info run: | echo "Current workspace directory: $GITHUB_WORKSPACE" echo "Current directory: $(pwd)" echo "Project structure:" find . -type f -name "*.kt" | sort find . -type f -name "pom.xml" echo "Maven version: $(mvn --version)" """ # Add individual build steps for each POM for i, info in enumerate(pom_infos): # Determine the Maven command to use (same as the default goal if specified) maven_command = "clean package" if info["default_goal"]: maven_command = info["default_goal"] workflow_content += f""" - name: Build {info["name"]} ({info["artifact_id"]}) run: | echo "Building {info["artifact_id"]}" echo "Current directory: $(pwd)" # Run Maven build directly using the POM file path mvn -B {maven_command} -f "$GITHUB_WORKSPACE/pom.xml" -Dmaven.compiler.failOnError=true """ # Add artifact upload step workflow_content += f""" - name: Upload {info["artifact_id"]} artifact uses: actions/upload-artifact@v3 with: name: {info["artifact_id"]} path: target/{info['artifact_id']}-*.jar if-no-files-found: error """ return workflow_content def find_pom_files(base_dir="."): """Find all pom.xml files in the given directory and subdirectories""" return glob.glob(f"{base_dir}/**/pom.xml", recursive=True) def main(): parser = argparse.ArgumentParser(description='Generate Gitea workflow for Maven/Kotlin projects') parser.add_argument('--dir', '-d', default='.', help='Base directory to search for pom.xml files') parser.add_argument('--specific-pom', '-p', help='Path to a specific pom.xml file to process') args = parser.parse_args() pom_files = [] if args.specific_pom: pom_files = [args.specific_pom] else: pom_files = find_pom_files(args.dir) if not pom_files: print(f"No pom.xml files found in {args.dir}") return print(f"Found {len(pom_files)} pom.xml files") # Parse all POM files pom_infos = [] for pom_file in pom_files: info = parse_pom_xml(pom_file) if info: pom_infos.append(info) if not pom_infos: print("No valid POM files could be parsed") return # Generate the workflow content workflow_content = generate_gitea_workflow(pom_infos) if not workflow_content: return # Create the .gitea/workflows directory if it doesn't exist workflow_dir = Path(".gitea/workflows") workflow_dir.mkdir(parents=True, exist_ok=True) # Write the workflow file workflow_file = workflow_dir / "maven_build.yaml" with open(workflow_file, "w") as f: f.write(workflow_content) print(f"Gitea workflow generated at: {workflow_file}") print(f"This workflow will build {len(pom_infos)} Maven projects") # Print summary of detected projects print("\nDetected projects:") for info in pom_infos: kotlin_info = "with Kotlin" if info["is_kotlin"] else "Java only" build_command = info["default_goal"] if info["default_goal"] else "clean package" print( f"- {info['name']} ({info['artifact_id']}): {kotlin_info}, Java {info['java_version']}, build: {build_command}") # Create a simple direct build script as fallback with open("build.sh", "w") as f: f.write("""#!/bin/bash # Direct build script for Maven project echo "Current directory: $(pwd)" echo "Building project with Maven..." # Run Maven build using the exact pom.xml location mvn clean package -f "$(pwd)/pom.xml" echo "Build complete. JAR file should be in target/ directory." """) # Make it executable os.chmod("build.sh", 0o755) print(f"Simple build script generated at: build.sh") if __name__ == "__main__": main()