pommer new

This commit is contained in:
rattatwinko
2025-05-09 17:46:51 +02:00
parent 160c25c7cc
commit c85571a2ca

280
pommer.py
View File

@@ -1,98 +1,274 @@
#!/usr/bin/env python3
import os
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
import re
from pathlib import Path from pathlib import Path
import argparse import argparse
import os import glob
def analyze_pom(pom_path):
"""Detect required tools from pom.xml""" 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) tree = ET.parse(pom_path)
root = tree.getroot() root = tree.getroot()
ns = {'mvn': 'http://maven.apache.org/POM/4.0.0'}
requirements = { # Define namespace for easier XPath queries
'java_version': root.findtext('mvn:properties/mvn:java.version', namespaces=ns, default="21"), ns = {'mvn': "http://maven.apache.org/POM/4.0.0"}
'kotlin_version': root.findtext('mvn:properties/mvn:kotlin.version', namespaces=ns),
'needs_docker': False
}
# Check for docker-maven-plugin # Extract project info
for plugin in root.findall('.//mvn:plugin', namespaces=ns): artifact_id = root.find('./mvn:artifactId', ns).text
if 'docker' in plugin.findtext('mvn:artifactId', namespaces=ns, default=""): group_id = root.find('./mvn:groupId', ns).text if root.find('./mvn:groupId', ns) is not None else "unknown"
requirements['needs_docker'] = True 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 break
return requirements # 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
def generate_gitea_actions(pom_path, requirements): # Determine if this is a Kotlin project
"""Generate Gitea Actions workflow file""" is_kotlin = kotlin_version is not None or kotlin_plugin is not None or kotlin_dep is not None
workflow_dir = Path(".gitea/workflows")
workflow_dir.mkdir(parents=True, exist_ok=True)
workflow_file = workflow_dir / "build.yml" # Check for source directories
source_dir = None
source_dirs = root.findall('.//mvn:sourceDirectory', ns)
if source_dirs:
source_dir = source_dirs[0].text
java_version = requirements['java_version'] # Check for default goal (to use the same command as IntelliJ)
kotlin_version = requirements['kotlin_version'] default_goal = None
needs_docker = requirements['needs_docker'] default_goal_elem = root.find('./mvn:build/mvn:defaultGoal', ns)
if default_goal_elem is not None:
default_goal = default_goal_elem.text
# Base Maven command with optimizations return {
maven_cmd = "mvn -B -T 1C -Ddependency.cache=true -Dmaven.artifact.threads=8" "artifact_id": artifact_id,
if kotlin_version: "group_id": group_id,
maven_cmd += " -Dkotlin.compiler.incremental=true" "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
content = f"""name: Java CI with Maven
on: [push, pull_request] 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: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK {java_version} - name: Set up JDK {java_version}
uses: actions/setup-java@v3 uses: actions/setup-java@v3
with: with:
java-version: '{java_version}'
distribution: 'temurin' distribution: 'temurin'
java-version: '{java_version}'
cache: 'maven' cache: 'maven'
- name: Install Maven - name: Install Maven
run: | run: |
sudo apt-get update -qq if ! command -v mvn &> /dev/null; then
echo "Maven not found, installing..."
sudo apt-get update
sudo apt-get install -y maven sudo apt-get install -y maven
fi
mvn --version mvn --version
"""
if needs_docker: - name: Debug Info
content += """
- name: Set up Docker
run: | run: |
sudo apt-get install -y docker.io echo "Current workspace directory: $GITHUB_WORKSPACE"
sudo systemctl start docker echo "Current directory: $(pwd)"
""" echo "Project structure:"
find . -type f -name "*.kt" | sort
find . -type f -name "pom.xml"
echo "Maven version: $(mvn --version)"
"""
content += f""" # Add individual build steps for each POM
- name: Build with Maven for i, info in enumerate(pom_infos):
run: {maven_cmd} clean package # 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"]
with open(workflow_file, "w") as f: workflow_content += f"""
f.write(content) - 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)
print(f"✓ Generated Gitea Actions workflow at {workflow_file}")
def main(): def main():
parser = argparse.ArgumentParser(description='Generate Gitea Actions workflow for Maven project') parser = argparse.ArgumentParser(description='Generate Gitea workflow for Maven/Kotlin projects')
parser.add_argument('pom_path', type=str, help='Path to pom.xml') 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() args = parser.parse_args()
pom_path = Path(args.pom_path) pom_files = []
if not pom_path.exists(): if args.specific_pom:
print(f"❌ Error: {pom_path} does not exist") 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 return
requirements = analyze_pom(pom_path) print(f"Found {len(pom_files)} pom.xml files")
generate_gitea_actions(pom_path, requirements)
# 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__": if __name__ == "__main__":
main() main()