Skip to content

Commit 7314598

Browse files
committed
conga-aem-maven-plugin:cloudmanager-all-package: Extract nested sub packages and treat them in the same way as the other packages (managing dependencies and run modes).
1 parent 85bba30 commit 7314598

11 files changed

Lines changed: 400 additions & 217 deletions

File tree

changes.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
<body>
2525

2626
<release version="1.14.6" date="not released">
27-
<action type="fix" dev="sseifert">
28-
conga-aem-maven-plugin:cloudmanager-all-package: Also process package names and dependencies in embedded sub packages.
27+
<action type="update" dev="sseifert">
28+
conga-aem-maven-plugin:cloudmanager-all-package: Extract nested sub packages and treat them in the same way as the other packages (managing dependencies and run modes).
2929
</action>
3030
</release>
3131

tooling/conga-aem-maven-plugin/src/main/java/io/wcm/devops/conga/plugins/aem/maven/CloudManagerAllPackageMojo.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ private void visitEnvironmentsNodes(EnvironmentNodeVisitor visitor) throws MojoE
240240
for (File nodeDir : nodeDirs) {
241241
Set<String> cloudManagerTarget = modelParser.getCloudManagerTarget(nodeDir);
242242
if (!cloudManagerTarget.contains(CLOUDMANAGER_TARGET_NONE)) {
243-
List<ContentPackageFile> contentPackages = modelParser.getContentPackagesForNode(nodeDir);
243+
List<? extends ContentPackageFile> contentPackages = modelParser.getContentPackagesForNode(nodeDir);
244244
visitor.visit(environmentDir, nodeDir, cloudManagerTarget, contentPackages);
245245
}
246246
}
@@ -249,7 +249,7 @@ private void visitEnvironmentsNodes(EnvironmentNodeVisitor visitor) throws MojoE
249249

250250
interface EnvironmentNodeVisitor {
251251
void visit(File environmentDir, File nodeDir, Set<String> cloudManagerTarget,
252-
List<ContentPackageFile> contentPackages) throws MojoExecutionException, MojoFailureException;
252+
List<? extends ContentPackageFile> contentPackages) throws MojoExecutionException, MojoFailureException;
253253
}
254254

255255
}

tooling/conga-aem-maven-plugin/src/main/java/io/wcm/devops/conga/plugins/aem/maven/InstallPackagesMojo.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
import org.apache.maven.plugins.annotations.Mojo;
3131
import org.apache.maven.plugins.annotations.Parameter;
3232

33-
import io.wcm.devops.conga.plugins.aem.maven.model.ContentPackageFile;
33+
import io.wcm.devops.conga.plugins.aem.maven.model.ModelContentPackageFile;
3434
import io.wcm.devops.conga.plugins.aem.maven.model.ModelParser;
3535
import io.wcm.tooling.commons.packmgr.install.PackageFile;
3636
import io.wcm.tooling.commons.packmgr.install.PackageInstaller;
@@ -102,7 +102,7 @@ public void execute() throws MojoExecutionException, MojoFailureException {
102102
}
103103
}
104104

105-
private PackageFile toPackageFile(ContentPackageFile item) {
105+
private PackageFile toPackageFile(ModelContentPackageFile item) {
106106
PackageFile output = new PackageFile();
107107

108108
output.setFile(item.getFile());

tooling/conga-aem-maven-plugin/src/main/java/io/wcm/devops/conga/plugins/aem/maven/allpackage/AllPackageBuilder.java

Lines changed: 69 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
import static io.wcm.devops.conga.plugins.aem.maven.allpackage.RunModeUtil.RUNMODE_PUBLISH;
2525
import static org.apache.jackrabbit.vault.packaging.PackageProperties.NAME_DEPENDENCIES;
2626
import static org.apache.jackrabbit.vault.packaging.PackageProperties.NAME_NAME;
27+
import static org.apache.jackrabbit.vault.packaging.PackageProperties.NAME_PACKAGE_TYPE;
2728

2829
import java.io.File;
29-
import java.io.FileInputStream;
3030
import java.io.FileOutputStream;
3131
import java.io.IOException;
3232
import java.io.InputStream;
@@ -64,6 +64,21 @@
6464

6565
/**
6666
* Builds "all" package based on given set of content packages.
67+
* <p>
68+
* General concept:
69+
* </p>
70+
* <ul>
71+
* <li>Iterates through all content packages that are generated or collected by CONGA and contained in the
72+
* model.json</li>
73+
* <li>Enforces the order defined in CONGA by automatically adding dependencies to all packages reflecting the file
74+
* order in model.json</li>
75+
* <li>Because the dependency chain may be different for each runmode (author/publish), each package is added once for
76+
* each runmode (so usually twice, for author+publish)</li>
77+
* <li>To avoid conflicts with duplicate packages with different dependencies all package names are changed and a
78+
* runmode suffix (.author or .publish) is added, same applies to the install folder</li>
79+
* <li>To avoid problems with nested sub packages, the sub packages are extracted from the packages and treated in the
80+
* same way as other packages</li>
81+
* </ul>
6782
*/
6883
public final class AllPackageBuilder {
6984

@@ -134,7 +149,7 @@ private Log getLog() {
134149
* @param cloudManagerTarget Target environments/run modes the packages should be attached to
135150
* @throws IllegalArgumentException If and invalid package type is detected
136151
*/
137-
public void add(List<ContentPackageFile> contentPackages, Set<String> cloudManagerTarget) {
152+
public void add(List<? extends ContentPackageFile> contentPackages, Set<String> cloudManagerTarget) {
138153

139154
// collect list of cloud manager environment run modes
140155
List<String> environmentRunModes = new ArrayList<>();
@@ -217,7 +232,6 @@ public boolean build(Map<String, String> properties) throws IOException {
217232
for (String environmentRunMode : fileSet.getEnvironmentRunModes()) {
218233
List<ContentPackageFile> previousPackages = new ArrayList<>();
219234
for (ContentPackageFile pkg : fileSet.getContentPackages()) {
220-
String path = buildPackagePath(pkg, rootPath, environmentRunMode);
221235

222236
ContentPackageFile previousPkg = null;
223237

@@ -232,14 +246,22 @@ public boolean build(Map<String, String> properties) throws IOException {
232246
}
233247

234248
// set package name, wire previous package in package dependency
235-
File tempPackageFile = processContentPackage(pkg.getFile(), pkg, previousPkg, environmentRunMode, allPackagesFromFileSets);
249+
List<TemporaryContentPackageFile> processedFiles = processContentPackage(pkg, previousPkg, environmentRunMode, allPackagesFromFileSets);
236250

237-
// add temp zip file to "all" content package
251+
// add processed content packages to "all" content package - and delete the temporary files
238252
try {
239-
contentPackage.addFile(path, tempPackageFile);
253+
for (TemporaryContentPackageFile processedFile : processedFiles) {
254+
String path = buildPackagePath(processedFile, rootPath, environmentRunMode);
255+
contentPackage.addFile(path, processedFile.getFile());
256+
if (log.isDebugEnabled()) {
257+
log.debug(" Add " + processedFile.getPackageInfoWithDependencies());
258+
}
259+
}
240260
}
241261
finally {
242-
FileUtils.deleteQuietly(tempPackageFile);
262+
processedFiles.stream()
263+
.map(TemporaryContentPackageFile::getFile)
264+
.forEach(FileUtils::deleteQuietly);
243265
}
244266

245267
previousPackages.add(pkg);
@@ -284,7 +306,7 @@ private static String buildRootPath(String groupName, String packageName) {
284306

285307
/**
286308
* Generate suffix for instance and environment run modes.
287-
* @param pkg Package
309+
* @param pkg Content package
288310
* @return Package path
289311
*/
290312
private static String buildRunModeSuffix(ContentPackageFile pkg, String environmentRunMode) {
@@ -308,6 +330,10 @@ else if (RunModeUtil.isOnlyPublish(pkg)) {
308330
* @return Package path
309331
*/
310332
private static String buildPackagePath(ContentPackageFile pkg, String rootPath, String environmentRunMode) {
333+
if (!isValidPackageType(pkg)) {
334+
throw new IllegalArgumentException("Package " + pkg.getPackageInfo() + " has invalid package type: '" + pkg.getPackageType() + "'.");
335+
}
336+
311337
String runModeSuffix = buildRunModeSuffix(pkg, environmentRunMode);
312338

313339
// add run mode suffix to both install folder path and package file name
@@ -317,33 +343,33 @@ private static String buildPackagePath(ContentPackageFile pkg, String rootPath,
317343
if (pkg.getVersion() != null && pkg.getFile().getName().contains(pkg.getVersion())) {
318344
versionSuffix = "-" + pkg.getVersion();
319345
}
320-
String fileName = pkg.getName() + runModeSuffix + versionSuffix
346+
String fileName = pkg.getName() + versionSuffix
321347
+ "." + FilenameUtils.getExtension(pkg.getFile().getName());
322348
return path + "/" + fileName;
323349
}
324350

325351
/**
326352
* Rewrite content package ZIP file while adding to "all" package:
327353
* Add dependency to previous package in CONGA configuration file oder.
328-
* @param contentPackageFile The actual content package file to process
329354
* @param pkg Package to process (can be parent packe of the actual file)
330355
* @param previousPkg Previous package to get dependency information from.
331356
* Is null if no previous package exists or auto dependency mode is switched off.
332357
* @param environmentRunMode Environment run mode
333358
* @param allPackagesFromFileSets Set with all packages from all file sets as dependency instances
334-
* @return Returns a *temporary* file - has to be deleted when processing the result is completed.
359+
* @return Returns a list of content package *temporary* files - have to be deleted when processing is completed.
335360
* @throws IOException I/O error
336361
*/
337-
private File processContentPackage(File contentPackageFile, ContentPackageFile pkg,
362+
private List<TemporaryContentPackageFile> processContentPackage(ContentPackageFile pkg,
338363
ContentPackageFile previousPkg, String environmentRunMode,
339364
Set<Dependency> allPackagesFromFileSets) throws IOException {
340365

366+
List<TemporaryContentPackageFile> result = new ArrayList<>();
367+
341368
// create temp zip file to create rewritten copy of package
342-
File tempFile = File.createTempFile("pkg", ".zip");
369+
File tempFile = File.createTempFile(FilenameUtils.getBaseName(pkg.getFile().getName()), ".zip");
343370

344371
// open original content package
345-
try (ZipFile zipFileIn = new ZipFile(contentPackageFile)) {
346-
String dependenciesString = null;
372+
try (ZipFile zipFileIn = new ZipFile(pkg.getFile())) {
347373

348374
// iterate through entries and write them to the temp. zip file
349375
try (FileOutputStream fos = new FileOutputStream(tempFile);
@@ -353,48 +379,54 @@ private File processContentPackage(File contentPackageFile, ContentPackageFile p
353379
ZipEntry zipInEntry = zipInEntries.nextElement();
354380
if (!zipInEntry.isDirectory()) {
355381
try (InputStream is = zipFileIn.getInputStream(zipInEntry)) {
382+
boolean processedEntry = false;
356383

357384
// if entry is properties.xml, update dependency information
358385
if (StringUtils.equals(zipInEntry.getName(), "META-INF/vault/properties.xml")) {
359386
Properties props = new Properties();
360387
props.loadFromXML(is);
361388
addSuffixToPackageName(props, pkg, environmentRunMode);
362389
if (autoDependenciesMode != AutoDependenciesMode.OFF) {
363-
dependenciesString = updateDependencies(props, previousPkg, environmentRunMode, allPackagesFromFileSets);
390+
updateDependencies(props, previousPkg, environmentRunMode, allPackagesFromFileSets);
391+
}
392+
393+
// if package type is missing package properties, put in the type defined in model
394+
if (props.get(NAME_PACKAGE_TYPE) == null) {
395+
props.put(NAME_PACKAGE_TYPE, pkg.getPackageType());
364396
}
365397

366398
ZipEntry zipOutEntry = new ZipEntry(zipInEntry.getName());
367399
zipOut.putNextEntry(zipOutEntry);
368400
props.storeToXML(zipOut, null);
401+
processedEntry = true;
369402
}
370403

371404
// process sub-packages as well: add runmode suffix and update dependencies
372405
else if (StringUtils.equals(FilenameUtils.getExtension(zipInEntry.getName()), "zip")) {
373-
String path = FilenameUtils.getPath(zipInEntry.getName());
374-
String basename = FilenameUtils.getBaseName(zipInEntry.getName());
375-
String runModeSuffix = buildRunModeSuffix(pkg, environmentRunMode);
376-
377-
File tempSubPackageFile = File.createTempFile("subpkg-" + basename + runModeSuffix, ".zip");
406+
File tempSubPackageFile = File.createTempFile(FilenameUtils.getBaseName(zipInEntry.getName()), ".zip");
378407
try (FileOutputStream subPackageFos = new FileOutputStream(tempSubPackageFile)) {
379408
IOUtils.copy(is, subPackageFos);
380409
}
381-
File resultSubPackageFile = processContentPackage(tempSubPackageFile, pkg, null, environmentRunMode, allPackagesFromFileSets);
382-
try (FileInputStream subPackageFis = new FileInputStream(resultSubPackageFile)) {
383-
// add runmode suffix to install path and to filename
384-
String newPath = StringUtils.removeEnd(path, "/") + runModeSuffix + "/"
385-
+ basename + runModeSuffix + ".zip";
386-
387-
ZipEntry zipOutEntry = new ZipEntry(newPath);
388-
zipOut.putNextEntry(zipOutEntry);
389-
IOUtils.copy(subPackageFis, zipOut);
410+
411+
// check if contained ZIP file is really a content package
412+
// then process it as well, remove if from the content package is was contained it
413+
// and add it as "1st level package" to the all package
414+
TemporaryContentPackageFile tempSubPackage = new TemporaryContentPackageFile(tempSubPackageFile, pkg.getVariants());
415+
if (!isValidPackageType(tempSubPackage)) {
416+
throw new IllegalArgumentException("Package " + pkg.getPackageInfo() + " contains sub package " + tempSubPackage.getPackageInfo()
417+
+ " with invalid package type: '" + StringUtils.defaultString(tempSubPackage.getPackageType()) + "'");
418+
}
419+
if (StringUtils.isNoneBlank(tempSubPackage.getGroup(), tempSubPackage.getName())) {
420+
result.addAll(processContentPackage(tempSubPackage, previousPkg, environmentRunMode, allPackagesFromFileSets));
421+
processedEntry = true;
390422
}
391-
finally {
392-
FileUtils.deleteQuietly(resultSubPackageFile);
423+
else {
424+
FileUtils.deleteQuietly(tempSubPackageFile);
393425
}
394426
}
395427

396428
// otherwise transfer the binary data 1:1
397-
else {
429+
if (!processedEntry) {
398430
ZipEntry zipOutEntry = new ZipEntry(zipInEntry.getName());
399431
zipOut.putNextEntry(zipOutEntry);
400432
IOUtils.copy(is, zipOut);
@@ -404,26 +436,21 @@ else if (StringUtils.equals(FilenameUtils.getExtension(zipInEntry.getName()), "z
404436
zipOut.closeEntry();
405437
}
406438
}
407-
408-
if (log.isDebugEnabled()) {
409-
log.debug("Processed " + getCanonicalPath(contentPackageFile)
410-
+ (dependenciesString != null ? " with dependencies: " + dependenciesString : ""));
411-
}
412439
}
413440

414-
return tempFile;
441+
result.add(new TemporaryContentPackageFile(tempFile, pkg.getVariants()));
415442
}
443+
return result;
416444
}
417445

418446
/**
419447
* Add dependency information to dependencies string in properties (if it does not exist already).
420448
* @param props Properties
421449
* @param dependencyFile Dependency package
422450
* @param allPackagesFromFileSets Set with all packages from all file sets as dependency instances
423-
* @throws IOException I/O exception
424451
*/
425-
private static String updateDependencies(Properties props, ContentPackageFile dependencyFile, String environmentRunMode,
426-
Set<Dependency> allPackagesFromFileSets) throws IOException {
452+
private static void updateDependencies(Properties props, ContentPackageFile dependencyFile, String environmentRunMode,
453+
Set<Dependency> allPackagesFromFileSets) {
427454
String[] existingDepsStrings = StringUtils.split(props.getProperty(NAME_DEPENDENCIES), ",");
428455
Dependency[] existingDeps = null;
429456
if (existingDepsStrings != null && existingDepsStrings.length > 0) {
@@ -448,10 +475,6 @@ private static String updateDependencies(Properties props, ContentPackageFile de
448475
if (deps != null) {
449476
String dependenciesString = Dependency.toString(deps);
450477
props.put(NAME_DEPENDENCIES, dependenciesString);
451-
return dependenciesString;
452-
}
453-
else {
454-
return null;
455478
}
456479
}
457480

0 commit comments

Comments
 (0)