Skip to content

Commit d7c44fa

Browse files
author
mdaraujo19
committed
Added RPM Sign and Publish functionality, also updates docs.
1 parent 24fd36f commit d7c44fa

23 files changed

+849
-18
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ There are some **requirements** (tools and programs) that are needed for the suc
1212

1313
- Have **Maven** installed.
1414
- Have **Java 11 SE** installed and configured.
15-
- Have access to the **dpkg**, **rpm**, **snap**, **snapcraft** and **lxd** commands, as well as being on a GNU/Linux operating system.
15+
- Have access to the **dpkg**, **rpm**, **snap**, **snapcraft**, **lxd**, **gpg** and **curl** commands, as well as being on a GNU/Linux operating system.
1616
- Recommended to have the **latests version of the Java to Distributable** project.
1717

1818
If you already meet this requirements, you are free to continue.
@@ -87,6 +87,8 @@ The tags that can be placed in the `choices.xml` file are:
8787
- `<javaRunArg>` represents a Java execution argument to run the application with. It must not have the initial hyphen.
8888
- `<numberJavaRunArgs>` represents/contains a set of `<numberJavaRunArg>`
8989
- `<numberJavaRunArg>` represents numbers that are the quantity of Java execution arguments for each command. Must be accumulative and match with the commands declaration order.
90+
- `<nexusUsername>` represents the Nexus repository username that is allowed to publish RPMs.
91+
- `<nexusRepoUrl>` represents the Nexus repository URL were the RPM package will be published to.
9092

9193
## Commands
9294

doc/Example_Java_To_Distributable_commands.md

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ jtd generate-snap-distributable --jar --jar-file <your_desired_jar_file_path> --
219219
A overview of the command syntax is:
220220

221221
```
222-
jtd generate-rpm-distributable [--verbose/-ve] {--maven/-mvn | --jar/-j} [--jar-file/-jf JAR_PATH...] [--input-pom-file/-ipf POM_PATH | { --maven-remote-repositories/-mrr URL_REPOSITORY… | --from-maven-central/-fmc | --from-maven-local/-fml } --maven-coordinates/-mc COORDINATE… ] [--ignore-central-repository/-icr] [--prioritize-local-m2-repository/-plr] [--main-name/-mn PACKAGE_MAIN_NAME] [--application-class-name/-acn MAIN_CLASS_NAME...] [--choices-file/-cf CHOICES_PATH] --output-directory/-od OUTPUT_DIRECTORY [--dependency/-d DEPENDENCY...] [--documentation/-d DOCUMENTATION_URL] [--target-command-name/-tcn TARGET_COMMAND_NAME...] [--application-name/-an APPLICATION_NAME] [--application-version/-av APPLICATION_VERSION] [--application-description/-ad APPLICATION_DESCRIPTION] [--java-dependency/-jd JAVA_DEPENDENCY] [--man-page/-mp MAN_PAGE_PATH] [--java-run-arg/-jra JAVA_RUN_ARGUMENT...] [--number-java-run-arg/-njra NUMBER_JAVA_RUN_ARGUMENT...] [--licence/-l LICENCE_NAME]
222+
jtd generate-rpm-distributable [--verbose/-ve] {--maven/-mvn | --jar/-j} [--jar-file/-jf JAR_PATH...] [--input-pom-file/-ipf POM_PATH | { --maven-remote-repositories/-mrr URL_REPOSITORY… | --from-maven-central/-fmc | --from-maven-local/-fml } --maven-coordinates/-mc COORDINATE… ] [--ignore-central-repository/-icr] [--prioritize-local-m2-repository/-plr] [--main-name/-mn PACKAGE_MAIN_NAME] [--application-class-name/-acn MAIN_CLASS_NAME...] [--choices-file/-cf CHOICES_PATH] --output-directory/-od OUTPUT_DIRECTORY [--dependency/-d DEPENDENCY...] [--documentation/-d DOCUMENTATION_URL] [--target-command-name/-tcn TARGET_COMMAND_NAME...] [--application-name/-an APPLICATION_NAME] [--application-version/-av APPLICATION_VERSION] [--application-description/-ad APPLICATION_DESCRIPTION] [--java-dependency/-jd JAVA_DEPENDENCY] [--man-page/-mp MAN_PAGE_PATH] [--java-run-arg/-jra JAVA_RUN_ARGUMENT...] [--number-java-run-arg/-njra NUMBER_JAVA_RUN_ARGUMENT...] [--licence/-l LICENCE_NAME] [--sign/-s] [--publish/-p] [--nexus-username/-nu NEXUS_REPO_USERNAME] [--nexus-repo-url/-nru NEXUS_REPO_URL]
223223
```
224224

225225
Currently, the command has the following modes of operation:
@@ -318,7 +318,27 @@ Another example with more options is:
318318
jtd generate-rpm-distributable --jar --jar-file <your_desired_jar_file_path> --jar-file <another_desired_jar_file_path> --application-class-name org.sing_group.seda.cli.SedaCliApplication --licence GPLv3 --output-directory <your_desired_output_path> --choices-file <your_desired_choices_file>
319319
```
320320

321-
### Build a multi-command distributable
321+
### Sign a distributable
322+
323+
If you want to sign the resulting RPM distributable package after creation, you need to add the appropriate flag as follows:
324+
325+
```
326+
jtd generate-rpm-distributable --maven --maven-remote-repositories https://maven.sing-group.org/repository/maven-snapshots/ --maven-coordinates org.sing_group:seda:1.6.0-SNAPSHOT --maven-coordinates org.sing_group:seda-plugin-blast:1.6.0-SNAPSHOT --application-class-name org.sing_group.seda.cli.SedaCliApplication --output-directory <your_desired_output_path> --sign
327+
```
328+
329+
During the process, the user is required to enter the GPG key passphrase interactively so keep that in mind.
330+
331+
### Publish a distributable
332+
333+
If you want to publish the resulting RPM distributable package after creation, you need to add the appropriate flag and provide some additional information as follows:
334+
335+
```
336+
jtd generate-rpm-distributable --maven --maven-remote-repositories https://maven.sing-group.org/repository/maven-snapshots/ --maven-coordinates org.sing_group:seda:1.6.0-SNAPSHOT --maven-coordinates org.sing_group:seda-plugin-blast:1.6.0-SNAPSHOT --application-class-name org.sing_group.seda.cli.SedaCliApplication --output-directory <your_desired_output_path> --publish --nexus-username <your_nexus_repo_username> --nexus-repo-url <your_nexus_repo_url_for_package_storing>
337+
```
338+
339+
During the process, the user is required to enter the Nexus repository username's password interactively so keep that in mind.
340+
341+
## Build a multi-command distributable
322342

323343
If you need to package multiple commands in the same distributable file, you can add more classes and command names as follows:
324344

src/main/java/es/uvigo/esei/sing/java_to_distributable/cli/command/GenerateDebianDistributableCommand.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.ArrayList;
3030
import java.util.Arrays;
3131
import java.util.List;
32+
import java.util.Map;
3233

3334
import org.slf4j.Logger;
3435
import org.slf4j.LoggerFactory;
@@ -39,8 +40,11 @@
3940
import es.uvigo.esei.sing.java_to_distributable.cli.option.ImageFileWithExtensionOption;
4041
import es.uvigo.esei.sing.java_to_distributable.enums.OptionCategoryEnum;
4142
import es.uvigo.esei.sing.java_to_distributable.model.AppInfo;
43+
import es.uvigo.esei.sing.java_to_distributable.utils.output.AppOutputGenerator;
4244
import es.uvigo.esei.sing.java_to_distributable.utils.output.DebianAppOutputGenerator;
4345
import es.uvigo.esei.sing.java_to_distributable.utils.output.OutputGenerator;
46+
import es.uvigo.esei.sing.java_to_distributable.utils.output.sign.DebianSignerAppOutputGenerator;
47+
import es.uvigo.esei.sing.java_to_distributable.utils.output.publish.DebianPublisherAppOutputGenerator;
4448

4549
/**
4650
* An specialization of {@link GenerateDistributableCommand} that generates a
@@ -131,8 +135,24 @@ protected List<Option<?>> createDistributableOptions() {
131135
*
132136
*/
133137
@Override
134-
protected OutputGenerator getOutputGenerator(File output, AppInfo info) {
135-
return new DebianAppOutputGenerator(info, output);
138+
protected OutputGenerator getOutputGenerator(File output, AppInfo info, Map<String, Boolean> options) {
139+
AppOutputGenerator gen = new DebianAppOutputGenerator(info, output);
140+
for (String option : options.keySet()) {
141+
switch (option.toUpperCase()) {
142+
case "SIGN":
143+
if (options.get(option) == true)
144+
gen = new DebianSignerAppOutputGenerator(gen);
145+
break;
146+
case "PUBLISH":
147+
if (options.get(option) == true)
148+
gen = new DebianPublisherAppOutputGenerator(gen);
149+
break;
150+
default:
151+
LOGGER.warn("Option: " + option + " not supported.");
152+
break;
153+
}
154+
}
155+
return gen;
136156
}
137157

138158
/**

src/main/java/es/uvigo/esei/sing/java_to_distributable/cli/command/GenerateDistributableCommand.java

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
import java.io.IOException;
3030
import java.util.ArrayList;
3131
import java.util.Arrays;
32+
import java.util.LinkedHashMap;
3233
import java.util.List;
34+
import java.util.Map;
3335

3436
import org.apache.commons.lang3.tuple.ImmutablePair;
3537
import org.apache.commons.lang3.tuple.Pair;
@@ -328,6 +330,24 @@ public abstract class GenerateDistributableCommand extends AbstractCommand {
328330
Arrays.asList(OptionCategoryEnum.OPTIONAL.getCategory()), "verbose", "ve",
329331
"Whether to see command progress messages or not."
330332
);
333+
334+
/**
335+
* Represents the option that indicates whether to sign the resulting distributable
336+
* package file or not. It is optional and does not require a value.
337+
*/
338+
protected static final FlagOption SIGN_OPTION = new FlagOption(
339+
Arrays.asList(OptionCategoryEnum.SIGN.getCategory()), "sign", "s",
340+
"Wheter to sign the resulting package using GNUPG or not."
341+
);
342+
343+
/**
344+
* Represents the option that indicates whether to publish the resulting distributable
345+
* package file or not. It is optional and does not require a value.
346+
*/
347+
protected static final FlagOption PUBLISH_OPTION = new FlagOption(
348+
Arrays.asList(OptionCategoryEnum.PUBLISH.getCategory()), "publish", "p",
349+
"Wheter to publish the resulting package or not."
350+
);
331351

332352
/**
333353
* Represents the optional options of which at least one of each list must be
@@ -405,11 +425,13 @@ public abstract class GenerateDistributableCommand extends AbstractCommand {
405425
* The output directory where the result will be stored.
406426
* @param info
407427
* The application's info needed to generate the output.
428+
* @param options
429+
* The additional options that add extra processes (like signing or deploying).
408430
*
409431
* @return the {@code OutputGenerator} instance.
410432
*
411433
*/
412-
protected abstract OutputGenerator getOutputGenerator(File output, AppInfo info);
434+
protected abstract OutputGenerator getOutputGenerator(File output, AppInfo info, Map<String, Boolean> options);
413435

414436
/**
415437
* Abstract method that the subclasses must implement to get the proper
@@ -452,12 +474,14 @@ public void execute(Parameters parameters) throws Exception {
452474

453475
final AppInfo info = provider.createInfo();
454476

477+
// Verify if all the critical parameters are present
455478
if (info.getTargetCommandName().isEmpty() || info.getVersion().isEmpty() || info.getClassName().isEmpty()) {
456479
throw new IllegalArgumentException(
457480
"One of: targetCommandName, version or className is not found nor provided. Cannot continue."
458481
);
459482
}
460483

484+
// If there is no Java run arguments, set the number of Java run arguments to 0
461485
if (info.getJavaRunArgs().isEmpty() && info.getNumberJavaRunArgs().isEmpty()) {
462486
List<String> nja = new ArrayList<>();
463487
for (int i = 0; i < info.getTargetCommandName().size(); i++) {
@@ -467,6 +491,7 @@ public void execute(Parameters parameters) throws Exception {
467491
LOGGER.warn("The parameter numberJavaRunArgs is not set, using default value (all zeroes [0]).");
468492
}
469493

494+
// Verify the multi-command format
470495
if (!info.validateMulticommandFormat(info.getTargetCommandName(),
471496
info.getClassName(), info.getJavaRunArgs(), info.getNumberJavaRunArgs())) {
472497
throw new IllegalArgumentException(
@@ -477,8 +502,12 @@ public void execute(Parameters parameters) throws Exception {
477502

478503
LOGGER.info("Choosing the OutputGenerator.");
479504

505+
Map<String, Boolean> options = new LinkedHashMap<>();
506+
options.put("SIGN", parameters.hasFlag(SIGN_OPTION));
507+
options.put("PUBLISH", parameters.hasFlag(PUBLISH_OPTION));
508+
480509
final OutputGenerator generator = this
481-
.getOutputGenerator(parameters.getSingleValue(OUTPUT_DIRECTORY_OPTION), info);
510+
.getOutputGenerator(parameters.getSingleValue(OUTPUT_DIRECTORY_OPTION), info, options);
482511

483512
LOGGER.info("Generating output, this step could take several minutes.");
484513

@@ -539,6 +568,8 @@ protected List<Option<?>> createOptions() {
539568
options.add(DOCUMENTATION_URL_OPTION);
540569
options.add(MAN_PAGE_OPTION);
541570
options.add(OUTPUT_DIRECTORY_OPTION);
571+
options.add(SIGN_OPTION);
572+
options.add(PUBLISH_OPTION);
542573
options.addAll(this.createDistributableOptions());
543574

544575
return options;

src/main/java/es/uvigo/esei/sing/java_to_distributable/cli/command/GenerateRPMDistributableCommand.java

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,24 @@
2626
package es.uvigo.esei.sing.java_to_distributable.cli.command;
2727

2828
import java.io.File;
29+
import java.util.ArrayList;
2930
import java.util.Arrays;
3031
import java.util.List;
32+
import java.util.Map;
3133

3234
import org.slf4j.Logger;
3335
import org.slf4j.LoggerFactory;
3436

3537
import es.uvigo.ei.sing.yacli.command.option.Option;
3638
import es.uvigo.ei.sing.yacli.command.option.StringOption;
39+
import es.uvigo.esei.sing.java_to_distributable.cli.option.UrlOption;
3740
import es.uvigo.esei.sing.java_to_distributable.enums.OptionCategoryEnum;
3841
import es.uvigo.esei.sing.java_to_distributable.model.AppInfo;
3942
import es.uvigo.esei.sing.java_to_distributable.utils.output.OutputGenerator;
43+
import es.uvigo.esei.sing.java_to_distributable.utils.output.AppOutputGenerator;
4044
import es.uvigo.esei.sing.java_to_distributable.utils.output.RPMAppOutputGenerator;
45+
import es.uvigo.esei.sing.java_to_distributable.utils.output.sign.RPMSignerAppOutputGenerator;
46+
import es.uvigo.esei.sing.java_to_distributable.utils.output.publish.RPMPublisherAppOutputGenerator;
4147

4248
/**
4349
* A specialization of {@link GenerateDistributableCommand} that generates a Red
@@ -52,6 +58,16 @@ public class GenerateRPMDistributableCommand extends GenerateDistributableComman
5258
Arrays.asList(OptionCategoryEnum.CUSTOM.getCategory()), "licence", "l",
5359
"The name of the licence of the application.", true, true, false
5460
);
61+
62+
private static final StringOption NEXUS_USERNAME = new StringOption(
63+
Arrays.asList(OptionCategoryEnum.PUBLISH.getCategory()), "nexus-username", "nu",
64+
"The username of the Nexus repository access credentials for publishing the RPM package.", true, true, false
65+
);
66+
67+
private static final UrlOption NEXUS_REPO_URL = new UrlOption(
68+
Arrays.asList(OptionCategoryEnum.PUBLISH.getCategory()), "nexus-repo-url", "nru",
69+
"The URL of the Nexus repository where the RPM package will be published to.", true, true, false
70+
);
5571

5672
/**
5773
* Gets the command name.
@@ -95,7 +111,13 @@ public String getDescription() {
95111
*/
96112
@Override
97113
protected List<Option<?>> createDistributableOptions() {
98-
return Arrays.asList(LICENSE_OPTION);
114+
final List<Option<?>> options = new ArrayList<>();
115+
116+
options.add(LICENSE_OPTION);
117+
options.add(NEXUS_USERNAME);
118+
options.add(NEXUS_REPO_URL);
119+
120+
return options;
99121
}
100122

101123
/**
@@ -105,8 +127,26 @@ protected List<Option<?>> createDistributableOptions() {
105127
*
106128
*/
107129
@Override
108-
protected OutputGenerator getOutputGenerator(File output, AppInfo info) {
109-
return new RPMAppOutputGenerator(info, output);
130+
protected OutputGenerator getOutputGenerator(File output, AppInfo info, Map<String, Boolean> options) {
131+
AppOutputGenerator gen = new RPMAppOutputGenerator(info, output);
132+
for (String option : options.keySet()) {
133+
switch (option.toUpperCase()) {
134+
case "SIGN":
135+
if (options.get(option) == true) {
136+
gen = new RPMSignerAppOutputGenerator(gen);
137+
}
138+
break;
139+
case "PUBLISH":
140+
if (options.get(option) == true) {
141+
gen = new RPMPublisherAppOutputGenerator(gen);
142+
}
143+
break;
144+
default:
145+
LOGGER.warn("Option: " + option + " not supported.");
146+
break;
147+
}
148+
}
149+
return gen;
110150
}
111151

112152
/**

src/main/java/es/uvigo/esei/sing/java_to_distributable/cli/command/GenerateSnapcraftDistributableCommand.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.ArrayList;
3030
import java.util.Arrays;
3131
import java.util.List;
32+
import java.util.Map;
3233

3334
import org.slf4j.Logger;
3435
import org.slf4j.LoggerFactory;
@@ -40,8 +41,11 @@
4041
import es.uvigo.esei.sing.java_to_distributable.enums.SnapConfinementEnum;
4142
import es.uvigo.esei.sing.java_to_distributable.enums.SnapGradeEnum;
4243
import es.uvigo.esei.sing.java_to_distributable.model.AppInfo;
44+
import es.uvigo.esei.sing.java_to_distributable.utils.output.AppOutputGenerator;
4345
import es.uvigo.esei.sing.java_to_distributable.utils.output.OutputGenerator;
4446
import es.uvigo.esei.sing.java_to_distributable.utils.output.SnapcraftAppOutputGenerator;
47+
import es.uvigo.esei.sing.java_to_distributable.utils.output.sign.SnapcraftSignerAppOutputGenerator;
48+
import es.uvigo.esei.sing.java_to_distributable.utils.output.publish.SnapcraftPublisherAppOutputGenerator;
4549

4650
/**
4751
* A specialization of {@link GenerateDistributableCommand} that generates a
@@ -127,8 +131,24 @@ protected List<Option<?>> createDistributableOptions() {
127131
*
128132
*/
129133
@Override
130-
protected OutputGenerator getOutputGenerator(File output, AppInfo info) {
131-
return new SnapcraftAppOutputGenerator(info, output);
134+
protected OutputGenerator getOutputGenerator(File output, AppInfo info, Map<String, Boolean> options) {
135+
AppOutputGenerator gen = new SnapcraftAppOutputGenerator(info, output);
136+
for (String option : options.keySet()) {
137+
switch (option.toUpperCase()) {
138+
case "SIGN":
139+
if (options.get(option) == true)
140+
gen = new SnapcraftSignerAppOutputGenerator(gen);
141+
break;
142+
case "PUBLISH":
143+
if (options.get(option) == true)
144+
gen = new SnapcraftPublisherAppOutputGenerator(gen);
145+
break;
146+
default:
147+
LOGGER.warn("Option: " + option + " not supported.");
148+
break;
149+
}
150+
}
151+
return gen;
132152
}
133153

134154
/**

src/main/java/es/uvigo/esei/sing/java_to_distributable/enums/OptionCategoryEnum.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,17 @@ public enum OptionCategoryEnum {
8080
/**
8181
* Represents Jar-related options.
8282
*/
83-
JAR(new OptionCategory("jar"));
83+
JAR(new OptionCategory("jar")),
84+
85+
/**
86+
* Represents Package signing-related options.
87+
*/
88+
SIGN(new OptionCategory("sign")),
89+
90+
/**
91+
* Represents Package publish-related options.
92+
*/
93+
PUBLISH(new OptionCategory("publish"));
8494

8595
private OptionCategory category;
8696

0 commit comments

Comments
 (0)