• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jreleaser / jreleaser / #510

27 Jul 2025 12:31PM UTC coverage: 45.783% (-3.6%) from 49.39%
#510

push

github

aalmiray
feat(packagers): Stage distribution publication in a fixed directory

Closes #1943

12 of 25 new or added lines in 4 files covered. (48.0%)

2208 existing lines in 190 files now uncovered.

23924 of 52255 relevant lines covered (45.78%)

0.46 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

63.98
/core/jreleaser-model-impl/src/main/java/org/jreleaser/model/internal/JReleaserContext.java
1
/*
2
 * SPDX-License-Identifier: Apache-2.0
3
 *
4
 * Copyright 2020-2025 The JReleaser authors.
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     https://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
package org.jreleaser.model.internal;
19

20
import com.fasterxml.jackson.annotation.JsonIgnore;
21
import org.bouncycastle.openpgp.PGPException;
22
import org.jreleaser.bundle.RB;
23
import org.jreleaser.extensions.api.workflow.WorkflowListener;
24
import org.jreleaser.extensions.api.workflow.WorkflowListenerException;
25
import org.jreleaser.logging.JReleaserLogger;
26
import org.jreleaser.logging.SimpleJReleaserLoggerAdapter;
27
import org.jreleaser.model.Active;
28
import org.jreleaser.model.Constants;
29
import org.jreleaser.model.JReleaserException;
30
import org.jreleaser.model.JReleaserVersion;
31
import org.jreleaser.model.Signing;
32
import org.jreleaser.model.api.JReleaserCommand;
33
import org.jreleaser.model.api.JReleaserContext.Changelog;
34
import org.jreleaser.model.api.announce.Announcer;
35
import org.jreleaser.model.api.assemble.Assembler;
36
import org.jreleaser.model.api.catalog.Cataloger;
37
import org.jreleaser.model.api.deploy.Deployer;
38
import org.jreleaser.model.api.distributions.Distribution;
39
import org.jreleaser.model.api.download.Downloader;
40
import org.jreleaser.model.api.hooks.ExecutionEvent;
41
import org.jreleaser.model.api.packagers.Packager;
42
import org.jreleaser.model.api.release.Releaser;
43
import org.jreleaser.model.api.signing.Keyring;
44
import org.jreleaser.model.api.signing.SigningException;
45
import org.jreleaser.model.api.upload.Uploader;
46
import org.jreleaser.model.internal.assemble.DebAssembler;
47
import org.jreleaser.model.internal.assemble.JavaArchiveAssembler;
48
import org.jreleaser.model.internal.assemble.JavaAssembler;
49
import org.jreleaser.model.internal.assemble.NativeImageAssembler;
50
import org.jreleaser.model.internal.common.Artifact;
51
import org.jreleaser.model.internal.platform.Platform;
52
import org.jreleaser.model.internal.project.Project;
53
import org.jreleaser.model.internal.release.BaseReleaser;
54
import org.jreleaser.mustache.TemplateContext;
55
import org.jreleaser.sdk.signing.FilesKeyring;
56
import org.jreleaser.sdk.signing.InMemoryKeyring;
57
import org.jreleaser.util.Errors;
58
import org.jreleaser.util.FileType;
59
import org.jreleaser.util.PlatformUtils;
60
import org.jreleaser.util.StringUtils;
61
import org.jreleaser.version.SemanticVersion;
62

63
import java.io.FileOutputStream;
64
import java.io.IOException;
65
import java.nio.file.Path;
66
import java.nio.file.Paths;
67
import java.util.ArrayList;
68
import java.util.Collection;
69
import java.util.Collections;
70
import java.util.Enumeration;
71
import java.util.Iterator;
72
import java.util.LinkedHashMap;
73
import java.util.List;
74
import java.util.Locale;
75
import java.util.Map;
76
import java.util.Optional;
77
import java.util.Properties;
78
import java.util.Set;
79
import java.util.TreeMap;
80

81
import static java.nio.charset.StandardCharsets.UTF_8;
82
import static java.util.Collections.unmodifiableList;
83
import static java.util.Collections.unmodifiableMap;
84
import static java.util.stream.Collectors.toList;
85
import static org.jreleaser.model.Constants.KEY_COMMIT_FULL_HASH;
86
import static org.jreleaser.model.Constants.KEY_COMMIT_SHORT_HASH;
87
import static org.jreleaser.model.Constants.KEY_GRAALVM_NAGIVE_IMAGE;
88
import static org.jreleaser.model.Constants.KEY_MILESTONE_NAME;
89
import static org.jreleaser.model.Constants.KEY_PLATFORM;
90
import static org.jreleaser.model.Constants.KEY_PLATFORM_REPLACED;
91
import static org.jreleaser.model.Constants.KEY_PREVIOUS_TAG_NAME;
92
import static org.jreleaser.model.Constants.KEY_PROJECT_NAME;
93
import static org.jreleaser.model.Constants.KEY_PROJECT_SNAPSHOT;
94
import static org.jreleaser.model.Constants.KEY_PROJECT_VERSION;
95
import static org.jreleaser.model.Constants.KEY_RELEASE_NAME;
96
import static org.jreleaser.model.Constants.KEY_TAG_NAME;
97
import static org.jreleaser.model.Constants.KEY_TIMESTAMP;
98
import static org.jreleaser.model.Constants.KEY_VERSION_BUILD;
99
import static org.jreleaser.model.Constants.KEY_VERSION_DAY;
100
import static org.jreleaser.model.Constants.KEY_VERSION_MAJOR;
101
import static org.jreleaser.model.Constants.KEY_VERSION_MICRO;
102
import static org.jreleaser.model.Constants.KEY_VERSION_MINOR;
103
import static org.jreleaser.model.Constants.KEY_VERSION_MODIFIER;
104
import static org.jreleaser.model.Constants.KEY_VERSION_MONTH;
105
import static org.jreleaser.model.Constants.KEY_VERSION_NUMBER;
106
import static org.jreleaser.model.Constants.KEY_VERSION_OPTIONAL;
107
import static org.jreleaser.model.Constants.KEY_VERSION_PATCH;
108
import static org.jreleaser.model.Constants.KEY_VERSION_PRERELEASE;
109
import static org.jreleaser.model.Constants.KEY_VERSION_TAG;
110
import static org.jreleaser.model.Constants.KEY_VERSION_WEEK;
111
import static org.jreleaser.model.Constants.KEY_VERSION_YEAR;
112
import static org.jreleaser.model.internal.common.Matrix.replaceWithMatrix;
113
import static org.jreleaser.util.CollectionUtils.safePut;
114
import static org.jreleaser.util.StringUtils.capitalize;
115
import static org.jreleaser.util.StringUtils.isBlank;
116
import static org.jreleaser.util.StringUtils.isNotBlank;
117

118
/**
119
 * @author Andres Almiray
120
 * @since 0.1.0
121
 */
122
public class JReleaserContext {
123
    private final JReleaserLogger logger;
124
    private final JReleaserModel model;
125
    private final Path basedir;
126
    private final Path outputDirectory;
127
    private final boolean yolo;
128
    private final boolean dryrun;
129
    private final boolean strict;
130
    private final boolean gitRootSearch;
131
    private final org.jreleaser.model.api.JReleaserContext.Mode mode;
132
    private final JReleaserCommand command;
133
    private final Configurer configurer;
134
    private final Errors errors = new Errors();
1✔
135
    private final Changelog changelog = new Changelog();
1✔
136
    private final Map<String, Object> additionalProperties = new LinkedHashMap<>();
1✔
137

138
    private final List<String> selectedPlatforms = new ArrayList<>();
1✔
139
    private final List<String> rejectedPlatforms = new ArrayList<>();
1✔
140
    private final List<String> includedAnnouncers = new ArrayList<>();
1✔
141
    private final List<String> includedAssemblers = new ArrayList<>();
1✔
142
    private final List<String> includedCatalogers = new ArrayList<>();
1✔
143
    private final List<String> includedDistributions = new ArrayList<>();
1✔
144
    private final List<String> includedPackagers = new ArrayList<>();
1✔
145
    private final List<String> includedDownloaderTypes = new ArrayList<>();
1✔
146
    private final List<String> includedDownloaderNames = new ArrayList<>();
1✔
147
    private final List<String> includedDeployerTypes = new ArrayList<>();
1✔
148
    private final List<String> includedDeployerNames = new ArrayList<>();
1✔
149
    private final List<String> includedUploaderTypes = new ArrayList<>();
1✔
150
    private final List<String> includedUploaderNames = new ArrayList<>();
1✔
151
    private final List<String> excludedAnnouncers = new ArrayList<>();
1✔
152
    private final List<String> excludedAssemblers = new ArrayList<>();
1✔
153
    private final List<String> excludedCatalogers = new ArrayList<>();
1✔
154
    private final List<String> excludedDistributions = new ArrayList<>();
1✔
155
    private final List<String> excludedPackagers = new ArrayList<>();
1✔
156
    private final List<String> excludedDownloaderTypes = new ArrayList<>();
1✔
157
    private final List<String> excludedDownloaderNames = new ArrayList<>();
1✔
158
    private final List<String> excludedDeployerTypes = new ArrayList<>();
1✔
159
    private final List<String> excludedDeployerNames = new ArrayList<>();
1✔
160
    private final List<String> excludedUploaderTypes = new ArrayList<>();
1✔
161
    private final List<String> excludedUploaderNames = new ArrayList<>();
1✔
162
    private final List<WorkflowListener> workflowListeners = new ArrayList<>();
1✔
163

164
    private org.jreleaser.model.spi.release.Releaser<?> releaser;
165
    private final JReleaserScriptEvaluator scriptEvaluator = new JReleaserScriptEvaluator();
1✔
166

167
    @JsonIgnore
1✔
168
    private final org.jreleaser.model.api.JReleaserContext immutable = new org.jreleaser.model.api.JReleaserContext() {
1✔
169
        private static final long serialVersionUID = -4823233546663741626L;
170

171
        @Override
172
        public Path relativize(Path basedir, Path other) {
173
            return JReleaserContext.this.relativize(basedir, other);
×
174
        }
175

176
        @Override
177
        public Path relativizeToBasedir(Path other) {
178
            return JReleaserContext.this.relativizeToBasedir(other);
1✔
179
        }
180

181
        @Override
182
        public JReleaserLogger getLogger() {
183
            return logger;
1✔
184
        }
185

186
        @Override
187
        public Mode getMode() {
188
            return mode;
×
189
        }
190

191
        @Override
192
        public org.jreleaser.model.api.JReleaserModel getModel() {
193
            return model.asImmutable();
1✔
194
        }
195

196
        @Override
197
        public Path getBasedir() {
198
            return JReleaserContext.this.getBasedir();
×
199
        }
200

201
        @Override
202
        public Path getOutputDirectory() {
203
            return JReleaserContext.this.getOutputDirectory();
×
204
        }
205

206
        @Override
207
        public Path getChecksumsDirectory() {
208
            return JReleaserContext.this.getChecksumsDirectory();
×
209
        }
210

211
        @Override
212
        public Path getCatalogsDirectory() {
213
            return JReleaserContext.this.getCatalogsDirectory();
×
214
        }
215

216
        @Override
217
        public Path getSignaturesDirectory() {
218
            return JReleaserContext.this.getSignaturesDirectory();
×
219
        }
220

221
        @Override
222
        public Path getPrepareDirectory() {
223
            return JReleaserContext.this.getPrepareDirectory();
×
224
        }
225

226
        @Override
227
        public Path getPackageDirectory() {
228
            return JReleaserContext.this.getPackageDirectory();
×
229
        }
230

231
        @Override
232
        public Path getPublishDirectory() {
NEW
233
            return JReleaserContext.this.getPublishDirectory();
×
234
        }
235

236
        @Override
237
        public Path getAssembleDirectory() {
238
            return JReleaserContext.this.getAssembleDirectory();
×
239
        }
240

241
        @Override
242
        public Path getDownloadDirectory() {
243
            return JReleaserContext.this.getDownloadDirectory();
×
244
        }
245

246
        @Override
247
        public Path getArtifactsDirectory() {
248
            return JReleaserContext.this.getArtifactsDirectory();
×
249
        }
250

251
        @Override
252
        public Path getDeployDirectory() {
253
            return JReleaserContext.this.getDeployDirectory();
×
254
        }
255

256
        @Override
257
        public boolean isYolo() {
258
            return JReleaserContext.this.isYolo();
×
259
        }
260

261
        @Override
262
        public boolean isDryrun() {
263
            return JReleaserContext.this.isDryrun();
1✔
264
        }
265

266
        @Override
267
        public boolean isStrict() {
268
            return JReleaserContext.this.isStrict();
×
269
        }
270

271
        @Override
272
        public boolean isGitRootSearch() {
273
            return JReleaserContext.this.isGitRootSearch();
×
274
        }
275

276
        @Override
277
        public List<String> getIncludedAnnouncers() {
278
            return unmodifiableList(JReleaserContext.this.getIncludedAnnouncers());
×
279
        }
280

281
        @Override
282
        public List<String> getIncludedAssemblers() {
283
            return unmodifiableList(JReleaserContext.this.getIncludedAssemblers());
×
284
        }
285

286
        @Override
287
        public List<String> getIncludedDistributions() {
288
            return unmodifiableList(JReleaserContext.this.getIncludedDistributions());
×
289
        }
290

291
        @Override
292
        public List<String> getIncludedPackagers() {
293
            return unmodifiableList(JReleaserContext.this.getIncludedPackagers());
×
294
        }
295

296
        @Override
297
        public List<String> getIncludedDownloaderTypes() {
298
            return unmodifiableList(JReleaserContext.this.getIncludedDownloaderTypes());
×
299
        }
300

301
        @Override
302
        public List<String> getIncludedDownloaderNames() {
303
            return unmodifiableList(JReleaserContext.this.getIncludedDownloaderNames());
×
304
        }
305

306
        @Override
307
        public List<String> getIncludedDeployerTypes() {
308
            return unmodifiableList(JReleaserContext.this.getIncludedDeployerTypes());
×
309
        }
310

311
        @Override
312
        public List<String> getIncludedDeployerNames() {
313
            return unmodifiableList(JReleaserContext.this.getIncludedDeployerNames());
×
314
        }
315

316
        @Override
317
        public List<String> getIncludedUploaderTypes() {
318
            return unmodifiableList(JReleaserContext.this.getIncludedUploaderTypes());
×
319
        }
320

321
        @Override
322
        public List<String> getIncludedUploaderNames() {
323
            return unmodifiableList(JReleaserContext.this.getIncludedUploaderNames());
×
324
        }
325

326
        @Override
327
        public List<String> getExcludedAnnouncers() {
328
            return unmodifiableList(JReleaserContext.this.getExcludedAnnouncers());
×
329
        }
330

331
        @Override
332
        public List<String> getExcludedAssemblers() {
333
            return unmodifiableList(JReleaserContext.this.getExcludedAssemblers());
×
334
        }
335

336
        @Override
337
        public List<String> getExcludedDistributions() {
338
            return unmodifiableList(JReleaserContext.this.getExcludedDistributions());
×
339
        }
340

341
        @Override
342
        public List<String> getExcludedPackagers() {
343
            return unmodifiableList(JReleaserContext.this.getExcludedPackagers());
×
344
        }
345

346
        @Override
347
        public List<String> getExcludedDownloaderTypes() {
348
            return unmodifiableList(JReleaserContext.this.getExcludedDownloaderTypes());
×
349
        }
350

351
        @Override
352
        public List<String> getExcludedDownloaderNames() {
353
            return unmodifiableList(JReleaserContext.this.getExcludedDownloaderNames());
×
354
        }
355

356
        @Override
357
        public List<String> getExcludedDeployerTypes() {
358
            return unmodifiableList(JReleaserContext.this.getExcludedDeployerTypes());
×
359
        }
360

361
        @Override
362
        public List<String> getExcludedDeployerNames() {
363
            return unmodifiableList(JReleaserContext.this.getExcludedDeployerNames());
×
364
        }
365

366
        @Override
367
        public List<String> getExcludedUploaderTypes() {
368
            return unmodifiableList(JReleaserContext.this.getExcludedUploaderTypes());
×
369
        }
370

371
        @Override
372
        public List<String> getExcludedUploaderNames() {
373
            return unmodifiableList(JReleaserContext.this.getExcludedUploaderNames());
×
374
        }
375

376
        @Override
377
        public JReleaserCommand getCommand() {
378
            return JReleaserContext.this.getCommand();
×
379
        }
380

381
        @Override
382
        public TemplateContext props() {
383
            return JReleaserContext.this.props();
×
384
        }
385

386
        @Override
387
        public TemplateContext fullProps() {
388
            return JReleaserContext.this.fullProps();
×
389
        }
390

391
        @Override
392
        public void nag(String version, String message) {
393
            JReleaserContext.this.nag(version, message);
×
394
        }
×
395

396
        @Override
397
        public Keyring createKeyring() throws SigningException {
398
            return JReleaserContext.this.createKeyring();
1✔
399
        }
400

401
        @Override
402
        public Changelog getChangelog() {
403
            return JReleaserContext.this.changelog;
×
404
        }
405

406
        @Override
407
        public Map<String, Object> getAdditionalProperties() {
408
            return unmodifiableMap(JReleaserContext.this.getAdditionalProperties());
×
409
        }
410
    };
411

412
    public static JReleaserContext empty() {
413
        Path basedir = Paths.get(System.getProperty("user.dir"));
1✔
414
        return new JReleaserContext(new SimpleJReleaserLoggerAdapter(SimpleJReleaserLoggerAdapter.Level.DEBUG),
1✔
415
            null,
416
            org.jreleaser.model.api.JReleaserContext.Mode.FULL,
417
            JReleaserCommand.FULL_RELEASE,
418
            new JReleaserModel(),
419
            basedir,
420
            basedir.resolve("out/jreleaser"),
1✔
421
            false,
422
            true,
423
            true,
424
            false,
425
            Collections.emptyList(),
1✔
426
            Collections.emptyList());
1✔
427
    }
428

429
    public JReleaserContext(JReleaserLogger logger,
430
                            Configurer configurer,
431
                            org.jreleaser.model.api.JReleaserContext.Mode mode,
432
                            JReleaserCommand command,
433
                            JReleaserModel model,
434
                            Path basedir,
435
                            Path outputDirectory,
436
                            boolean yolo,
437
                            boolean dryrun,
438
                            boolean gitRootSearch,
439
                            boolean strict,
440
                            List<String> selectedPlatforms,
441
                            List<String> rejectedPlatforms) {
1✔
442
        this.logger = logger;
1✔
443
        this.configurer = configurer;
1✔
444
        this.mode = mode;
1✔
445
        this.command = command;
1✔
446
        this.model = model;
1✔
447
        this.basedir = basedir;
1✔
448
        this.outputDirectory = outputDirectory;
1✔
449
        this.yolo = yolo;
1✔
450
        this.dryrun = dryrun;
1✔
451
        this.gitRootSearch = gitRootSearch;
1✔
452
        this.strict = strict;
1✔
453
        this.selectedPlatforms.addAll(selectedPlatforms.stream()
1✔
454
            .filter(PlatformUtils::isSupported)
1✔
455
            .collect(toList()));
1✔
456

457
        try {
458
            logger.increaseIndent();
1✔
459
            logger.debug(RB.$("context.path.set", Constants.KEY_BASEDIR, getBasedir()));
1✔
460
            logger.debug(RB.$("context.path.set", Constants.KEY_BASE_OUTPUT_DIRECTORY, getOutputDirectory().getParent()));
1✔
461
            logger.debug(RB.$("context.path.set", Constants.KEY_OUTPUT_DIRECTORY, getOutputDirectory()));
1✔
462
            logger.debug(RB.$("context.path.set", Constants.KEY_CHECKSUMS_DIRECTORY, getChecksumsDirectory()));
1✔
463
            logger.debug(RB.$("context.path.set", Constants.KEY_CATALOGS_DIRECTORY, getCatalogsDirectory()));
1✔
464
            logger.debug(RB.$("context.path.set", Constants.KEY_SIGNATURES_DIRECTORY, getSignaturesDirectory()));
1✔
465
            logger.debug(RB.$("context.path.set", Constants.KEY_PREPARE_DIRECTORY, getPrepareDirectory()));
1✔
466
            logger.debug(RB.$("context.path.set", Constants.KEY_PACKAGE_DIRECTORY, getPackageDirectory()));
1✔
467
            logger.debug(RB.$("context.path.set", Constants.KEY_PUBLISH_DIRECTORY, getPublishDirectory()));
1✔
468
            logger.debug(RB.$("context.path.set", Constants.KEY_DOWNLOAD_DIRECTORY, getDownloadDirectory()));
1✔
469
            logger.debug(RB.$("context.path.set", Constants.KEY_ASSEMBLE_DIRECTORY, getAssembleDirectory()));
1✔
470
            logger.debug(RB.$("context.path.set", Constants.KEY_ARTIFACTS_DIRECTORY, getArtifactsDirectory()));
1✔
471
            logger.debug(RB.$("context.path.set", Constants.KEY_DEPLOY_DIRECTORY, getDeployDirectory()));
1✔
472
        } finally {
473
            logger.decreaseIndent();
1✔
474
        }
475

476
        List<String> unmatchedPlatforms = new ArrayList<>(selectedPlatforms);
1✔
477
        unmatchedPlatforms.removeAll(this.selectedPlatforms);
1✔
478
        if (!unmatchedPlatforms.isEmpty()) {
1✔
479
            logger.warn(RB.$("context.platform.selection.active"));
×
480
            logger.error(RB.$("context.platform.selection.no.match"), unmatchedPlatforms);
×
481
            logger.error(RB.$("context.platform.selection.valid"),
×
482
                System.lineSeparator(), PlatformUtils.getSupportedOsNames(),
×
483
                System.lineSeparator(), PlatformUtils.getSupportedOsArchs());
×
484
            throw new JReleaserException(RB.$("context.platform.selection.unmatched", unmatchedPlatforms));
×
485
        }
486

487
        if (!this.selectedPlatforms.isEmpty()) {
1✔
488
            logger.warn(RB.$("context.platform.selection.active"));
1✔
489
            logger.warn(RB.$("context.platform.selection.artifacts"), this.selectedPlatforms);
1✔
490
        }
491

492
        this.rejectedPlatforms.addAll(rejectedPlatforms);
1✔
493
        if (!this.rejectedPlatforms.isEmpty()) {
1✔
494
            logger.warn(RB.$("context.platform.selection.active"));
×
495
            logger.warn(RB.$("context.platform.rejection.artifacts"), this.rejectedPlatforms);
×
496
        }
497
    }
1✔
498

499
    public org.jreleaser.model.api.JReleaserContext asImmutable() {
500
        return immutable;
1✔
501
    }
502

503
    public Object eval(String script) {
504
        return scriptEvaluator.eval(this, script);
×
505
    }
506

507
    public Path relativize(Path basedir, Path other) {
508
        return basedir.toAbsolutePath().relativize(other.toAbsolutePath());
1✔
509
    }
510

511
    public Path relativizeToBasedir(Path other) {
512
        return relativize(basedir, other);
1✔
513
    }
514

515
    public Path relativize(Path basedir, String other) {
516
        return relativize(basedir, Paths.get(other));
×
517
    }
518

519
    public Path relativizeToBasedir(String other) {
520
        return relativize(basedir, other);
×
521
    }
522

523
    public Errors validateModel() {
524
        if (errors.hasErrors()) return errors;
1✔
525

526
        this.model.getEnvironment().initProps(this);
1✔
527

528
        logger.info(RB.$("context.configuration.validation"));
1✔
529
        logger.info(RB.$("context.configuration.strict", strict));
1✔
530

531
        if (mode.validateConfig()) {
1✔
532
            adjustDistributions();
1✔
533
        }
534

535
        try {
536
            JReleaserModelValidator.validate(this, this.mode, errors);
1✔
537
        } catch (Exception e) {
×
538
            logger.trace(e);
×
539
            errors.configuration(e.toString());
×
540
        }
1✔
541

542
        if (errors.hasWarnings()) {
1✔
543
            logger.warn("== JReleaser ==");
×
544
            errors.logWarnings(logger);
×
545
        }
546
        if (errors.hasErrors()) {
1✔
547
            logger.error("== JReleaser ==");
×
548
            errors.logErrors(logger);
×
549
        }
550

551
        return errors;
1✔
552
    }
553

554
    private void adjustDistributions() {
555
        logger.debug(RB.$("context.adjust.assemblies"));
1✔
556

557
        // resolve assemblers
558
        try {
559
            JReleaserModelValidator.validate(this, org.jreleaser.model.api.JReleaserContext.Mode.ASSEMBLE, errors);
1✔
560
            JReleaserModelResolver.resolve(this, errors);
1✔
561
        } catch (Exception e) {
×
562
            logger.trace(e);
×
563
            errors.configuration(e.toString());
×
564
        }
1✔
565

566
        // match distributions
567
        for (org.jreleaser.model.internal.assemble.Assembler<?> assembler : model.getAssemble().findAllAssemblers()) {
1✔
568
            if (!assembler.isExported()) continue;
1✔
569

570
            org.jreleaser.model.internal.distributions.Distribution distribution = model.getDistributions().get(assembler.getName());
1✔
571
            if (null == distribution) {
1✔
572
                distribution = new org.jreleaser.model.internal.distributions.Distribution();
1✔
573
                distribution.setType(assembler.getDistributionType());
1✔
574
                distribution.setStereotype(assembler.getStereotype());
1✔
575
                distribution.setName(assembler.getName());
1✔
576
                model.getDistributions().put(assembler.getName(), distribution);
1✔
577
            }
578
            distribution.setName(assembler.getName());
1✔
579
            distribution.setType(assembler.getDistributionType());
1✔
580

581
            distribution.setActive(Active.NEVER);
1✔
582
            if (isDistributionSelected(distribution.getName())) {
1✔
583
                distribution.setActive(assembler.getActive());
1✔
584
            }
585

586
            if (assembler instanceof JavaAssembler) {
1✔
587
                distribution.getExecutable().setName(((JavaAssembler<?>) assembler).getExecutable());
1✔
588
                distribution.setJava(((JavaAssembler<?>) assembler).getJava());
1✔
589
                if (assembler instanceof NativeImageAssembler) {
1✔
590
                    distribution.getExecutable().setWindowsExtension(FileType.EXE.type());
1✔
591
                    distribution.getExtraProperties().put(KEY_GRAALVM_NAGIVE_IMAGE, "true");
1✔
592
                    NativeImageAssembler nia = (NativeImageAssembler) assembler;
1✔
593
                    if (!nia.getArchiving().isEnabled()) {
1✔
594
                        distribution.setType(org.jreleaser.model.Distribution.DistributionType.FLAT_BINARY);
×
595
                    }
596
                }
1✔
597
            } else if (assembler instanceof JavaArchiveAssembler) {
1✔
598
                JavaArchiveAssembler javaArchiveAssembler = (JavaArchiveAssembler) assembler;
1✔
599
                distribution.getExecutable().setName(javaArchiveAssembler.getExecutable().getName());
1✔
600
                distribution.getExecutable().setUnixExtension(javaArchiveAssembler.getExecutable().getUnixExtension());
1✔
601
                distribution.getExecutable().setWindowsExtension(javaArchiveAssembler.getExecutable().getWindowsExtension());
1✔
602
                distribution.getJava().setMainClass(javaArchiveAssembler.getJava().getMainClass());
1✔
603
                distribution.getJava().setMainModule(javaArchiveAssembler.getJava().getMainModule());
1✔
604
                distribution.getJava().setJvmOptions(javaArchiveAssembler.getJava().getJvmOptions());
1✔
605
                distribution.getJava().setEnvironmentVariables(javaArchiveAssembler.getJava().getEnvironmentVariables());
1✔
606
            } else if (assembler instanceof DebAssembler) {
1✔
607
                distribution.getExecutable().setName(((DebAssembler) assembler).getExecutable());
1✔
608
            }
609
            mergeArtifacts(assembler, distribution);
1✔
610

611
            Map<String, Object> extraProperties = new LinkedHashMap<>(distribution.getExtraProperties());
1✔
612
            extraProperties.putAll(assembler.getExtraProperties());
1✔
613
            distribution.mergeExtraProperties(extraProperties);
1✔
614
        }
1✔
615

616
        resolveArtifactPatterns();
1✔
617
    }
1✔
618

619
    private void resolveArtifactPatterns() {
620
        for (org.jreleaser.model.internal.distributions.Distribution distribution : model.getDistributions().values()) {
1✔
621
            if (distribution.isApplyDefaultMatrix()) {
1✔
622
                distribution.setMatrix(model.getMatrix());
×
623
            }
624

625
            if (!distribution.getMatrix().isEmpty() && isNotBlank(distribution.getArtifactPattern().getPath())) {
1✔
626
                List<Artifact> artifacts = new ArrayList<>();
×
627
                for (Map<String, String> matrixRow : distribution.getMatrix().resolve()) {
×
628
                    artifacts.add(createArtifact(distribution.getArtifactPattern(), matrixRow));
×
629
                }
×
630
                mergeArtifacts(artifacts, distribution);
×
631
            }
632
        }
1✔
633
    }
1✔
634

635
    private Artifact createArtifact(Artifact artifactPattern, Map<String, String> matrix) {
636
        Artifact artifact = new Artifact();
×
637
        artifact.setPlatform(matrix.get(KEY_PLATFORM));
×
638

639
        artifact.setPath(replaceWithMatrix(artifactPattern.getPath(), matrix));
×
640
        artifact.setTransform(replaceWithMatrix(artifactPattern.getTransform(), matrix));
×
641

642
        for (Map.Entry<String, Object> property : artifactPattern.getExtraProperties().entrySet()) {
×
643
            artifact.addExtraProperty(property.getKey(), replaceWithMatrix(property.getValue(), matrix));
×
644
        }
×
645

646
        for (Map.Entry<String, String> property : matrix.entrySet()) {
×
647
            if (property.getKey().startsWith("extraProperties.")) {
×
648
                String key = property.getKey().substring("extraProperties.".length());
×
649
                artifact.addExtraProperty(key, property.getValue());
×
650
            }
651
        }
×
652

653
        return artifact;
×
654
    }
655

656
    private void mergeArtifacts(org.jreleaser.model.internal.assemble.Assembler<?> assembler, org.jreleaser.model.internal.distributions.Distribution distribution) {
657
        for (Artifact incoming : assembler.getOutputs()) {
1✔
658
            Optional<Artifact> artifact = distribution.getArtifacts().stream()
1✔
659
                .filter(other -> {
1✔
660
                    if (isPlatformSelected(incoming)) incoming.select();
1✔
661
                    if (isPlatformSelected(other)) other.select();
1✔
662
                    if (incoming.isSelected() && other.isSelected()) {
1✔
663
                        Path p1 = incoming.getResolvedPath(this, assembler);
1✔
664
                        Path p2 = other.getResolvedPath(this, distribution);
1✔
665
                        return p1.equals(p2);
1✔
666
                    }
667
                    return false;
×
668
                })
669
                .findFirst();
1✔
670
            if (artifact.isPresent()) {
1✔
671
                artifact.get().mergeWith(incoming);
1✔
672
            } else {
673
                distribution.addArtifact(incoming);
1✔
674
            }
675
        }
1✔
676
    }
1✔
677

678
    private void mergeArtifacts(List<Artifact> artifacts, org.jreleaser.model.internal.distributions.Distribution distribution) {
679
        for (Artifact incoming : artifacts) {
×
680
            Optional<Artifact> artifact = distribution.getArtifacts().stream()
×
681
                .filter(other -> {
×
682
                    if (isPlatformSelected(incoming)) incoming.select();
×
683
                    if (isPlatformSelected(other)) other.select();
×
684
                    if (incoming.isSelected() && other.isSelected()) {
×
685
                        Path p1 = incoming.getResolvedPath(this, distribution);
×
686
                        Path p2 = other.getResolvedPath(this, distribution);
×
687
                        return p1.equals(p2);
×
688
                    }
689
                    return false;
×
690
                })
691
                .findFirst();
×
692
            if (artifact.isPresent()) {
×
693
                artifact.get().mergeWith(incoming);
×
694
            } else {
695
                distribution.addArtifact(incoming);
×
696
            }
697
        }
×
698
    }
×
699

700
    public boolean isDistributionSelected(String distributionName) {
701
        if (!getIncludedDistributions().isEmpty() && getIncludedDistributions().contains(distributionName)) {
1✔
702
            return true;
×
703
        } else if (!getExcludedDistributions().isEmpty() && !getExcludedDistributions().contains(distributionName)) {
1✔
704
            return true;
×
705
        } else if (getIncludedDistributions().isEmpty() && getExcludedDistributions().isEmpty()) {
1✔
706
            return true;
1✔
707
        }
708

709
        return false;
×
710
    }
711

712
    public boolean isPlatformSelected(Artifact artifact) {
713
        return isPlatformSelected(artifact.getPlatform(), new Platform());
1✔
714
    }
715

716
    public boolean isPlatformSelected(Artifact artifact, Platform platform) {
717
        return isPlatformSelected(artifact.getPlatform(), platform);
×
718
    }
719

720
    public boolean isPlatformSelected(String platform) {
721
        return isPlatformSelected(platform, new Platform());
1✔
722
    }
723

724
    public boolean isPlatformSelected(String platform, Platform replacements) {
725
        if (isBlank(platform)) return true;
1✔
726

727
        if (!selectedPlatforms.isEmpty()) {
1✔
728
            return selectedPlatforms.stream()
1✔
729
                .anyMatch(selected -> PlatformUtils.isCompatible(replacements.applyReplacements(selected), platform));
1✔
730
        }
731

732
        if (!rejectedPlatforms.isEmpty()) {
1✔
733
            return rejectedPlatforms.stream()
×
734
                .noneMatch(selected -> PlatformUtils.isCompatible(replacements.applyReplacements(selected), platform));
×
735
        }
736

737
        return true;
1✔
738
    }
739

740
    public JReleaserLogger getLogger() {
741
        return logger;
1✔
742
    }
743

744
    public Configurer getConfigurer() {
745
        return configurer;
1✔
746
    }
747

748
    public org.jreleaser.model.api.JReleaserContext.Mode getMode() {
749
        return mode;
1✔
750
    }
751

752
    public JReleaserModel getModel() {
753
        return model;
1✔
754
    }
755

756
    public Path getBasedir() {
757
        return basedir;
1✔
758
    }
759

760
    public Path getOutputDirectory() {
761
        return outputDirectory;
1✔
762
    }
763

764
    public Path getChecksumsDirectory() {
765
        return outputDirectory.resolve("checksums");
1✔
766
    }
767

768
    public Path getCatalogsDirectory() {
769
        return outputDirectory.resolve("catalogs");
1✔
770
    }
771

772
    public Path getSignaturesDirectory() {
773
        return outputDirectory.resolve("signatures");
1✔
774
    }
775

776
    public Path getPrepareDirectory() {
777
        return outputDirectory.resolve("prepare");
1✔
778
    }
779

780
    public Path getPackageDirectory() {
781
        return outputDirectory.resolve("package");
1✔
782
    }
783

784
    public Path getPublishDirectory() {
785
        return outputDirectory.resolve("publish");
1✔
786
    }
787

788
    public Path getAssembleDirectory() {
789
        return outputDirectory.resolve("assemble");
1✔
790
    }
791

792
    public Path getDownloadDirectory() {
793
        return outputDirectory.resolve("download");
1✔
794
    }
795

796
    public Path getArtifactsDirectory() {
797
        return outputDirectory.resolve("artifacts");
1✔
798
    }
799

800
    public Path getDeployDirectory() {
801
        return outputDirectory.resolve("deploy");
1✔
802
    }
803

804
    public boolean isYolo() {
805
        return yolo;
1✔
806
    }
807

808
    public boolean isDryrun() {
809
        return dryrun;
1✔
810
    }
811

812
    public boolean isGitRootSearch() {
813
        return gitRootSearch;
1✔
814
    }
815

816
    public boolean isStrict() {
817
        return strict;
1✔
818
    }
819

820
    public Changelog getChangelog() {
821
        return changelog;
1✔
822
    }
823

824
    public org.jreleaser.model.spi.release.Releaser<?> getReleaser() {
825
        return releaser;
1✔
826
    }
827

828
    public void setReleaser(org.jreleaser.model.spi.release.Releaser<?> releaser) {
829
        this.releaser = releaser;
1✔
830
    }
1✔
831

832
    private List<String> normalize(List<String> list) {
833
        if (null == list || list.isEmpty()) return Collections.emptyList();
1✔
834

835
        List<String> tmp = new ArrayList<>(list);
×
836
        for (int i = 0; i < tmp.size(); i++) {
×
837
            String s = tmp.get(i).trim();
×
838
            if (!s.contains("-")) {
×
839
                s = StringUtils.getHyphenatedName(s);
×
840
            }
841
            tmp.set(i, s.toLowerCase(Locale.ENGLISH));
×
842
        }
843

844
        return tmp;
×
845
    }
846

847
    private List<String> compact(List<String> list) {
848
        if (null == list || list.isEmpty()) return Collections.emptyList();
1✔
849

850
        return list.stream()
1✔
851
            .map(s -> s.toLowerCase(Locale.ENGLISH))
1✔
852
            .map(s -> s.replace("-", ""))
1✔
853
            .map(s -> s.replace(" ", ""))
1✔
854
            .collect(toList());
1✔
855
    }
856

857
    public List<WorkflowListener> getWorkflowListeners() {
858
        return workflowListeners;
×
859
    }
860

861
    public void setWorkflowListeners(Collection<WorkflowListener> workflowListeners) {
862
        this.workflowListeners.clear();
1✔
863
        this.workflowListeners.addAll(workflowListeners);
1✔
864
    }
1✔
865

866
    public List<String> getIncludedAnnouncers() {
867
        return includedAnnouncers;
1✔
868
    }
869

870
    public void setIncludedAnnouncers(List<String> includedAnnouncers) {
UNCOV
871
        this.includedAnnouncers.clear();
×
UNCOV
872
        this.includedAnnouncers.addAll(normalize(includedAnnouncers));
×
UNCOV
873
    }
×
874

875
    public List<String> getIncludedAssemblers() {
876
        return includedAssemblers;
1✔
877
    }
878

879
    public void setIncludedAssemblers(List<String> includedAssemblerTypes) {
880
        this.includedAssemblers.clear();
1✔
881
        this.includedAssemblers.addAll(normalize(includedAssemblerTypes));
1✔
882
    }
1✔
883

884
    public List<String> getIncludedCatalogers() {
885
        return includedCatalogers;
1✔
886
    }
887

888
    public void setIncludedCatalogers(List<String> includedCatalogers) {
889
        this.includedCatalogers.clear();
1✔
890
        this.includedCatalogers.addAll(normalize(includedCatalogers));
1✔
891
    }
1✔
892

893
    public List<String> getIncludedDistributions() {
894
        return includedDistributions;
1✔
895
    }
896

897
    public void setIncludedDistributions(List<String> includedDistributions) {
898
        this.includedDistributions.clear();
1✔
899
        this.includedDistributions.addAll(includedDistributions);
1✔
900
    }
1✔
901

902
    public List<String> getIncludedPackagers() {
903
        return includedPackagers;
1✔
904
    }
905

906
    public void setIncludedPackagers(List<String> includedPackagers) {
907
        this.includedPackagers.clear();
1✔
908
        this.includedPackagers.addAll(compact(includedPackagers));
1✔
909
    }
1✔
910

911
    public List<String> getIncludedDownloaderTypes() {
912
        return includedDownloaderTypes;
1✔
913
    }
914

915
    public void setIncludedDownloaderTypes(List<String> includedDownloaderTypes) {
916
        this.includedDownloaderTypes.clear();
1✔
917
        this.includedDownloaderTypes.addAll(normalize(includedDownloaderTypes));
1✔
918
    }
1✔
919

920
    public List<String> getIncludedDownloaderNames() {
921
        return includedDownloaderNames;
1✔
922
    }
923

924
    public void setIncludedDownloaderNames(List<String> includedDownloaderNames) {
925
        this.includedDownloaderNames.clear();
1✔
926
        this.includedDownloaderNames.addAll(includedDownloaderNames);
1✔
927
    }
1✔
928

929
    public List<String> getIncludedDeployerTypes() {
930
        return includedDeployerTypes;
1✔
931
    }
932

933
    public void setIncludedDeployerTypes(List<String> includedDeployerTypes) {
934
        this.includedDeployerTypes.clear();
1✔
935
        this.includedDeployerTypes.addAll(normalize(includedDeployerTypes));
1✔
936
    }
1✔
937

938
    public List<String> getIncludedDeployerNames() {
939
        return includedDeployerNames;
1✔
940
    }
941

942
    public void setIncludedDeployerNames(List<String> includedDeployerNames) {
943
        this.includedDeployerNames.clear();
1✔
944
        this.includedDeployerNames.addAll(includedDeployerNames);
1✔
945
    }
1✔
946

947
    public List<String> getIncludedUploaderTypes() {
948
        return includedUploaderTypes;
1✔
949
    }
950

951
    public void setIncludedUploaderTypes(List<String> includedUploaderTypes) {
952
        this.includedUploaderTypes.clear();
1✔
953
        this.includedUploaderTypes.addAll(normalize(includedUploaderTypes));
1✔
954
    }
1✔
955

956
    public List<String> getIncludedUploaderNames() {
957
        return includedUploaderNames;
1✔
958
    }
959

960
    public void setIncludedUploaderNames(List<String> includedUploaderNames) {
961
        this.includedUploaderNames.clear();
1✔
962
        this.includedUploaderNames.addAll(includedUploaderNames);
1✔
963
    }
1✔
964

965
    public List<String> getExcludedAnnouncers() {
966
        return excludedAnnouncers;
1✔
967
    }
968

969
    public void setExcludedAnnouncers(List<String> excludedAnnouncers) {
UNCOV
970
        this.excludedAnnouncers.clear();
×
UNCOV
971
        this.excludedAnnouncers.addAll(normalize(excludedAnnouncers));
×
UNCOV
972
    }
×
973

974
    public List<String> getExcludedAssemblers() {
975
        return excludedAssemblers;
1✔
976
    }
977

978
    public void setExcludedAssemblers(List<String> excludedAssemblerTypes) {
979
        this.excludedAssemblers.clear();
1✔
980
        this.excludedAssemblers.addAll(normalize(excludedAssemblerTypes));
1✔
981
    }
1✔
982

983
    public List<String> getExcludedCatalogers() {
984
        return excludedCatalogers;
1✔
985
    }
986

987
    public void setExcludedCatalogers(List<String> excludedCatalogers) {
988
        this.excludedCatalogers.clear();
1✔
989
        this.excludedCatalogers.addAll(normalize(excludedCatalogers));
1✔
990
    }
1✔
991

992
    public List<String> getExcludedDistributions() {
993
        return excludedDistributions;
1✔
994
    }
995

996
    public void setExcludedDistributions(List<String> excludedDistributions) {
997
        this.excludedDistributions.clear();
1✔
998
        this.excludedDistributions.addAll(excludedDistributions);
1✔
999
    }
1✔
1000

1001
    public List<String> getExcludedPackagers() {
1002
        return excludedPackagers;
1✔
1003
    }
1004

1005
    public void setExcludedPackagers(List<String> excludedPackagers) {
1006
        this.excludedPackagers.clear();
1✔
1007
        this.excludedPackagers.addAll(compact(excludedPackagers));
1✔
1008
    }
1✔
1009

1010
    public List<String> getExcludedDownloaderTypes() {
1011
        return excludedDownloaderTypes;
1✔
1012
    }
1013

1014
    public void setExcludedDownloaderTypes(List<String> excludedDownloaderTypes) {
1015
        this.excludedDownloaderTypes.clear();
1✔
1016
        this.excludedDownloaderTypes.addAll(normalize(excludedDownloaderTypes));
1✔
1017
    }
1✔
1018

1019
    public List<String> getExcludedDownloaderNames() {
1020
        return excludedDownloaderNames;
1✔
1021
    }
1022

1023
    public void setExcludedDownloaderNames(List<String> excludedDownloaderNames) {
1024
        this.excludedDownloaderNames.clear();
1✔
1025
        this.excludedDownloaderNames.addAll(excludedDownloaderNames);
1✔
1026
    }
1✔
1027

1028
    public List<String> getExcludedDeployerTypes() {
1029
        return excludedDeployerTypes;
1✔
1030
    }
1031

1032
    public void setExcludedDeployerTypes(List<String> excludedDeployerTypes) {
1033
        this.excludedDeployerTypes.clear();
1✔
1034
        this.excludedDeployerTypes.addAll(normalize(excludedDeployerTypes));
1✔
1035
    }
1✔
1036

1037
    public List<String> getExcludedDeployerNames() {
1038
        return excludedDeployerNames;
1✔
1039
    }
1040

1041
    public void setExcludedDeployerNames(List<String> excludedDeployerNames) {
1042
        this.excludedDeployerNames.clear();
1✔
1043
        this.excludedDeployerNames.addAll(excludedDeployerNames);
1✔
1044
    }
1✔
1045

1046
    public List<String> getExcludedUploaderTypes() {
1047
        return excludedUploaderTypes;
1✔
1048
    }
1049

1050
    public void setExcludedUploaderTypes(List<String> excludedUploaderTypes) {
1051
        this.excludedUploaderTypes.clear();
1✔
1052
        this.excludedUploaderTypes.addAll(normalize(excludedUploaderTypes));
1✔
1053
    }
1✔
1054

1055
    public List<String> getExcludedUploaderNames() {
1056
        return excludedUploaderNames;
1✔
1057
    }
1058

1059
    public void setExcludedUploaderNames(List<String> excludedUploaderNames) {
1060
        this.excludedUploaderNames.clear();
1✔
1061
        this.excludedUploaderNames.addAll(excludedUploaderNames);
1✔
1062
    }
1✔
1063

1064
    public JReleaserCommand getCommand() {
1065
        return command;
1✔
1066
    }
1067

1068
    public TemplateContext props() {
1069
        TemplateContext props = new TemplateContext(model.props());
1✔
1070
        props.set(Constants.KEY_BASEDIR, getBasedir());
1✔
1071
        props.set(Constants.KEY_BASE_OUTPUT_DIRECTORY, getOutputDirectory().getParent());
1✔
1072
        props.set(Constants.KEY_OUTPUT_DIRECTORY, getOutputDirectory());
1✔
1073
        props.set(Constants.KEY_CHECKSUMS_DIRECTORY, getChecksumsDirectory());
1✔
1074
        props.set(Constants.KEY_CATALOGS_DIRECTORY, getCatalogsDirectory());
1✔
1075
        props.set(Constants.KEY_SIGNATURES_DIRECTORY, getSignaturesDirectory());
1✔
1076
        props.set(Constants.KEY_PREPARE_DIRECTORY, getPrepareDirectory());
1✔
1077
        props.set(Constants.KEY_PACKAGE_DIRECTORY, getPackageDirectory());
1✔
1078
        props.set(Constants.KEY_PUBLISH_DIRECTORY, getPublishDirectory());
1✔
1079
        props.set(Constants.KEY_DOWNLOAD_DIRECTORY, getDownloadDirectory());
1✔
1080
        props.set(Constants.KEY_ASSEMBLE_DIRECTORY, getAssembleDirectory());
1✔
1081
        props.set(Constants.KEY_ARTIFACTS_DIRECTORY, getArtifactsDirectory());
1✔
1082
        props.set(Constants.KEY_DEPLOY_DIRECTORY, getDeployDirectory());
1✔
1083
        if (null != getCommand()) props.set(Constants.KEY_COMMAND, getCommand().toStep());
1✔
1084
        return props;
1✔
1085
    }
1086

1087
    public TemplateContext fullProps() {
1088
        TemplateContext props = new TemplateContext(props());
1✔
1089
        props.setAll(model.props());
1✔
1090
        return props;
1✔
1091
    }
1092

1093
    public Map<String, Object> getAdditionalProperties() {
1094
        return additionalProperties;
1✔
1095
    }
1096

1097
    @Override
1098
    public String toString() {
1099
        return "JReleaserContext[" +
×
1100
            "basedir=" + basedir.toAbsolutePath() +
×
1101
            ", outputDirectory=" + outputDirectory.toAbsolutePath() +
×
1102
            ", yolo=" + yolo +
1103
            ", dryrun=" + dryrun +
1104
            ", gitRootSearch=" + gitRootSearch +
1105
            ", strict=" + strict +
1106
            ", mode=" + mode +
1107
            "]";
1108
    }
1109

1110
    public void report() {
1111
        Project project = model.getProject();
1✔
1112

1113
        SortedProperties props = new SortedProperties();
1✔
1114
        props.put(KEY_TIMESTAMP, model.getTimestamp());
1✔
1115
        props.put(KEY_PLATFORM, PlatformUtils.getCurrentFull());
1✔
1116
        props.put(KEY_PLATFORM_REPLACED, model.getPlatform().applyReplacements(PlatformUtils.getCurrentFull()));
1✔
1117
        if (null != model.getCommit()) {
1✔
1118
            props.put(KEY_COMMIT_SHORT_HASH, model.getCommit().getShortHash());
1✔
1119
            props.put(KEY_COMMIT_FULL_HASH, model.getCommit().getFullHash());
1✔
1120
        }
1121
        props.put(KEY_PROJECT_NAME, project.getName());
1✔
1122
        props.put(KEY_PROJECT_VERSION, project.getVersion());
1✔
1123
        props.put(KEY_PROJECT_SNAPSHOT, String.valueOf(project.isSnapshot()));
1✔
1124
        if (null != model.getCommit()) {
1✔
1125
            BaseReleaser<?, ?> releaser = model.getRelease().getReleaser();
1✔
1126
            if (null != releaser) {
1✔
1127
                safePut(KEY_TAG_NAME, releaser.getEffectiveTagName(model), props);
1✔
1128
                String previousTagName = releaser.getResolvedPreviousTagName(model);
1✔
1129
                safePut(KEY_PREVIOUS_TAG_NAME, previousTagName, props);
1✔
1130
                safePut("releaseBranch", releaser.getBranch(), props);
1✔
1131
                if (releaser.isReleaseSupported()) {
1✔
1132
                    safePut(KEY_RELEASE_NAME, releaser.getEffectiveReleaseName(), props);
1✔
1133
                    safePut(KEY_MILESTONE_NAME, releaser.getMilestone().getEffectiveName(), props);
1✔
1134
                }
1135
            }
1136
        }
1137
        props.put("javaVersion", System.getProperty("java.version"));
1✔
1138
        props.put("javaVendor", System.getProperty("java.vendor"));
1✔
1139
        props.put("javaVmVersion", System.getProperty("java.vm.version"));
1✔
1140

1141
        Map<String, Object> resolvedExtraProperties = project.resolvedExtraProperties();
1✔
1142
        safePut(project.prefix() + capitalize(KEY_VERSION_MAJOR), resolvedExtraProperties, props);
1✔
1143
        safePut(project.prefix() + capitalize(KEY_VERSION_MINOR), resolvedExtraProperties, props);
1✔
1144
        safePut(project.prefix() + capitalize(KEY_VERSION_PATCH), resolvedExtraProperties, props);
1✔
1145
        safePut(project.prefix() + capitalize(KEY_VERSION_NUMBER), resolvedExtraProperties, props);
1✔
1146
        safePut(project.prefix() + capitalize(KEY_VERSION_PRERELEASE), resolvedExtraProperties, props);
1✔
1147
        safePut(project.prefix() + capitalize(KEY_VERSION_TAG), resolvedExtraProperties, props);
1✔
1148
        safePut(project.prefix() + capitalize(KEY_VERSION_BUILD), resolvedExtraProperties, props);
1✔
1149
        safePut(project.prefix() + capitalize(KEY_VERSION_OPTIONAL), resolvedExtraProperties, props);
1✔
1150
        safePut(project.prefix() + capitalize(KEY_VERSION_YEAR), resolvedExtraProperties, props);
1✔
1151
        safePut(project.prefix() + capitalize(KEY_VERSION_MONTH), resolvedExtraProperties, props);
1✔
1152
        safePut(project.prefix() + capitalize(KEY_VERSION_DAY), resolvedExtraProperties, props);
1✔
1153
        safePut(project.prefix() + capitalize(KEY_VERSION_WEEK), resolvedExtraProperties, props);
1✔
1154
        safePut(project.prefix() + capitalize(KEY_VERSION_MICRO), resolvedExtraProperties, props);
1✔
1155
        safePut(project.prefix() + capitalize(KEY_VERSION_MODIFIER), resolvedExtraProperties, props);
1✔
1156

1157
        props.putAll(getAdditionalProperties());
1✔
1158

1159
        Path output = getOutputDirectory().resolve("output.properties");
1✔
1160

1161
        try (FileOutputStream out = new FileOutputStream(output.toFile())) {
1✔
1162
            logger.info(RB.$("context.writing.properties"),
1✔
1163
                relativizeToBasedir(output));
1✔
1164
            props.store(out, "JReleaser " + JReleaserVersion.getPlainVersion());
1✔
1165
        } catch (IOException ignored) {
×
1166
            logger.warn(RB.$("context.writing.properties.error"),
×
1167
                relativizeToBasedir(output));
×
1168
        }
1✔
1169
    }
1✔
1170

1171
    public void nag(String version, String message) {
1172
        logger.warn(RB.$("context.nag", message, version));
×
1173
    }
×
1174

1175
    public Keyring createKeyring() throws SigningException {
1176
        try {
1177
            org.jreleaser.model.internal.signing.Signing signing = model.getSigning();
1✔
1178

1179
            if (!signing.isEnabled()) {
1✔
1180
                throw new SigningException(RB.$("ERROR_signing_disabled"));
×
1181
            }
1182

1183
            if (signing.getMode() == Signing.Mode.FILE) {
1✔
1184
                return new FilesKeyring(
×
1185
                    signing.isVerify() ? basedir.resolve(signing.getPublicKey()) : null,
×
1186
                    basedir.resolve(signing.getSecretKey())
×
1187
                ).initialize(signing.isArmored());
×
1188
            }
1189

1190
            return new InMemoryKeyring(
1✔
1191
                signing.isVerify() ? signing.getPublicKey().getBytes(UTF_8) : null,
1✔
1192
                signing.getSecretKey().getBytes(UTF_8)
1✔
1193
            ).initialize(signing.isArmored());
1✔
1194
        } catch (IOException | PGPException e) {
×
1195
            throw new SigningException(RB.$("ERROR_signing_init_keyring"), e);
×
1196
        }
1197
    }
1198

1199
    public boolean isDistributionIncluded(org.jreleaser.model.internal.distributions.Distribution distribution) {
1200
        String distributionName = distribution.getName();
1✔
1201

1202
        if (!includedDistributions.isEmpty()) {
1✔
1203
            return includedDistributions.contains(distributionName);
×
1204
        }
1205

1206
        if (!excludedDistributions.isEmpty()) {
1✔
1207
            return !excludedDistributions.contains(distributionName);
×
1208
        }
1209

1210
        return true;
1✔
1211
    }
1212

1213
    public void fireSessionStartEvent() throws WorkflowListenerException {
1214
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1215
            try {
1216
                workflowListener.onSessionStart(this.asImmutable());
×
1217
            } catch (RuntimeException e) {
×
1218
                throw new WorkflowListenerException(workflowListener, e);
×
1219
            }
×
1220
        }
×
1221
    }
1✔
1222

1223
    public void fireSessionEndEvent() throws WorkflowListenerException {
1224
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1225
            try {
1226
                workflowListener.onSessionEnd(this.asImmutable());
×
1227
            } catch (RuntimeException e) {
×
1228
                throw new WorkflowListenerException(workflowListener, e);
×
1229
            }
×
1230
        }
×
1231
    }
1✔
1232

1233
    public void fireWorkflowEvent(ExecutionEvent event) throws WorkflowListenerException {
1234
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1235
            try {
1236
                workflowListener.onWorkflowStep(event, this.asImmutable());
×
1237
            } catch (RuntimeException e) {
×
1238
                throw new WorkflowListenerException(workflowListener, e);
×
1239
            }
×
1240
        }
×
1241
    }
1✔
1242

1243
    public void fireAnnounceStepEvent(ExecutionEvent event, Announcer announcer) throws WorkflowListenerException {
UNCOV
1244
        for (WorkflowListener workflowListener : workflowListeners) {
×
1245
            try {
1246
                workflowListener.onAnnounceStep(event, this.asImmutable(), announcer);
×
1247
            } catch (RuntimeException e) {
×
1248
                throw new WorkflowListenerException(workflowListener, e);
×
1249
            }
×
1250
        }
×
UNCOV
1251
    }
×
1252

1253
    public void fireAssembleStepEvent(ExecutionEvent event, Assembler assembler) throws WorkflowListenerException {
1254
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1255
            try {
1256
                workflowListener.onAssembleStep(event, this.asImmutable(), assembler);
×
1257
            } catch (RuntimeException e) {
×
1258
                throw new WorkflowListenerException(workflowListener, e);
×
1259
            }
×
1260
        }
×
1261
    }
1✔
1262

1263
    public void fireCatalogStepEvent(ExecutionEvent event, Cataloger cataloger) throws WorkflowListenerException {
1264
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1265
            try {
1266
                workflowListener.onCatalogStep(event, this.asImmutable(), cataloger);
×
1267
            } catch (RuntimeException e) {
×
1268
                throw new WorkflowListenerException(workflowListener, e);
×
1269
            }
×
1270
        }
×
1271
    }
1✔
1272

1273
    public void fireDeployStepEvent(ExecutionEvent event, Deployer deployer) throws WorkflowListenerException {
1274
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1275
            try {
1276
                workflowListener.onDeployStep(event, this.asImmutable(), deployer);
×
1277
            } catch (RuntimeException e) {
×
1278
                throw new WorkflowListenerException(workflowListener, e);
×
1279
            }
×
1280
        }
×
1281
    }
1✔
1282

1283
    public void fireDownloadStepEvent(ExecutionEvent event, Downloader downloader) throws WorkflowListenerException {
1284
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1285
            try {
1286
                workflowListener.onDownloadStep(event, this.asImmutable(), downloader);
×
1287
            } catch (RuntimeException e) {
×
1288
                throw new WorkflowListenerException(workflowListener, e);
×
1289
            }
×
1290
        }
×
1291
    }
1✔
1292

1293
    public void fireUploadStepEvent(ExecutionEvent event, Uploader uploader) throws WorkflowListenerException {
1294
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1295
            try {
1296
                workflowListener.onUploadStep(event, this.asImmutable(), uploader);
×
1297
            } catch (RuntimeException e) {
×
1298
                throw new WorkflowListenerException(workflowListener, e);
×
1299
            }
×
1300
        }
×
1301
    }
1✔
1302

1303
    public void fireReleaseStepEvent(ExecutionEvent event, Releaser releaser) throws WorkflowListenerException {
1304
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1305
            try {
1306
                workflowListener.onReleaseStep(event, this.asImmutable(), releaser);
×
1307
            } catch (RuntimeException e) {
×
1308
                throw new WorkflowListenerException(workflowListener, e);
×
1309
            }
×
1310
        }
×
1311
    }
1✔
1312

1313
    public void fireDistributionStartEvent(Distribution distribution) throws WorkflowListenerException {
1314
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1315
            try {
1316
                workflowListener.onDistributionStart(this.asImmutable(), distribution);
×
1317
            } catch (RuntimeException e) {
×
1318
                throw new WorkflowListenerException(workflowListener, e);
×
1319
            }
×
1320
        }
×
1321
    }
1✔
1322

1323
    public void fireDistributionEndEvent(Distribution distribution) throws WorkflowListenerException {
1324
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1325
            try {
1326
                workflowListener.onDistributionEnd(this.asImmutable(), distribution);
×
1327
            } catch (RuntimeException e) {
×
1328
                throw new WorkflowListenerException(workflowListener, e);
×
1329
            }
×
1330
        }
×
1331
    }
1✔
1332

1333
    public void firePackagerPackageEvent(ExecutionEvent event, Distribution distribution, Packager packager) throws WorkflowListenerException {
1334
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1335
            try {
1336
                workflowListener.onPackagerPackageStep(event, this.asImmutable(), distribution, packager);
×
1337
            } catch (RuntimeException e) {
×
1338
                throw new WorkflowListenerException(workflowListener, e);
×
1339
            }
×
1340
        }
×
1341
    }
1✔
1342

1343
    public void firePackagerPublishEvent(ExecutionEvent event, Distribution distribution, Packager packager) throws WorkflowListenerException {
1344
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1345
            try {
1346
                workflowListener.onPackagerPublishStep(event, this.asImmutable(), distribution, packager);
×
1347
            } catch (RuntimeException e) {
×
1348
                throw new WorkflowListenerException(workflowListener, e);
×
1349
            }
×
1350
        }
×
1351
    }
1✔
1352

1353
    public void firePackagerPrepareEvent(ExecutionEvent event, Distribution distribution, Packager packager) throws WorkflowListenerException {
1354
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1355
            try {
1356
                workflowListener.onPackagerPrepareStep(event, this.asImmutable(), distribution, packager);
×
1357
            } catch (RuntimeException e) {
×
1358
                throw new WorkflowListenerException(workflowListener, e);
×
1359
            }
×
1360
        }
×
1361
    }
1✔
1362

1363
    public enum Configurer {
1✔
1364
        CLI("CLI flags"),
1✔
1365
        CLI_YAML("CLI yaml DSL"),
1✔
1366
        CLI_TOML("CLI toml DSL"),
1✔
1367
        CLI_JSON("CLI json DSL"),
1✔
1368
        MAVEN("Maven DSL"),
1✔
1369
        GRADLE("Gradle DSL");
1✔
1370

1371
        private final String dsl;
1372

1373
        Configurer(String dsl) {
1✔
1374
            this.dsl = dsl;
1✔
1375
        }
1✔
1376

1377
        @Override
1378
        public String toString() {
1379
            return this.dsl;
1✔
1380
        }
1381
    }
1382

1383
    private static class SortedProperties extends Properties {
1384
        private static final long serialVersionUID = 8794541421003888869L;
1385

1386
        // Java 11 calls entrySet() when storing properties
1387
        @Override
1388
        public Set<Map.Entry<Object, Object>> entrySet() {
1389
            int javaMajorVersion = SemanticVersion.javaMajorVersion();
1✔
1390
            if (javaMajorVersion < 11) {
1✔
1391
                return super.entrySet();
×
1392
            }
1393

1394
            Map<Object, Object> map = new TreeMap<>();
1✔
1395
            for (Object k : keySet()) {
1✔
1396
                map.put(String.valueOf(k), get(k));
1✔
1397
            }
1✔
1398
            return map.entrySet();
1✔
1399
        }
1400

1401
        // Java 8 calls keys() when storing properties
1402
        @Override
1403
        public synchronized Enumeration<Object> keys() {
1404
            int javaMajorVersion = SemanticVersion.javaMajorVersion();
×
1405
            if (javaMajorVersion >= 11) {
×
1406
                return super.keys();
×
1407
            }
1408

1409
            Set<Object> keySet = keySet();
×
1410
            List<String> keys = new ArrayList<>(keySet.size());
×
1411
            for (Object key : keySet) {
×
1412
                keys.add(key.toString());
×
1413
            }
×
1414
            Collections.sort(keys);
×
1415
            return new IteratorEnumeration<>(keys.iterator());
×
1416
        }
1417
    }
1418

1419
    private static class IteratorEnumeration<E> implements Enumeration<E> {
1420
        private final Iterator<? extends E> iterator;
1421

1422
        public IteratorEnumeration(Iterator<? extends E> iterator) {
×
1423
            this.iterator = iterator;
×
1424
        }
×
1425

1426
        @Override
1427
        public boolean hasMoreElements() {
1428
            return iterator.hasNext();
×
1429
        }
1430

1431
        @Override
1432
        public E nextElement() {
1433
            return iterator.next();
×
1434
        }
1435
    }
1436
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc