Skip to content

Instantly share code, notes, and snippets.

@fzakaria
Created March 14, 2025 20:43
Show Gist options
  • Save fzakaria/0ac000eb10258a30b28c07501ec8d40b to your computer and use it in GitHub Desktop.
Save fzakaria/0ac000eb10258a30b28c07501ec8d40b to your computer and use it in GitHub Desktop.
Generate a .classpath from a text file
import sys
import os
from xml.etree import ElementTree as ET
from xml.dom import minidom
# Usage: python gen_classpath.py jars.txt /path/to/bazel/workspace
def find_binary_jar(source_jar):
"""Replace '-sources.jar' or '-src.jar' with '.jar' or 'lib' prefix if necessary"""
dir_name, file_name = os.path.split(source_jar)
if file_name.endswith('-sources.jar'):
base = file_name.replace('-sources.jar', '.jar')
processed_base = os.path.join(dir_name, 'processed_' + base)
if os.path.exists(processed_base):
return processed_base
return os.path.join(dir_name, base)
elif file_name.endswith('-src.jar'):
base = file_name.replace('-src.jar', '.jar')
lib_base = os.path.join(dir_name, 'lib' + base)
if os.path.exists(lib_base):
return lib_base
return os.path.join(dir_name, base)
return None
def generate_classpath_entries(jar_list, workspace_root):
classpath_entries = set()
handled_jars = set()
for jar in jar_list:
jar = jar.strip()
if jar in handled_jars:
continue
if jar.endswith('-sources.jar') or jar.endswith('-src.jar'):
binary_jar = find_binary_jar(jar)
if binary_jar and os.path.exists(os.path.join(workspace_root, binary_jar)):
entry_path = os.path.abspath(os.path.join(workspace_root, binary_jar))
classpath_entries.add(entry_path)
handled_jars.add(binary_jar)
handled_jars.add(jar)
elif jar.endswith('.jar'):
entry_path = os.path.abspath(os.path.join(workspace_root, jar))
if entry_path not in handled_jars:
classpath_entries.add(entry_path)
handled_jars.add(jar)
return sorted(classpath_entries)
def create_classpath_xml(entries):
classpath = ET.Element('classpath')
# Add fixed JRE and src entries
ET.SubElement(classpath, 'classpathentry', kind="con", path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21")
ET.SubElement(classpath, 'classpathentry', kind="src", path="core/src/main/resources")
ET.SubElement(classpath, 'classpathentry', kind="src", path="core/src/main/java")
for entry in entries:
ET.SubElement(classpath, 'classpathentry', kind="lib", path=entry)
ET.SubElement(classpath, 'classpathentry', kind="output", path="builds")
rough_string = ET.tostring(classpath, encoding='utf-8')
reparsed = minidom.parseString(rough_string)
return reparsed.toprettyxml(indent=" ", encoding='utf-8').decode('utf-8')
if __name__ == '__main__':
if len(sys.argv) != 3:
print(f"Usage: python {sys.argv[0]} jars.txt /path/to/bazel/workspace")
sys.exit(1)
jars_txt = sys.argv[1]
workspace_root = sys.argv[2]
with open(jars_txt, 'r') as f:
jar_list = f.readlines()
classpath_entries = generate_classpath_entries(jar_list, workspace_root)
xml_output = create_classpath_xml(classpath_entries)
print(xml_output)
@fzakaria
Copy link
Author

fzakaria commented Mar 27, 2025

Restricting myself to //core to start

bazel cquery 'deps(//core) intersect @maven//:all' --output=files > jars.txt
bazel cquery 'kind("java_library", deps(//core) intersect //...)' --output=files >> jars.txt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment