From 84814d7f8bff2c06b9386ab165366199d2630e51 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro <gregd@basistech.com> Date: Mon, 28 Aug 2023 21:09:56 -0400 Subject: [PATCH] beginnings of APIUpdate jar --- release_scripts/APIUpdate/.gitignore | 1 + release_scripts/APIUpdate/nbactions.xml | 55 ++++++ release_scripts/APIUpdate/pom.xml | 28 +++ .../apiupdate/APIUpdate.java | 137 +++++++++++++++ .../apiupdate/CLIProcessor.java | 166 ++++++++++++++++++ 5 files changed, 387 insertions(+) create mode 100644 release_scripts/APIUpdate/.gitignore create mode 100644 release_scripts/APIUpdate/nbactions.xml create mode 100644 release_scripts/APIUpdate/pom.xml create mode 100644 release_scripts/APIUpdate/src/main/java/org/sleuthkit/autopsy/classpathsimplication/apiupdate/APIUpdate.java create mode 100644 release_scripts/APIUpdate/src/main/java/org/sleuthkit/autopsy/classpathsimplication/apiupdate/CLIProcessor.java diff --git a/release_scripts/APIUpdate/.gitignore b/release_scripts/APIUpdate/.gitignore new file mode 100644 index 0000000000..c41cc9e35e --- /dev/null +++ b/release_scripts/APIUpdate/.gitignore @@ -0,0 +1 @@ +/target \ No newline at end of file diff --git a/release_scripts/APIUpdate/nbactions.xml b/release_scripts/APIUpdate/nbactions.xml new file mode 100644 index 0000000000..e3b484bf66 --- /dev/null +++ b/release_scripts/APIUpdate/nbactions.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8"?> +<actions> + <action> + <actionName>run</actionName> + <packagings> + <packaging>jar</packaging> + </packagings> + <goals> + <goal>process-classes</goal> + <goal>org.codehaus.mojo:exec-maven-plugin:3.1.0:exec</goal> + </goals> + <properties> + <exec.vmArgs></exec.vmArgs> + <exec.args>${exec.vmArgs} -classpath %classpath ${exec.mainClass} ${exec.appArgs}</exec.args> + <exec.appArgs>--help</exec.appArgs> + <exec.mainClass>${packageClassName}</exec.mainClass> + <exec.executable>java</exec.executable> + </properties> + </action> + <action> + <actionName>debug</actionName> + <packagings> + <packaging>jar</packaging> + </packagings> + <goals> + <goal>process-classes</goal> + <goal>org.codehaus.mojo:exec-maven-plugin:3.1.0:exec</goal> + </goals> + <properties> + <exec.vmArgs>-agentlib:jdwp=transport=dt_socket,server=n,address=${jpda.address}</exec.vmArgs> + <exec.args>${exec.vmArgs} -classpath %classpath ${exec.mainClass} ${exec.appArgs}</exec.args> + <exec.appArgs>--help</exec.appArgs> + <exec.mainClass>${packageClassName}</exec.mainClass> + <exec.executable>java</exec.executable> + <jpda.listen>true</jpda.listen> + </properties> + </action> + <action> + <actionName>profile</actionName> + <packagings> + <packaging>jar</packaging> + </packagings> + <goals> + <goal>process-classes</goal> + <goal>org.codehaus.mojo:exec-maven-plugin:3.1.0:exec</goal> + </goals> + <properties> + <exec.vmArgs></exec.vmArgs> + <exec.args>${exec.vmArgs} -classpath %classpath ${exec.mainClass} ${exec.appArgs}</exec.args> + <exec.mainClass>${packageClassName}</exec.mainClass> + <exec.executable>java</exec.executable> + <exec.appArgs>--help</exec.appArgs> + </properties> + </action> + </actions> diff --git a/release_scripts/APIUpdate/pom.xml b/release_scripts/APIUpdate/pom.xml new file mode 100644 index 0000000000..1d38e4f5e2 --- /dev/null +++ b/release_scripts/APIUpdate/pom.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.sleuthkit.autopsy.classpathsimplication</groupId> + <artifactId>APIUpdate</artifactId> + <version>1.0</version> + <packaging>jar</packaging> + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <maven.compiler.source>17</maven.compiler.source> + <maven.compiler.target>17</maven.compiler.target> + <exec.mainClass>org.sleuthkit.autopsy.classpathsimplication.apiupdate.APIUpdate</exec.mainClass> + </properties> + <dependencies> + <dependency> + <groupId>com.github.siom79.japicmp</groupId> + <artifactId>japicmp</artifactId> + <version>0.17.2</version> + </dependency> + + <dependency> + <groupId>commons-cli</groupId> + <artifactId>commons-cli</artifactId> + <version>1.5.0</version> + </dependency> + + </dependencies> +</project> \ No newline at end of file diff --git a/release_scripts/APIUpdate/src/main/java/org/sleuthkit/autopsy/classpathsimplication/apiupdate/APIUpdate.java b/release_scripts/APIUpdate/src/main/java/org/sleuthkit/autopsy/classpathsimplication/apiupdate/APIUpdate.java new file mode 100644 index 0000000000..e387fd686c --- /dev/null +++ b/release_scripts/APIUpdate/src/main/java/org/sleuthkit/autopsy/classpathsimplication/apiupdate/APIUpdate.java @@ -0,0 +1,137 @@ +/* + * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license + */ +package org.sleuthkit.autopsy.classpathsimplication.apiupdate; + +import japicmp.cmp.JApiCmpArchive; +import japicmp.cmp.JarArchiveComparator; +import japicmp.cmp.JarArchiveComparatorOptions; +import japicmp.model.JApiClass; +import java.io.File; +import java.io.FileFilter; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.text.MessageFormat; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.jar.Attributes; +import java.util.jar.Manifest; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import org.apache.commons.cli.ParseException; +import org.sleuthkit.autopsy.classpathsimplication.apiupdate.CLIProcessor.CLIArgs; + +/** + * + * @author gregd + */ +public class APIUpdate { + + public static void main(String[] args) { + args = "-c C:\\Users\\gregd\\Documents\\Source\\autopsy\\build\\cluster\\modules -p C:\\Users\\gregd\\Desktop\\prevVers -cv 4.21.0 -pv 4.20.0".split(" "); + CLIArgs cliArgs; + try { + cliArgs = CLIProcessor.parseCli(args); + if (cliArgs.isIsHelp()) { + CLIProcessor.printHelp(null); + System.exit(0); + } + } catch (ParseException ex) { + CLIProcessor.printHelp(ex); + System.exit(-1); + return; + } + + for (String commonJarFileName : getCommonJars(cliArgs.getPreviousVersPath(), cliArgs.getCurrentVersPath())) { +// getComparison( +// cliArgs.getPreviousVersion(), +// cliArgs.getCurrentVersion(), +// cliArgs.getPreviousVersPath().toPath().resolve(commonJarFileName).toFile(), +// cliArgs.getCurrentVersPath().toPath().resolve(commonJarFileName).toFile()); + try { + Set<String> pubPackages = getPublicPackages(cliArgs.getPreviousVersPath().toPath().resolve(commonJarFileName).toFile()); + System.out.println(pubPackages); + } catch (IOException ex) { + Logger.getLogger(APIUpdate.class.getName()).log(Level.SEVERE, null, ex); + } catch (IllegalStateException ex) { + Logger.getLogger(APIUpdate.class.getName()).log(Level.SEVERE, null, ex); + } + } + + } + + private static final FileFilter JAR_FILTER + = (File f) -> f.isFile() && (f.getName().toLowerCase().endsWith(".jar") || f.getName().toLowerCase().endsWith(".nbm")); + + private static List<String> getCommonJars(File prevDir, File currDir) { + Set<String> prevJars = getJars(prevDir); + Set<String> currJars = getJars(currDir); + + Set<String> commonJars = new HashSet<>(prevJars); + commonJars.retainAll(currJars); + + // TODO how to handle different + return commonJars.stream().sorted().collect(Collectors.toList()); + } + + private static Set<String> getJars(File dir) { + return Stream.of(dir.listFiles(JAR_FILTER)) + .map(f -> f.getName()) + .collect(Collectors.toSet()); + } + + private static Set<String> getPublicPackages(File jarFile) throws IOException, IllegalStateException { + ZipFile zipFile = new ZipFile(jarFile); + + Enumeration<? extends ZipEntry> entries = zipFile.entries(); + + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + if ("META-INF/MANIFEST.MF".equalsIgnoreCase(entry.getName())) { + InputStream stream = zipFile.getInputStream(entry); + Manifest manifest = new Manifest(stream); + Attributes attributes = manifest.getMainAttributes(); + String publicPackageStr = attributes.getValue("OpenIDE-Module-Public-Packages"); + if (publicPackageStr == null) { + throw new IllegalStateException(MessageFormat.format("Manifest for {0} does not have key of 'OpenIDE-Module-Public-Packages'", jarFile.getAbsolutePath())); + } else { + return Stream.of(publicPackageStr.split(",")) + .map(String::trim) + .map(str -> str.endsWith(".*") ? str.substring(0, str.length() - 2) : str) + .collect(Collectors.toSet()); + } + } + } + + throw new FileNotFoundException("Could not find MANIFEST.MF in " + jarFile.getAbsolutePath()); + } + + private static void getComparison(String prevVersion, String curVersion, File prevJar, File curJar) { + JarArchiveComparatorOptions comparatorOptions = new JarArchiveComparatorOptions(); + comparatorOptions.getIgnoreMissingClasses().setIgnoreAllMissingClasses(true); + JarArchiveComparator jarArchiveComparator = new JarArchiveComparator(comparatorOptions); + List<JApiClass> jApiClasses = jarArchiveComparator.compare( + new JApiCmpArchive(prevJar, prevVersion), + new JApiCmpArchive(curJar, curVersion) + ); + System.out.println("Comparing " + prevJar.getName()); + System.out.println(jApiClasses); + } + + private static void mainRun() { + + // get public API diff's, for each jar + // limit to public packages + // one of the following: + // generate text output of difference + // update version numbers in manifest file/references accordingly + } + +} diff --git a/release_scripts/APIUpdate/src/main/java/org/sleuthkit/autopsy/classpathsimplication/apiupdate/CLIProcessor.java b/release_scripts/APIUpdate/src/main/java/org/sleuthkit/autopsy/classpathsimplication/apiupdate/CLIProcessor.java new file mode 100644 index 0000000000..0ac99e73ed --- /dev/null +++ b/release_scripts/APIUpdate/src/main/java/org/sleuthkit/autopsy/classpathsimplication/apiupdate/CLIProcessor.java @@ -0,0 +1,166 @@ +/* + * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license + * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template + */ +package org.sleuthkit.autopsy.classpathsimplication.apiupdate; + +import java.io.File; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; + +/** + * + * @author gregd + */ +public class CLIProcessor { + + static Option PREV_VERS_PATH_OPT = Option.builder() + .argName("path") + .desc("The path to the previous version jar files") + .hasArg(true) + .longOpt("prev-path") + .option("p") + .required(true) + .build(); + + static Option CUR_VERS_PATH_OPT = Option.builder() + .argName("path") + .desc("The path to the current version jar files") + .hasArg(true) + .longOpt("curr-path") + .option("c") + .required(true) + .build(); + + static Option PREV_VERS_OPT = Option.builder() + .argName("version") + .desc("The previous version number") + .hasArg(true) + .longOpt("prev-version") + .option("pv") + .required(true) + .build(); + + static Option CUR_VERS_OPT = Option.builder() + .argName("version") + .desc("The current version number") + .hasArg(true) + .longOpt("curr-version") + .option("cv") + .required(true) + .build(); + + static List<Option> ALL_OPTIONS = Arrays.asList( + PREV_VERS_PATH_OPT, + CUR_VERS_PATH_OPT, + PREV_VERS_OPT, + CUR_VERS_OPT + ); + + static Options CLI_OPTIONS = getCliOptions(ALL_OPTIONS); + + private static Options getCliOptions(List<Option> opts) { + Options toRet = new Options(); + for (Option opt : opts) { + toRet.addOption(opt); + } + + return toRet; + } + + static Option HELP_OPT = Option.builder() + .desc("Print help message") + .hasArg(false) + .longOpt("help") + .option("h") + .required(false) + .build(); + + static Options HELP_OPTIONS = getCliOptions(Collections.singletonList(HELP_OPT)); + + private static CommandLineParser parser = new DefaultParser(); + + + private static HelpFormatter helpFormatter = new HelpFormatter(); + + static void printHelp(Exception ex) { + if (ex != null && ex.getMessage() != null && !ex.getMessage().isBlank()) { + System.out.println(ex.getMessage()); + } + + helpFormatter.printHelp("APIUpdate", CLI_OPTIONS); + } + + static CLIArgs parseCli(String[] args) throws ParseException { + CommandLine helpCmd = parser.parse(HELP_OPTIONS, args, true); + boolean isHelp = helpCmd.hasOption(HELP_OPT); + if (isHelp) { + return new CLIArgs(null, null, null, null, true); + } + + CommandLine cmd = parser.parse(CLI_OPTIONS, args); + String curVers = cmd.getOptionValue(CUR_VERS_OPT); + String prevVers = cmd.getOptionValue(PREV_VERS_OPT); + String curVersPath = cmd.getOptionValue(CUR_VERS_PATH_OPT); + String prevVersPath = cmd.getOptionValue(PREV_VERS_PATH_OPT); + File curVersFile = new File(curVersPath); + File prevVersFile = new File(prevVersPath); + + if (!curVersFile.isDirectory()) { + throw new ParseException("No directory found at " + curVersFile.getAbsolutePath()); + } + + if (!prevVersFile.isDirectory()) { + throw new ParseException("No directory found at " + prevVersFile.getAbsolutePath()); + } + + return new CLIArgs(curVers, prevVers, curVersFile, prevVersFile, false); + } + + + public static class CLIArgs { + + private final String currentVersion; + private final String previousVersion; + private final File currentVersPath; + private final File previousVersPath; + private final boolean isHelp; + + public String getCurrentVersion() { + return currentVersion; + } + + public String getPreviousVersion() { + return previousVersion; + } + + public File getCurrentVersPath() { + return currentVersPath; + } + + public File getPreviousVersPath() { + return previousVersPath; + } + + public boolean isIsHelp() { + return isHelp; + } + + public CLIArgs(String currentVersion, String previousVersion, File currentVersPath, File previousVersPath, boolean isHelp) { + this.currentVersion = currentVersion; + this.previousVersion = previousVersion; + this.currentVersPath = currentVersPath; + this.previousVersPath = previousVersPath; + this.isHelp = isHelp; + } + + } +} -- GitLab