mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-01-09 14:08:03 -05:00
Merge remote-tracking branch
'origin/GP-5819-dragonmacher-help-build-update--SQUASHED' (Closes #8320)
This commit is contained in:
@@ -123,7 +123,7 @@ task buildJavacc {
|
||||
description = " Compiles the JavaCC files\n"
|
||||
}
|
||||
|
||||
// Note: this must happen before the standard buildHelp for Base
|
||||
// Note: this must happen before the standard buildModuleHelp for Base
|
||||
tasks.register('generateExtraHelpFiles') {
|
||||
|
||||
group = 'private'
|
||||
@@ -193,7 +193,7 @@ def createTipsHelpFile(input, output) {
|
||||
compileJava.dependsOn buildJavacc
|
||||
rootProject.prepDev.dependsOn buildJavacc
|
||||
|
||||
// 'indexHelp' is defined in the buildHelp.gradle 'script plugin'
|
||||
// 'indexHelp' is defined in the helpProject.gradle 'script plugin'
|
||||
indexHelp.dependsOn generateExtraHelpFiles
|
||||
|
||||
zipSourceSubproject.dependsOn buildCPPParser
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
<tocroot>
|
||||
<tocref id="Ghidra Functionality">
|
||||
<tocref id="Scripting">
|
||||
<tocdef id="Jython Interpreter" sortgroup="z" text="Jython Interpreter" target="help/topics/Jython/interpreter.html" />
|
||||
|
||||
<!-- The sort group places this entry at the bottom of all other entries in the Program
|
||||
Annotation section. 'z' puts it at the end. The rest makes it unique. -->
|
||||
<tocdef id="Jython Interpreter" sortgroup="z_Python_Jython" text="Jython Interpreter" target="help/topics/Jython/interpreter.html" />
|
||||
</tocref>
|
||||
</tocref>
|
||||
</tocroot>
|
||||
|
||||
@@ -50,7 +50,10 @@
|
||||
|
||||
<tocroot>
|
||||
<tocref id="Program Annotation">
|
||||
<tocdef id="PDB" sortgroup="s" text="PDB" target="help/topics/Pdb/PDB.htm" >
|
||||
|
||||
<!-- The sort group places this entry at the bottom of all other entries in the Program
|
||||
Annotation section. 'z' puts it at the end. The rest makes it unique. -->
|
||||
<tocdef id="PDB" sortgroup="z_PDB" text="PDB" target="help/topics/Pdb/PDB.htm" >
|
||||
<tocdef id="LoadPDB" sortgroup="a" text="Load PDB File" target="help/topics/Pdb/LoadPDB.html" />
|
||||
<tocdef id="README_PDB" sortgroup="b" text="PDB Parser (README_PDB)" target="external:docs/README_PDB.html" />
|
||||
</tocdef>
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
<tocroot>
|
||||
<tocref id="Ghidra Functionality">
|
||||
<tocref id="Scripting">
|
||||
<tocdef id="PyGhidra Interpreter" sortgroup="z" text="PyGhidra Interpreter" target="help/topics/PyGhidra/interpreter.html" />
|
||||
|
||||
<!-- The sort group places this entry at the bottom of all other entries in the Program
|
||||
Annotation section. 'z' puts it at the end. The rest makes it unique. -->
|
||||
<tocdef id="PyGhidra Interpreter" sortgroup="z_Python_PyGhidra" text="PyGhidra Interpreter" target="help/topics/PyGhidra/interpreter.html" />
|
||||
</tocref>
|
||||
</tocref>
|
||||
</tocroot>
|
||||
|
||||
@@ -50,7 +50,10 @@
|
||||
|
||||
<tocroot>
|
||||
<tocref id="Program Annotation">
|
||||
<tocdef id="SARIF" sortgroup="s" text="SARIF" target="help/topics/Sarif/SARIF.htm" >
|
||||
|
||||
<!-- The sort group places this entry at the bottom of all other entries in the Program
|
||||
Annotation section. 'z' puts it at the end. The rest makes it unique. -->
|
||||
<tocdef id="SARIF" sortgroup="z_Sarif" text="SARIF" target="help/topics/Sarif/SARIF.htm" >
|
||||
</tocdef>
|
||||
</tocref>
|
||||
</tocroot>
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -31,3 +31,85 @@ dependencies {
|
||||
//api name:'jh2.with.debug'
|
||||
api 'javax.help:javahelp:2.0.05'
|
||||
}
|
||||
|
||||
/*
|
||||
* Get all help tasks from all projects
|
||||
*/
|
||||
def getAllHelpTasks() {
|
||||
|
||||
List list = new ArrayList()
|
||||
rootProject.allprojects {
|
||||
tasks.each {
|
||||
if (it.name == 'buildModuleHelp') {
|
||||
list.add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
/*
|
||||
* A task at the Ghidra tool top-level build that will trigger all 'buildModuleHelp' tasks to run,
|
||||
* this building help. Additionally, this task will perform any needed validation after all help
|
||||
* modules are built.
|
||||
*/
|
||||
tasks.register('buildHelp') {
|
||||
|
||||
description 'Build all Ghidra help'
|
||||
|
||||
dependsOn { getAllHelpTasks() } // all 'buildHelpModule' tasks
|
||||
dependsOn 'validateHelpTocFiles' // the validate TOC task to run after all help is built
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Gathers all generated help TOC files and validates them.
|
||||
*/
|
||||
tasks.register('validateHelpTocFiles', JavaExec) {
|
||||
|
||||
group = "private"
|
||||
|
||||
dependsOn { getAllHelpTasks() } // all 'buildHelpModule' tasks to provide TOC inputs
|
||||
|
||||
// we need our Help java files compiled
|
||||
dependsOn jar
|
||||
|
||||
mainClass = 'help.GHelpTocValidator'
|
||||
|
||||
// to allow remote debugging of the help build jvm
|
||||
// jvmArgs '-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=13001'
|
||||
|
||||
// print debug info
|
||||
// args '-debug'
|
||||
|
||||
doFirst {
|
||||
|
||||
// get the Help module jar file, since it has classes we use
|
||||
classpath += jar.outputs.files
|
||||
|
||||
// get the classpath items used by the Help module, since we use those classes
|
||||
classpath += configurations.runtimeClasspath
|
||||
|
||||
// add each Module-help.jar file created by 'buildModuleHelp' to the application inputs
|
||||
rootProject.allprojects.forEach {
|
||||
|
||||
// <module>/build/libs/Module-help.jar
|
||||
def helpLibDir = it.file('build/libs')
|
||||
if (helpLibDir.isDirectory()) {
|
||||
|
||||
helpLibDir.listFiles().each {
|
||||
String name = it.getName()
|
||||
if (name.endsWith('-help.jar')) {
|
||||
args "${it.absolutePath}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Sigal that any System.out messages from this Java process should be logged at INFO level.
|
||||
// To see this output, run gradle with the '-i' option to show INFO messages.
|
||||
logging.captureStandardOutput LogLevel.INFO
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package help;
|
||||
|
||||
import static help.GHelpMsg.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
@@ -96,7 +98,7 @@ public class GHelpBuilder {
|
||||
if (results.failed()) {
|
||||
String message = "Found invalid help:\n" + results.getMessage();
|
||||
if (ignoreInvalid) {
|
||||
printErrorMessage(message);
|
||||
error(message);
|
||||
}
|
||||
else {
|
||||
exitWithError(message, null);
|
||||
@@ -267,15 +269,6 @@ public class GHelpBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
private static void flush() {
|
||||
System.out.flush();
|
||||
System.out.println();
|
||||
System.out.flush();
|
||||
System.err.flush();
|
||||
System.err.println();
|
||||
System.err.flush();
|
||||
}
|
||||
|
||||
private static void debug(String string) {
|
||||
if (debugEnabled) {
|
||||
flush();
|
||||
@@ -290,7 +283,7 @@ public class GHelpBuilder {
|
||||
if (opt.equals(OUTPUT_DIRECTORY_OPTION)) {
|
||||
i++;
|
||||
if (i >= args.length) {
|
||||
errorMessage(OUTPUT_DIRECTORY_OPTION + " requires an argument");
|
||||
error(OUTPUT_DIRECTORY_OPTION + " requires an argument");
|
||||
printUsage();
|
||||
System.exit(1);
|
||||
}
|
||||
@@ -299,7 +292,7 @@ public class GHelpBuilder {
|
||||
else if (opt.equals(MODULE_NAME_OPTION)) {
|
||||
i++;
|
||||
if (i >= args.length) {
|
||||
errorMessage(MODULE_NAME_OPTION + " requires an argument");
|
||||
error(MODULE_NAME_OPTION + " requires an argument");
|
||||
printUsage();
|
||||
System.exit(1);
|
||||
}
|
||||
@@ -308,7 +301,7 @@ public class GHelpBuilder {
|
||||
else if (opt.equals(HELP_PATHS_OPTION)) {
|
||||
i++;
|
||||
if (i >= args.length) {
|
||||
errorMessage(HELP_PATHS_OPTION + " requires an argument");
|
||||
error(HELP_PATHS_OPTION + " requires an argument");
|
||||
printUsage();
|
||||
System.exit(1);
|
||||
}
|
||||
@@ -322,7 +315,7 @@ public class GHelpBuilder {
|
||||
else if (opt.equals(HELP_PATHS_GENERATED_OPTION)) {
|
||||
i++;
|
||||
if (i >= args.length) {
|
||||
errorMessage(HELP_PATHS_GENERATED_OPTION + " requires an argument");
|
||||
error(HELP_PATHS_GENERATED_OPTION + " requires an argument");
|
||||
printUsage();
|
||||
System.exit(1);
|
||||
}
|
||||
@@ -340,7 +333,7 @@ public class GHelpBuilder {
|
||||
ignoreInvalid = true;
|
||||
}
|
||||
else if (opt.startsWith("-")) {
|
||||
errorMessage("Unknown option " + opt);
|
||||
error("Unknown option " + opt);
|
||||
printUsage();
|
||||
System.exit(1);
|
||||
}
|
||||
@@ -353,17 +346,17 @@ public class GHelpBuilder {
|
||||
HelpBuildUtils.debug = debugEnabled;
|
||||
|
||||
if (helpInputDirectories.size() == 0) {
|
||||
errorMessage("Must specify at least one input directory");
|
||||
error("Must specify at least one input directory");
|
||||
printUsage();
|
||||
System.exit(1);
|
||||
}
|
||||
if (outputDirectoryName == null) {
|
||||
errorMessage("Missing output directory: " + OUTPUT_DIRECTORY_OPTION + " [output]");
|
||||
error("Missing output directory: " + OUTPUT_DIRECTORY_OPTION + " [output]");
|
||||
printUsage();
|
||||
System.exit(1);
|
||||
}
|
||||
if (moduleName == null) {
|
||||
errorMessage("Missing module name: " + MODULE_NAME_OPTION + " [name]");
|
||||
error("Missing module name: " + MODULE_NAME_OPTION + " [name]");
|
||||
printUsage();
|
||||
System.exit(1);
|
||||
}
|
||||
@@ -385,35 +378,7 @@ public class GHelpBuilder {
|
||||
buffy.append(" ").append(IGNORE_INVALID_SWITCH).append("\n");
|
||||
buffy.append(" to continue despite broken links and anchors\n");
|
||||
|
||||
errorMessage(buffy.toString());
|
||||
}
|
||||
|
||||
private static void printErrorMessage(String message) {
|
||||
// this prevents error messages getting interspersed with output messages
|
||||
flush();
|
||||
errorMessage(message);
|
||||
}
|
||||
|
||||
private static void errorMessage(String message) {
|
||||
errorMessage(message, null);
|
||||
}
|
||||
|
||||
private static void errorMessage(String message, Throwable t) {
|
||||
try {
|
||||
// give the output thread a chance to finish it's output (this is a workaround for
|
||||
// the Eclipse editor, and its use of two threads in its console).
|
||||
Thread.sleep(250);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
// don't care; we tried
|
||||
}
|
||||
|
||||
System.err.println("[" + GHelpBuilder.class.getSimpleName() + "] " + message);
|
||||
if (t != null) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
|
||||
flush();
|
||||
error(buffy.toString());
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
62
Ghidra/Framework/Help/src/main/java/help/GHelpMsg.java
Normal file
62
Ghidra/Framework/Help/src/main/java/help/GHelpMsg.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package help;
|
||||
|
||||
import utilities.util.reflection.ReflectionUtilities;
|
||||
|
||||
/**
|
||||
* Contains helpful methods for emitting messages to the console.
|
||||
*/
|
||||
public class GHelpMsg {
|
||||
|
||||
public static void error(String message) {
|
||||
error(message, null);
|
||||
}
|
||||
|
||||
public static void error(String message, Throwable t) {
|
||||
|
||||
flush();
|
||||
|
||||
try {
|
||||
// give the output thread a chance to finish it's output (this is a workaround for
|
||||
// the Eclipse editor, and its use of two threads in its console).
|
||||
Thread.sleep(250);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
// don't care; we tried
|
||||
}
|
||||
|
||||
String caller = ReflectionUtilities.getClassNameOlderThan(GHelpMsg.class);
|
||||
int index = caller.lastIndexOf('.');
|
||||
caller = caller.substring(index + 1);
|
||||
|
||||
System.err.println("[" + caller + "] " + message);
|
||||
if (t != null) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
|
||||
flush();
|
||||
}
|
||||
|
||||
public static void flush() {
|
||||
System.out.flush();
|
||||
System.out.println();
|
||||
System.out.flush();
|
||||
System.err.flush();
|
||||
System.err.println();
|
||||
System.err.flush();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package help;
|
||||
|
||||
import static help.GHelpMsg.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
import generic.application.GenericApplicationLayout;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.ApplicationConfiguration;
|
||||
import help.validator.LinkDatabase;
|
||||
import help.validator.location.HelpModuleCollection;
|
||||
|
||||
/**
|
||||
* Checks for errors in source TOC files, such as conflicting sort groups. This validator is meant
|
||||
* to be used when all system TOC files have been built. Individual module TOC files are validated
|
||||
* for correctness with their dependencies when they are built. This class is needed to validate
|
||||
* all TOC files, including for leaf modules that don't have each other as dependencies.
|
||||
*/
|
||||
public class GHelpTocValidator {
|
||||
|
||||
private static final String DEBUG_SWITCH = "-debug";
|
||||
|
||||
private Collection<File> helpInputDirectories = new LinkedHashSet<>();
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
GHelpTocValidator validator = new GHelpTocValidator();
|
||||
|
||||
ApplicationConfiguration config = new ApplicationConfiguration();
|
||||
Application.initializeApplication(new GenericApplicationLayout("Help TOC Validator", "0.1"),
|
||||
config);
|
||||
|
||||
validator.validate(args);
|
||||
}
|
||||
|
||||
private void validate(String[] args) {
|
||||
|
||||
parseArguments(args);
|
||||
|
||||
List<File> allHelp = new ArrayList<>(helpInputDirectories);
|
||||
HelpModuleCollection help = HelpModuleCollection.fromFiles(allHelp);
|
||||
LinkDatabase linkDatabase = new LinkDatabase(help);
|
||||
linkDatabase.validateAllTOCs();
|
||||
}
|
||||
|
||||
private void parseArguments(String[] args) {
|
||||
|
||||
boolean debugEnabled = false;
|
||||
for (String opt : args) {
|
||||
if (opt.equals(DEBUG_SWITCH)) {
|
||||
debugEnabled = true;
|
||||
}
|
||||
else if (opt.startsWith("-")) {
|
||||
error("Unknown option " + opt);
|
||||
System.exit(1);
|
||||
}
|
||||
else {
|
||||
// It must just be an input
|
||||
helpInputDirectories.add(new File(opt));
|
||||
}
|
||||
}
|
||||
|
||||
HelpBuildUtils.debug = debugEnabled;
|
||||
|
||||
if (helpInputDirectories.size() == 0) {
|
||||
error("Must specify at least one help jar file");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -428,10 +428,10 @@ public class HelpBuildUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static final Path DEFAULT_FS_ROOT;
|
||||
private static final Path DEFAULT_ROOT_DIR;
|
||||
static {
|
||||
try {
|
||||
DEFAULT_FS_ROOT = Paths.get(".").toRealPath().getRoot();
|
||||
DEFAULT_ROOT_DIR = Paths.get(".").toRealPath().getRoot();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(
|
||||
@@ -439,7 +439,7 @@ public class HelpBuildUtils {
|
||||
}
|
||||
}
|
||||
|
||||
private static Path toFSGivenRoot(Path root, Path path) {
|
||||
private static Path relativeToRoot(Path root, Path path) {
|
||||
if (path.getNameCount() == 0) {
|
||||
if (path.isAbsolute()) {
|
||||
return root;
|
||||
@@ -459,12 +459,12 @@ public class HelpBuildUtils {
|
||||
return temp;
|
||||
}
|
||||
|
||||
public static Path toDefaultFS(Path path) {
|
||||
return toFSGivenRoot(DEFAULT_FS_ROOT, path);
|
||||
public static Path relativeToWorkingDir(Path path) {
|
||||
return relativeToRoot(DEFAULT_ROOT_DIR, path);
|
||||
}
|
||||
|
||||
public static Path toFS(Path targetFS, Path path) {
|
||||
return toFSGivenRoot(targetFS.toAbsolutePath().getRoot(), path);
|
||||
public static Path relativeTo(Path targetFS, Path path) {
|
||||
return relativeToRoot(targetFS.toAbsolutePath().getRoot(), path);
|
||||
}
|
||||
|
||||
public static Path createReferencePath(URI fileURI) {
|
||||
|
||||
@@ -17,7 +17,8 @@ package help;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.*;
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
||||
import ghidra.util.exception.AssertException;
|
||||
import help.validator.LinkDatabase;
|
||||
@@ -135,9 +136,7 @@ public class JavaHelpFilesBuilder {
|
||||
out.println("<map version=\"1.0\">");
|
||||
|
||||
Collection<AnchorDefinition> anchors = help.getAllAnchorDefinitions();
|
||||
Iterator<AnchorDefinition> iterator = anchors.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
AnchorDefinition a = iterator.next();
|
||||
for (AnchorDefinition a : anchors) {
|
||||
String anchorTarget = a.getHelpPath();
|
||||
|
||||
//
|
||||
|
||||
@@ -52,6 +52,7 @@ public class OverlayHelpTree {
|
||||
}
|
||||
|
||||
private void addExternalTOCItem(TOCItem item) {
|
||||
|
||||
TOCItem parent = item.getParent();
|
||||
String parentID = parent == null ? null : parent.getIDAttribute();
|
||||
if (parentID == null) {
|
||||
@@ -129,6 +130,20 @@ public class OverlayHelpTree {
|
||||
// printTreeForID(writer, sourceFileID);
|
||||
}
|
||||
|
||||
public void validateAllTOCs() {
|
||||
|
||||
initializeTree();
|
||||
doValidateAllTOCs(rootNode);
|
||||
}
|
||||
|
||||
private void doValidateAllTOCs(OverlayNode node) {
|
||||
node.validateChildrenSortGroups();
|
||||
Set<OverlayNode> children = node.children;
|
||||
for (OverlayNode child : children) {
|
||||
doValidateAllTOCs(child);
|
||||
}
|
||||
}
|
||||
|
||||
void printTreeForID(PrintWriter writer, String sourceFileID) {
|
||||
initializeTree();
|
||||
|
||||
@@ -149,7 +164,7 @@ public class OverlayHelpTree {
|
||||
|
||||
private void printContents(String sourceFileID, PrintWriter writer) {
|
||||
if (rootNode == null) {
|
||||
// assume not TOC contents; empty TOC file
|
||||
// assume no TOC contents; empty TOC file
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -185,6 +200,7 @@ public class OverlayHelpTree {
|
||||
}
|
||||
|
||||
private void buildChildren(OverlayNode node) {
|
||||
|
||||
String definitionID = node.getDefinitionID();
|
||||
Set<TOCItem> children = parentToChildrenMap.remove(definitionID);
|
||||
if (children == null) {
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -16,12 +15,12 @@
|
||||
*/
|
||||
package help.validator;
|
||||
|
||||
import help.validator.model.AnchorDefinition;
|
||||
import help.validator.model.HelpTopic;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
import help.validator.model.AnchorDefinition;
|
||||
import help.validator.model.HelpTopic;
|
||||
|
||||
public class DuplicateAnchorCollectionByHelpTopic implements DuplicateAnchorCollection,
|
||||
Comparable<DuplicateAnchorCollectionByHelpTopic> {
|
||||
|
||||
@@ -35,7 +34,7 @@ public class DuplicateAnchorCollectionByHelpTopic implements DuplicateAnchorColl
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Duplicate anchors for topic\n\ttopic file: " + topic.getTopicFile() + "\n" +
|
||||
return "Duplicate anchors for topic\n\ttopic dir: " + topic.getTopicDir() + "\n" +
|
||||
getAnchorsAsString();
|
||||
}
|
||||
|
||||
@@ -49,8 +48,8 @@ public class DuplicateAnchorCollectionByHelpTopic implements DuplicateAnchorColl
|
||||
|
||||
@Override
|
||||
public int compareTo(DuplicateAnchorCollectionByHelpTopic o) {
|
||||
Path topicFile1 = topic.getTopicFile();
|
||||
Path topicFile2 = o.topic.getTopicFile();
|
||||
return topicFile1.compareTo(topicFile2);
|
||||
Path topicDir1 = topic.getTopicDir();
|
||||
Path topicDir2 = o.topic.getTopicDir();
|
||||
return topicDir1.compareTo(topicDir2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ public class JavaHelpValidator {
|
||||
Path dirPath = Paths.get(dir.getAbsolutePath());
|
||||
Path imagePath = Paths.get(imgSrc);
|
||||
|
||||
Path imageFileFS = HelpBuildUtils.toFS(dirPath, imagePath);
|
||||
Path imageFileFS = HelpBuildUtils.relativeTo(dirPath, imagePath);
|
||||
Path toCheck = dirPath.resolve(imageFileFS);
|
||||
if (Files.exists(toCheck)) {
|
||||
return toCheck;
|
||||
@@ -214,7 +214,7 @@ public class JavaHelpValidator {
|
||||
|
||||
private Path makePath(Path helpDir, Path imagePath) {
|
||||
|
||||
Path imageFileFS = HelpBuildUtils.toFS(helpDir, imagePath);
|
||||
Path imageFileFS = HelpBuildUtils.relativeTo(helpDir, imagePath);
|
||||
imageFileFS = removeRedundantHelp(helpDir, imageFileFS);
|
||||
Path toCheck = helpDir.resolve(imageFileFS);
|
||||
if (Files.exists(toCheck)) {
|
||||
|
||||
@@ -204,4 +204,8 @@ public class LinkDatabase {
|
||||
public void generateTOCOutputFile(Path outputFile, GhidraTOCFile file) throws IOException {
|
||||
printableTree.printTreeForID(outputFile, file.getFile().toUri().toString());
|
||||
}
|
||||
|
||||
public void validateAllTOCs() {
|
||||
printableTree.validateAllTOCs();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +124,10 @@ public class HelpModuleCollection implements TOCItemProvider {
|
||||
}
|
||||
|
||||
public GhidraTOCFile getSourceTOCFile() {
|
||||
if (inputHelp == null) {
|
||||
// this collection of help modules is only external inputs (e.g., jar files)
|
||||
return null;
|
||||
}
|
||||
return inputHelp.getSourceTOCFile();
|
||||
}
|
||||
|
||||
@@ -258,6 +262,11 @@ public class HelpModuleCollection implements TOCItemProvider {
|
||||
|
||||
@Override
|
||||
public Map<String, TOCItemDefinition> getTocDefinitionsByID() {
|
||||
if (inputHelp == null) {
|
||||
// this collection of help modules is only external inputs (e.g., jar files)
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
Map<String, TOCItemDefinition> map = new HashMap<>();
|
||||
GhidraTOCFile TOC = inputHelp.getSourceTOCFile();
|
||||
map.putAll(TOC.getTOCDefinitionByIDMapping());
|
||||
@@ -267,7 +276,6 @@ public class HelpModuleCollection implements TOCItemProvider {
|
||||
@Override
|
||||
public Map<String, TOCItemExternal> getExternalTocItemsById() {
|
||||
Map<String, TOCItemExternal> map = new HashMap<>();
|
||||
|
||||
if (externalHelpSets.isEmpty()) {
|
||||
return map;
|
||||
}
|
||||
@@ -325,6 +333,11 @@ public class HelpModuleCollection implements TOCItemProvider {
|
||||
* @return the items
|
||||
*/
|
||||
public Collection<TOCItem> getInputTOCItems() {
|
||||
if (inputHelp == null) {
|
||||
// this collection of help modules is only external inputs (e.g., jar files)
|
||||
return List.of();
|
||||
}
|
||||
|
||||
Collection<TOCItem> items = new ArrayList<>();
|
||||
GhidraTOCFile TOC = inputHelp.getSourceTOCFile();
|
||||
items.addAll(TOC.getAllTOCItems());
|
||||
@@ -332,6 +345,11 @@ public class HelpModuleCollection implements TOCItemProvider {
|
||||
}
|
||||
|
||||
public Collection<HREF> getTOC_HREFs() {
|
||||
if (inputHelp == null) {
|
||||
// this collection of help modules is only external inputs (e.g., jar files)
|
||||
return List.of();
|
||||
}
|
||||
|
||||
Collection<HREF> definitions = new ArrayList<>();
|
||||
GhidraTOCFile TOC = inputHelp.getSourceTOCFile();
|
||||
definitions.addAll(getTOC_HREFs(TOC));
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -17,17 +17,11 @@ package help.validator.model;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.util.exception.AssertException;
|
||||
import help.HelpBuildUtils;
|
||||
import help.PathKey;
|
||||
import help.validator.AnchorManager;
|
||||
import help.validator.HTMLFileParser;
|
||||
import help.validator.ReferenceTagProcessor;
|
||||
import help.validator.TagProcessor;
|
||||
import help.*;
|
||||
import help.validator.*;
|
||||
import help.validator.location.HelpModuleLocation;
|
||||
|
||||
public class HelpFile {
|
||||
@@ -80,7 +74,7 @@ public class HelpFile {
|
||||
return anchorManager.getDuplicateAnchorsByID();
|
||||
}
|
||||
|
||||
public AnchorDefinition getAnchorDefinition(Path helpPath) {
|
||||
public AnchorDefinition getAnchorDefinition(Path helpPath) {
|
||||
Map<PathKey, AnchorDefinition> anchorsByHelpPath = anchorManager.getAnchorsByHelpPath();
|
||||
AnchorDefinition def = anchorsByHelpPath.get(new PathKey(helpPath));
|
||||
return def;
|
||||
@@ -124,9 +118,9 @@ public class HelpFile {
|
||||
HTMLFileParser.scanHtmlFile(file, tagProcessor);
|
||||
}
|
||||
catch (IOException e) {
|
||||
System.err.println("Exception parsing file: " + file.toUri() + "\n");
|
||||
System.err.println(e.getMessage());
|
||||
e.printStackTrace();
|
||||
String msg =
|
||||
"Exception parsing file: %s\n%s".formatted(file.toUri(), e.getMessage());
|
||||
GHelpMsg.error(msg, e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -20,16 +20,19 @@ import java.nio.file.*;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.*;
|
||||
|
||||
import help.GHelpMsg;
|
||||
import help.HelpBuildUtils;
|
||||
import help.validator.location.DirectoryHelpModuleLocation;
|
||||
import help.validator.location.HelpModuleLocation;
|
||||
|
||||
public class HelpTopic implements Comparable<HelpTopic> {
|
||||
private final HelpModuleLocation help;
|
||||
private final Path topicFile;
|
||||
private final Path topicDir;
|
||||
|
||||
// topics/TopicName
|
||||
private final Path relativePath;
|
||||
|
||||
private Map<Path, HelpFile> helpFiles = new LinkedHashMap<>();
|
||||
private Map<Path, HelpFile> helpFiles;
|
||||
|
||||
public static HelpTopic fromHTMLFile(Path topicFile) {
|
||||
|
||||
@@ -44,65 +47,80 @@ public class HelpTopic implements Comparable<HelpTopic> {
|
||||
return helpTopic;
|
||||
}
|
||||
|
||||
public HelpTopic(HelpModuleLocation help, Path topicFile) {
|
||||
public HelpTopic(HelpModuleLocation help, Path topicDir) {
|
||||
this.help = help;
|
||||
this.topicFile = topicFile;
|
||||
this.topicDir = topicDir;
|
||||
|
||||
Path helpDir = help.getHelpLocation();
|
||||
|
||||
Path unknownFSRelativePath = helpDir.relativize(topicFile); // may or may not be jar paths
|
||||
this.relativePath = HelpBuildUtils.toDefaultFS(unknownFSRelativePath);
|
||||
|
||||
loadHelpFiles(topicFile);
|
||||
// topic file: /help/topics/TopicName
|
||||
// relative: topics/TopicName
|
||||
Path relativeTopicPath = helpDir.relativize(topicDir); // may or may not be jar paths
|
||||
this.relativePath = HelpBuildUtils.relativeToWorkingDir(relativeTopicPath);
|
||||
}
|
||||
|
||||
public Path getTopicFile() {
|
||||
return topicFile;
|
||||
public Path getTopicDir() {
|
||||
return topicDir;
|
||||
}
|
||||
|
||||
private void loadHelpFiles(final Path dir) {
|
||||
final PathMatcher matcher =
|
||||
dir.getFileSystem().getPathMatcher("glob:**/*.{[Hh][Tt][Mm],[Hh][Tt][Mm][Ll]}");
|
||||
private void lazyLoad() {
|
||||
if (helpFiles != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ex:
|
||||
// jar: /help/topics/FooPlugin
|
||||
final Path dirDefaultFS = HelpBuildUtils.toDefaultFS(dir);
|
||||
helpFiles = new LinkedHashMap<>();
|
||||
loadHelpFiles(topicDir);
|
||||
}
|
||||
|
||||
private void loadHelpFiles(Path dir) {
|
||||
FileSystem fs = dir.getFileSystem();
|
||||
PathMatcher matcher =
|
||||
fs.getPathMatcher("glob:**/*.{[Hh][Tt][Mm],[Hh][Tt][Mm][Ll]}");
|
||||
|
||||
// Ex: /help/topics/FooPlugin
|
||||
Path dirDefaultFS = HelpBuildUtils.relativeToWorkingDir(dir);
|
||||
try {
|
||||
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
|
||||
throws IOException {
|
||||
if (matcher.matches(file)) {
|
||||
// Ex:
|
||||
// jar: /help/topics/FooPlugin/Foo.html
|
||||
Path fileDefaultFS = HelpBuildUtils.toDefaultFS(file);
|
||||
|
||||
// Ex: jar: Foo.html
|
||||
Path relFilePath = dirDefaultFS.relativize(fileDefaultFS);
|
||||
|
||||
// Ex: jar: topics/FooPlugin/Foo.html
|
||||
relFilePath = relativePath.resolve(relFilePath);
|
||||
helpFiles.put(relFilePath, new HelpFile(help, file));
|
||||
mapHelpFile(dirDefaultFS, file);
|
||||
}
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (IOException e) {
|
||||
System.err.println("Error loading help files: " + dir.toUri());
|
||||
e.printStackTrace(System.err);
|
||||
GHelpMsg.error("Error loading help files: " + dir.toUri(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void mapHelpFile(Path dirDefaultFS, Path file) {
|
||||
|
||||
// Ex: /help/topics/FooPlugin/Foo.html
|
||||
Path fileDefaultFS = HelpBuildUtils.relativeToWorkingDir(file);
|
||||
|
||||
// Ex: Foo.html
|
||||
Path relFilePath = dirDefaultFS.relativize(fileDefaultFS);
|
||||
|
||||
// Ex: topics/FooPlugin/Foo.html
|
||||
relFilePath = relativePath.resolve(relFilePath);
|
||||
helpFiles.put(relFilePath, new HelpFile(help, file));
|
||||
}
|
||||
|
||||
void addHelpFile(Path relPath, HelpFile helpFile) {
|
||||
lazyLoad();
|
||||
helpFiles.put(relPath, helpFile);
|
||||
}
|
||||
|
||||
public Collection<HREF> getAllHREFs() {
|
||||
// Don't need to validate hrefs already in a .jar
|
||||
if (topicFile.getFileSystem() != FileSystems.getDefault()) {
|
||||
if (topicDir.getFileSystem() != FileSystems.getDefault()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
lazyLoad();
|
||||
List<HREF> list = new ArrayList<>();
|
||||
for (HelpFile helpFile : helpFiles.values()) {
|
||||
list.addAll(helpFile.getAllHREFs());
|
||||
@@ -112,9 +130,11 @@ public class HelpTopic implements Comparable<HelpTopic> {
|
||||
|
||||
public Collection<IMG> getAllIMGs() {
|
||||
// Don't need to validate imgs already in a .jar
|
||||
if (topicFile.getFileSystem() != FileSystems.getDefault()) {
|
||||
if (topicDir.getFileSystem() != FileSystems.getDefault()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
lazyLoad();
|
||||
List<IMG> list = new ArrayList<>();
|
||||
for (HelpFile helpFile : helpFiles.values()) {
|
||||
list.addAll(helpFile.getAllIMGs());
|
||||
@@ -124,6 +144,7 @@ public class HelpTopic implements Comparable<HelpTopic> {
|
||||
|
||||
public Collection<AnchorDefinition> getAllAnchorDefinitions() {
|
||||
// The current module may refer to anchors in pre-built modules.
|
||||
lazyLoad();
|
||||
List<AnchorDefinition> list = new ArrayList<>();
|
||||
for (HelpFile helpFile : helpFiles.values()) {
|
||||
list.addAll(helpFile.getAllAnchorDefinitions());
|
||||
@@ -132,9 +153,14 @@ public class HelpTopic implements Comparable<HelpTopic> {
|
||||
}
|
||||
|
||||
public Collection<HelpFile> getHelpFiles() {
|
||||
lazyLoad();
|
||||
return helpFiles.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the relative path, which is {@code topics/TopicName}
|
||||
* @return the path
|
||||
*/
|
||||
Path getRelativePath() {
|
||||
return relativePath;
|
||||
}
|
||||
@@ -144,16 +170,16 @@ public class HelpTopic implements Comparable<HelpTopic> {
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return topicFile.getFileName().toString();
|
||||
return topicDir.getFileName().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(HelpTopic o) {
|
||||
return topicFile.compareTo(o.topicFile);
|
||||
return topicDir.compareTo(o.topicDir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return topicFile.toString();
|
||||
return topicDir.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -85,6 +85,7 @@ return buildy.toString();*/
|
||||
//@formatter:off
|
||||
return "<"+GhidraTOCFile.TOC_ITEM_DEFINITION +
|
||||
" id=\"" + getIDAttribute() + "\" text=\"" + getTextAttribute() + "\" " +
|
||||
"\n\t\tsortgroup=\"" + getSortPreference() + "\"" +
|
||||
"\n\t\ttarget=\"" + getTargetAttribute() + "\" />" +
|
||||
"\n\t\t[source file=\"" + getSourceFile() + "\" (line:" + getLineNumber() + ")]";
|
||||
//@formatter:on
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -16,10 +15,10 @@
|
||||
*/
|
||||
package help.validator.model;
|
||||
|
||||
import help.validator.LinkDatabase;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
import help.validator.LinkDatabase;
|
||||
|
||||
public class TOCItemExternal extends TOCItem {
|
||||
|
||||
public TOCItemExternal(TOCItem parentItem, Path tocFile, String ID, String text, String target,
|
||||
@@ -41,7 +40,8 @@ public class TOCItemExternal extends TOCItem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateTOCItemTag(LinkDatabase linkDatabase, boolean isInlineTag, int indentLevel) {
|
||||
public String generateTOCItemTag(LinkDatabase linkDatabase, boolean isInlineTag,
|
||||
int indentLevel) {
|
||||
return super.generateTOCItemTag(linkDatabase, isInlineTag, indentLevel);
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ public class TOCItemExternal extends TOCItem {
|
||||
public String toString() {
|
||||
//@formatter:off
|
||||
return "<tocitem id=\"" + getIDAttribute() + "\"\n\t\t" +
|
||||
"sort=\"" + getSortPreference() + "\"\n\t\t" +
|
||||
"text=\"" + getTextAttribute() + "\"\n\t\t" +
|
||||
"target=\"" + getTargetAttribute() + "\"" +
|
||||
"/>\n\t" +
|
||||
|
||||
@@ -363,7 +363,7 @@ tasks.register('indexHelp', JavaExec) {
|
||||
// - validates help
|
||||
// - the files generated will be placed in a diretory usable during development mode and will
|
||||
// eventually be placed in the <Module>.jar file
|
||||
tasks.register('buildHelp', JavaExec) {
|
||||
tasks.register('buildModuleHelp', JavaExec) {
|
||||
group = "Ghidra Private"
|
||||
|
||||
dependsOn 'indexHelp'
|
||||
@@ -406,7 +406,7 @@ tasks.register('buildHelp', JavaExec) {
|
||||
|
||||
//
|
||||
// The classpath needs to include:
|
||||
// 1) the jar of each dependent Module that has already been built
|
||||
// 1) the jar of each depended upon Module that has already been built
|
||||
// 2) 'src/main/resources'
|
||||
//
|
||||
|
||||
@@ -434,6 +434,12 @@ tasks.register('buildHelp', JavaExec) {
|
||||
}
|
||||
}
|
||||
|
||||
// a simple task to alias the old 'buildHelp' task to 'buildModuleHelp' so users that uses of the
|
||||
// old command will still work for end users
|
||||
tasks.register('buildHelp', JavaExec) {
|
||||
group = "Ghidra Private"
|
||||
dependsOn 'buildModuleHelp'
|
||||
}
|
||||
|
||||
|
||||
// include the help into the module's jar
|
||||
@@ -445,7 +451,7 @@ jar {
|
||||
}
|
||||
|
||||
// build the help whenever this module's jar file is built
|
||||
jar.dependsOn 'buildHelp'
|
||||
jar.dependsOn 'buildModuleHelp'
|
||||
|
||||
|
||||
/*********************************************************************************
|
||||
|
||||
@@ -197,14 +197,14 @@ def getModuleResourcesDirs(Collection<File> fullClasspath) {
|
||||
.findAll(dir -> dir.exists())
|
||||
}
|
||||
|
||||
// Locatates 'buildHelp' tasks in projects that this project depends on. The output of the tasks
|
||||
// is the module's help jar, which is only used to build help and not in the final release. The
|
||||
// jar file names follow this format: <Module>-help.jar.
|
||||
// Locates 'buildModuleHelp' tasks in projects that this project depends on. The output of the
|
||||
// tasks is the module's help jar, which is only used to build help and not in the final release.
|
||||
// The jar file names follow this format: <Module>-help.jar.
|
||||
def getDependentProjectHelpTasks(Collection<File> fullClasspath) {
|
||||
|
||||
def myModules = getMyModules(fullClasspath)
|
||||
def myProjects = filterProjectsBy(myModules)
|
||||
return myProjects.collect(p -> p.tasks.findByPath('buildHelp'))
|
||||
return myProjects.collect(p -> p.tasks.findByPath('buildModuleHelp'))
|
||||
.findAll(t -> t != null)
|
||||
}
|
||||
|
||||
@@ -313,6 +313,8 @@ tasks.register('buildGlobalMarkdown') {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Task for building Ghidra help files
|
||||
// - depends on the output from the help indexer
|
||||
// - validates help
|
||||
@@ -376,7 +378,7 @@ tasks.register('buildHelpFiles', JavaExec) {
|
||||
//
|
||||
// The classpath needs to include items used by internal Java code to validate help
|
||||
// resources:
|
||||
// 1) The jar path of each dependent Module. The jar file will be on the 'main' runtime
|
||||
// 1) The jar path of each depended upon Module. The jar file will be on the 'main' runtime
|
||||
// classpath, but may not yet exist. Regardless, the Java code will use the path to
|
||||
// locate the module for that path.
|
||||
// 2) Each module's 'src/main/resources' dir (this is needed when the jar files from 1
|
||||
@@ -395,7 +397,7 @@ tasks.register('buildHelpFiles', JavaExec) {
|
||||
|
||||
// To build help, the validator needs any other help content that this module may reference.
|
||||
// Add each of these dependencies as an argument to the validator.
|
||||
// The dependency file is the <Module>-help.jar file from the 'buildHelp' tasks upon which
|
||||
// The dependency file is <Module>-help.jar from the 'buildModuleHelp' tasks upon which
|
||||
// we depend.
|
||||
def buildHelpTasks = getDependentProjectHelpTasks(sourceSets.main.runtimeClasspath.files)
|
||||
buildHelpTasks.each {
|
||||
@@ -423,7 +425,7 @@ tasks.register('buildHelpFiles', JavaExec) {
|
||||
* this jar is <Module>-help.jar. This is in contrast to each module's jar which itself contains
|
||||
* all help needed in production. The module's jar filename is <Module>.jar.
|
||||
*/
|
||||
tasks.register('buildHelp', Jar) {
|
||||
tasks.register('buildModuleHelp', Jar) {
|
||||
|
||||
group = rootProject.GHIDRA_GROUP
|
||||
description = " Builds the help for this module. [gradle/helpProject.gradle]\n"
|
||||
@@ -473,11 +475,11 @@ jar {
|
||||
}
|
||||
|
||||
// build the help whenever this module's jar file is built
|
||||
processResources.dependsOn buildHelp
|
||||
jar.dependsOn buildHelp
|
||||
processResources.dependsOn buildModuleHelp
|
||||
jar.dependsOn buildModuleHelp
|
||||
|
||||
|
||||
// make sure generated help directories exist during prepdev so that the directories are created and
|
||||
// eclipse doesn't complain about missing src directories.
|
||||
rootProject.prepDev.dependsOn buildHelp
|
||||
rootProject.prepDev.dependsOn buildModuleHelp
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -27,8 +27,8 @@ GHIDRA GRADLE
|
||||
be run against a specific module. For example:
|
||||
|
||||
from root project, "gradle buildHelp" builds help for all modules.
|
||||
from root project, "gradle :Base:buildHelp" builds help for the "Base" module
|
||||
from the Base project dir, "gradle buildHelp" builds help for the "Base" module
|
||||
from root project, "gradle :Base:buildModuleHelp" builds help for the "Base" module
|
||||
from the Base project dir, "gradle buildModuleHelp" builds help for the "Base" module
|
||||
|
||||
Primary gradle tasks for Ghidra
|
||||
|
||||
|
||||
Reference in New Issue
Block a user