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

jreleaser / jreleaser / #486

23 May 2025 05:11PM UTC coverage: 48.584% (-0.09%) from 48.67%
#486

push

github

aalmiray
feat(core): Add a flag to skip non-configured sections. The yolo flag.

Closes #1840

160 of 217 new or added lines in 57 files covered. (73.73%)

438 existing lines in 34 files now uncovered.

25292 of 52058 relevant lines covered (48.58%)

0.49 hits per line

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

65.16
/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 = 8947541863163002549L;
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 getAssembleDirectory() {
233
            return JReleaserContext.this.getAssembleDirectory();
×
234
        }
235

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

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

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

251
        @Override
252
        public boolean isYolo() {
NEW
253
            return JReleaserContext.this.isYolo();
×
254
        }
255

256
        @Override
257
        public boolean isDryrun() {
258
            return JReleaserContext.this.isDryrun();
1✔
259
        }
260

261
        @Override
262
        public boolean isStrict() {
263
            return JReleaserContext.this.isStrict();
×
264
        }
265

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

271
        @Override
272
        public List<String> getIncludedAnnouncers() {
273
            return unmodifiableList(JReleaserContext.this.getIncludedAnnouncers());
×
274
        }
275

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

371
        @Override
372
        public JReleaserCommand getCommand() {
373
            return JReleaserContext.this.getCommand();
×
374
        }
375

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

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

386
        @Override
387
        public void nag(String version, String message) {
388
            JReleaserContext.this.nag(version, message);
×
389
        }
×
390

391
        @Override
392
        public Keyring createKeyring() throws SigningException {
393
            return JReleaserContext.this.createKeyring();
1✔
394
        }
395

396
        @Override
397
        public Changelog getChangelog() {
398
            return JReleaserContext.this.changelog;
×
399
        }
400

401
        @Override
402
        public Map<String, Object> getAdditionalProperties() {
403
            return unmodifiableMap(JReleaserContext.this.getAdditionalProperties());
×
404
        }
405
    };
406

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

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

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

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

481
        if (!this.selectedPlatforms.isEmpty()) {
1✔
482
            logger.warn(RB.$("context.platform.selection.active"));
1✔
483
            logger.warn(RB.$("context.platform.selection.artifacts"), this.selectedPlatforms);
1✔
484
        }
485

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

493
    public org.jreleaser.model.api.JReleaserContext asImmutable() {
494
        return immutable;
1✔
495
    }
496

497
    public Object eval(String script) {
498
        return scriptEvaluator.eval(this, script);
×
499
    }
500

501
    public Path relativize(Path basedir, Path other) {
502
        return basedir.toAbsolutePath().relativize(other.toAbsolutePath());
1✔
503
    }
504

505
    public Path relativizeToBasedir(Path other) {
506
        return relativize(basedir, other);
1✔
507
    }
508

509
    public Path relativize(Path basedir, String other) {
510
        return relativize(basedir, Paths.get(other));
×
511
    }
512

513
    public Path relativizeToBasedir(String other) {
514
        return relativize(basedir, other);
×
515
    }
516

517
    public Errors validateModel() {
518
        if (errors.hasErrors()) return errors;
1✔
519

520
        this.model.getEnvironment().initProps(this);
1✔
521

522
        logger.info(RB.$("context.configuration.validation"));
1✔
523
        logger.info(RB.$("context.configuration.strict", strict));
1✔
524

525
        if (mode.validateConfig()) {
1✔
526
            adjustDistributions();
1✔
527
        }
528

529
        try {
530
            JReleaserModelValidator.validate(this, this.mode, errors);
1✔
531
        } catch (Exception e) {
×
532
            logger.trace(e);
×
533
            errors.configuration(e.toString());
×
534
        }
1✔
535

536
        if (errors.hasWarnings()) {
1✔
UNCOV
537
            logger.warn("== JReleaser ==");
×
UNCOV
538
            errors.logWarnings(logger);
×
539
        }
540
        if (errors.hasErrors()) {
1✔
541
            logger.error("== JReleaser ==");
×
542
            errors.logErrors(logger);
×
543
        }
544

545
        return errors;
1✔
546
    }
547

548
    private void adjustDistributions() {
549
        logger.debug(RB.$("context.adjust.assemblies"));
1✔
550

551
        // resolve assemblers
552
        try {
553
            JReleaserModelValidator.validate(this, org.jreleaser.model.api.JReleaserContext.Mode.ASSEMBLE, errors);
1✔
554
            JReleaserModelResolver.resolve(this, errors);
1✔
555
        } catch (Exception e) {
×
556
            logger.trace(e);
×
557
            errors.configuration(e.toString());
×
558
        }
1✔
559

560
        // match distributions
561
        for (org.jreleaser.model.internal.assemble.Assembler<?> assembler : model.getAssemble().findAllAssemblers()) {
1✔
562
            if (!assembler.isExported()) continue;
1✔
563

564
            org.jreleaser.model.internal.distributions.Distribution distribution = model.getDistributions().get(assembler.getName());
1✔
565
            if (null == distribution) {
1✔
566
                distribution = new org.jreleaser.model.internal.distributions.Distribution();
1✔
567
                distribution.setType(assembler.getDistributionType());
1✔
568
                distribution.setStereotype(assembler.getStereotype());
1✔
569
                distribution.setName(assembler.getName());
1✔
570
                model.getDistributions().put(assembler.getName(), distribution);
1✔
571
            }
572
            distribution.setName(assembler.getName());
1✔
573
            distribution.setType(assembler.getDistributionType());
1✔
574

575
            distribution.setActive(Active.NEVER);
1✔
576
            if (isDistributionSelected(distribution.getName())) {
1✔
577
                distribution.setActive(assembler.getActive());
1✔
578
            }
579

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

605
            Map<String, Object> extraProperties = new LinkedHashMap<>(distribution.getExtraProperties());
1✔
606
            extraProperties.putAll(assembler.getExtraProperties());
1✔
607
            distribution.mergeExtraProperties(extraProperties);
1✔
608
        }
1✔
609

610
        resolveArtifactPatterns();
1✔
611
    }
1✔
612

613
    private void resolveArtifactPatterns() {
614
        for (org.jreleaser.model.internal.distributions.Distribution distribution : model.getDistributions().values()) {
1✔
615
            if (distribution.isApplyDefaultMatrix()) {
1✔
616
                distribution.setMatrix(model.getMatrix());
×
617
            }
618

619
            if (!distribution.getMatrix().isEmpty() && isNotBlank(distribution.getArtifactPattern().getPath())) {
1✔
620
                List<Artifact> artifacts = new ArrayList<>();
×
621
                for (Map<String, String> matrixRow : distribution.getMatrix().resolve()) {
×
622
                    artifacts.add(createArtifact(distribution.getArtifactPattern(), matrixRow));
×
623
                }
×
624
                mergeArtifacts(artifacts, distribution);
×
625
            }
626
        }
1✔
627
    }
1✔
628

629
    private Artifact createArtifact(Artifact artifactPattern, Map<String, String> matrix) {
630
        Artifact artifact = new Artifact();
×
631
        artifact.setPlatform(matrix.get(KEY_PLATFORM));
×
632

633
        artifact.setPath(replaceWithMatrix(artifactPattern.getPath(), matrix));
×
634
        artifact.setTransform(replaceWithMatrix(artifactPattern.getTransform(), matrix));
×
635

636
        for (Map.Entry<String, Object> property : artifactPattern.getExtraProperties().entrySet()) {
×
637
            artifact.addExtraProperty(property.getKey(), replaceWithMatrix(property.getValue(), matrix));
×
638
        }
×
639

640
        for (Map.Entry<String, String> property : matrix.entrySet()) {
×
641
            if (property.getKey().startsWith("extraProperties.")) {
×
642
                String key = property.getKey().substring("extraProperties.".length());
×
643
                artifact.addExtraProperty(key, property.getValue());
×
644
            }
645
        }
×
646

647
        return artifact;
×
648
    }
649

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

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

694
    public boolean isDistributionSelected(String distributionName) {
695
        if (!getIncludedDistributions().isEmpty() && getIncludedDistributions().contains(distributionName)) {
1✔
696
            return true;
×
697
        } else if (!getExcludedDistributions().isEmpty() && !getExcludedDistributions().contains(distributionName)) {
1✔
698
            return true;
×
699
        } else if (getIncludedDistributions().isEmpty() && getExcludedDistributions().isEmpty()) {
1✔
700
            return true;
1✔
701
        }
702

703
        return false;
×
704
    }
705

706
    public boolean isPlatformSelected(Artifact artifact) {
707
        return isPlatformSelected(artifact.getPlatform(), new Platform());
1✔
708
    }
709

710
    public boolean isPlatformSelected(Artifact artifact, Platform platform) {
711
        return isPlatformSelected(artifact.getPlatform(), platform);
×
712
    }
713

714
    public boolean isPlatformSelected(String platform) {
715
        return isPlatformSelected(platform, new Platform());
1✔
716
    }
717

718
    public boolean isPlatformSelected(String platform, Platform replacements) {
719
        if (isBlank(platform)) return true;
1✔
720

721
        if (!selectedPlatforms.isEmpty()) {
1✔
722
            return selectedPlatforms.stream()
1✔
723
                .anyMatch(selected -> PlatformUtils.isCompatible(replacements.applyReplacements(selected), platform));
1✔
724
        }
725

726
        if (!rejectedPlatforms.isEmpty()) {
1✔
727
            return rejectedPlatforms.stream()
×
728
                .noneMatch(selected -> PlatformUtils.isCompatible(replacements.applyReplacements(selected), platform));
×
729
        }
730

731
        return true;
1✔
732
    }
733

734
    public JReleaserLogger getLogger() {
735
        return logger;
1✔
736
    }
737

738
    public Configurer getConfigurer() {
739
        return configurer;
1✔
740
    }
741

742
    public org.jreleaser.model.api.JReleaserContext.Mode getMode() {
743
        return mode;
1✔
744
    }
745

746
    public JReleaserModel getModel() {
747
        return model;
1✔
748
    }
749

750
    public Path getBasedir() {
751
        return basedir;
1✔
752
    }
753

754
    public Path getOutputDirectory() {
755
        return outputDirectory;
1✔
756
    }
757

758
    public Path getChecksumsDirectory() {
759
        return outputDirectory.resolve("checksums");
1✔
760
    }
761

762
    public Path getCatalogsDirectory() {
763
        return outputDirectory.resolve("catalogs");
1✔
764
    }
765

766
    public Path getSignaturesDirectory() {
767
        return outputDirectory.resolve("signatures");
1✔
768
    }
769

770
    public Path getPrepareDirectory() {
771
        return outputDirectory.resolve("prepare");
1✔
772
    }
773

774
    public Path getPackageDirectory() {
775
        return outputDirectory.resolve("package");
1✔
776
    }
777

778
    public Path getAssembleDirectory() {
779
        return outputDirectory.resolve("assemble");
1✔
780
    }
781

782
    public Path getDownloadDirectory() {
783
        return outputDirectory.resolve("download");
1✔
784
    }
785

786
    public Path getArtifactsDirectory() {
787
        return outputDirectory.resolve("artifacts");
1✔
788
    }
789

790
    public Path getDeployDirectory() {
791
        return outputDirectory.resolve("deploy");
1✔
792
    }
793

794
    public boolean isYolo() {
795
        return yolo;
1✔
796
    }
797

798
    public boolean isDryrun() {
799
        return dryrun;
1✔
800
    }
801

802
    public boolean isGitRootSearch() {
803
        return gitRootSearch;
1✔
804
    }
805

806
    public boolean isStrict() {
807
        return strict;
1✔
808
    }
809

810
    public Changelog getChangelog() {
811
        return changelog;
1✔
812
    }
813

814
    public org.jreleaser.model.spi.release.Releaser<?> getReleaser() {
815
        return releaser;
1✔
816
    }
817

818
    public void setReleaser(org.jreleaser.model.spi.release.Releaser<?> releaser) {
819
        this.releaser = releaser;
1✔
820
    }
1✔
821

822
    private List<String> normalize(List<String> list) {
823
        if (null == list || list.isEmpty()) return Collections.emptyList();
1✔
824

825
        List<String> tmp = new ArrayList<>(list);
×
826
        for (int i = 0; i < tmp.size(); i++) {
×
827
            String s = tmp.get(i).trim();
×
828
            if (!s.contains("-")) {
×
829
                s = StringUtils.getHyphenatedName(s);
×
830
            }
831
            tmp.set(i, s.toLowerCase(Locale.ENGLISH));
×
832
        }
833

834
        return tmp;
×
835
    }
836

837
    private List<String> compact(List<String> list) {
838
        if (null == list || list.isEmpty()) return Collections.emptyList();
1✔
839

840
        return list.stream()
1✔
841
            .map(s -> s.toLowerCase(Locale.ENGLISH))
1✔
842
            .map(s -> s.replace("-", ""))
1✔
843
            .map(s -> s.replace(" ", ""))
1✔
844
            .collect(toList());
1✔
845
    }
846

847
    public List<WorkflowListener> getWorkflowListeners() {
848
        return workflowListeners;
×
849
    }
850

851
    public void setWorkflowListeners(Collection<WorkflowListener> workflowListeners) {
852
        this.workflowListeners.clear();
1✔
853
        this.workflowListeners.addAll(workflowListeners);
1✔
854
    }
1✔
855

856
    public List<String> getIncludedAnnouncers() {
857
        return includedAnnouncers;
1✔
858
    }
859

860
    public void setIncludedAnnouncers(List<String> includedAnnouncers) {
861
        this.includedAnnouncers.clear();
1✔
862
        this.includedAnnouncers.addAll(normalize(includedAnnouncers));
1✔
863
    }
1✔
864

865
    public List<String> getIncludedAssemblers() {
866
        return includedAssemblers;
1✔
867
    }
868

869
    public void setIncludedAssemblers(List<String> includedAssemblerTypes) {
870
        this.includedAssemblers.clear();
1✔
871
        this.includedAssemblers.addAll(normalize(includedAssemblerTypes));
1✔
872
    }
1✔
873

874
    public List<String> getIncludedCatalogers() {
875
        return includedCatalogers;
1✔
876
    }
877

878
    public void setIncludedCatalogers(List<String> includedCatalogers) {
879
        this.includedCatalogers.clear();
1✔
880
        this.includedCatalogers.addAll(normalize(includedCatalogers));
1✔
881
    }
1✔
882

883
    public List<String> getIncludedDistributions() {
884
        return includedDistributions;
1✔
885
    }
886

887
    public void setIncludedDistributions(List<String> includedDistributions) {
888
        this.includedDistributions.clear();
1✔
889
        this.includedDistributions.addAll(includedDistributions);
1✔
890
    }
1✔
891

892
    public List<String> getIncludedPackagers() {
893
        return includedPackagers;
1✔
894
    }
895

896
    public void setIncludedPackagers(List<String> includedPackagers) {
897
        this.includedPackagers.clear();
1✔
898
        this.includedPackagers.addAll(compact(includedPackagers));
1✔
899
    }
1✔
900

901
    public List<String> getIncludedDownloaderTypes() {
902
        return includedDownloaderTypes;
1✔
903
    }
904

905
    public void setIncludedDownloaderTypes(List<String> includedDownloaderTypes) {
906
        this.includedDownloaderTypes.clear();
1✔
907
        this.includedDownloaderTypes.addAll(normalize(includedDownloaderTypes));
1✔
908
    }
1✔
909

910
    public List<String> getIncludedDownloaderNames() {
911
        return includedDownloaderNames;
1✔
912
    }
913

914
    public void setIncludedDownloaderNames(List<String> includedDownloaderNames) {
915
        this.includedDownloaderNames.clear();
1✔
916
        this.includedDownloaderNames.addAll(includedDownloaderNames);
1✔
917
    }
1✔
918

919
    public List<String> getIncludedDeployerTypes() {
920
        return includedDeployerTypes;
1✔
921
    }
922

923
    public void setIncludedDeployerTypes(List<String> includedDeployerTypes) {
924
        this.includedDeployerTypes.clear();
1✔
925
        this.includedDeployerTypes.addAll(normalize(includedDeployerTypes));
1✔
926
    }
1✔
927

928
    public List<String> getIncludedDeployerNames() {
929
        return includedDeployerNames;
1✔
930
    }
931

932
    public void setIncludedDeployerNames(List<String> includedDeployerNames) {
933
        this.includedDeployerNames.clear();
1✔
934
        this.includedDeployerNames.addAll(includedDeployerNames);
1✔
935
    }
1✔
936

937
    public List<String> getIncludedUploaderTypes() {
938
        return includedUploaderTypes;
1✔
939
    }
940

941
    public void setIncludedUploaderTypes(List<String> includedUploaderTypes) {
942
        this.includedUploaderTypes.clear();
1✔
943
        this.includedUploaderTypes.addAll(normalize(includedUploaderTypes));
1✔
944
    }
1✔
945

946
    public List<String> getIncludedUploaderNames() {
947
        return includedUploaderNames;
1✔
948
    }
949

950
    public void setIncludedUploaderNames(List<String> includedUploaderNames) {
951
        this.includedUploaderNames.clear();
1✔
952
        this.includedUploaderNames.addAll(includedUploaderNames);
1✔
953
    }
1✔
954

955
    public List<String> getExcludedAnnouncers() {
956
        return excludedAnnouncers;
1✔
957
    }
958

959
    public void setExcludedAnnouncers(List<String> excludedAnnouncers) {
960
        this.excludedAnnouncers.clear();
1✔
961
        this.excludedAnnouncers.addAll(normalize(excludedAnnouncers));
1✔
962
    }
1✔
963

964
    public List<String> getExcludedAssemblers() {
965
        return excludedAssemblers;
1✔
966
    }
967

968
    public void setExcludedAssemblers(List<String> excludedAssemblerTypes) {
969
        this.excludedAssemblers.clear();
1✔
970
        this.excludedAssemblers.addAll(normalize(excludedAssemblerTypes));
1✔
971
    }
1✔
972

973
    public List<String> getExcludedCatalogers() {
974
        return excludedCatalogers;
1✔
975
    }
976

977
    public void setExcludedCatalogers(List<String> excludedCatalogers) {
978
        this.excludedCatalogers.clear();
1✔
979
        this.excludedCatalogers.addAll(normalize(excludedCatalogers));
1✔
980
    }
1✔
981

982
    public List<String> getExcludedDistributions() {
983
        return excludedDistributions;
1✔
984
    }
985

986
    public void setExcludedDistributions(List<String> excludedDistributions) {
987
        this.excludedDistributions.clear();
1✔
988
        this.excludedDistributions.addAll(excludedDistributions);
1✔
989
    }
1✔
990

991
    public List<String> getExcludedPackagers() {
992
        return excludedPackagers;
1✔
993
    }
994

995
    public void setExcludedPackagers(List<String> excludedPackagers) {
996
        this.excludedPackagers.clear();
1✔
997
        this.excludedPackagers.addAll(compact(excludedPackagers));
1✔
998
    }
1✔
999

1000
    public List<String> getExcludedDownloaderTypes() {
1001
        return excludedDownloaderTypes;
1✔
1002
    }
1003

1004
    public void setExcludedDownloaderTypes(List<String> excludedDownloaderTypes) {
1005
        this.excludedDownloaderTypes.clear();
1✔
1006
        this.excludedDownloaderTypes.addAll(normalize(excludedDownloaderTypes));
1✔
1007
    }
1✔
1008

1009
    public List<String> getExcludedDownloaderNames() {
1010
        return excludedDownloaderNames;
1✔
1011
    }
1012

1013
    public void setExcludedDownloaderNames(List<String> excludedDownloaderNames) {
1014
        this.excludedDownloaderNames.clear();
1✔
1015
        this.excludedDownloaderNames.addAll(excludedDownloaderNames);
1✔
1016
    }
1✔
1017

1018
    public List<String> getExcludedDeployerTypes() {
1019
        return excludedDeployerTypes;
1✔
1020
    }
1021

1022
    public void setExcludedDeployerTypes(List<String> excludedDeployerTypes) {
1023
        this.excludedDeployerTypes.clear();
1✔
1024
        this.excludedDeployerTypes.addAll(normalize(excludedDeployerTypes));
1✔
1025
    }
1✔
1026

1027
    public List<String> getExcludedDeployerNames() {
1028
        return excludedDeployerNames;
1✔
1029
    }
1030

1031
    public void setExcludedDeployerNames(List<String> excludedDeployerNames) {
1032
        this.excludedDeployerNames.clear();
1✔
1033
        this.excludedDeployerNames.addAll(excludedDeployerNames);
1✔
1034
    }
1✔
1035

1036
    public List<String> getExcludedUploaderTypes() {
1037
        return excludedUploaderTypes;
1✔
1038
    }
1039

1040
    public void setExcludedUploaderTypes(List<String> excludedUploaderTypes) {
1041
        this.excludedUploaderTypes.clear();
1✔
1042
        this.excludedUploaderTypes.addAll(normalize(excludedUploaderTypes));
1✔
1043
    }
1✔
1044

1045
    public List<String> getExcludedUploaderNames() {
1046
        return excludedUploaderNames;
1✔
1047
    }
1048

1049
    public void setExcludedUploaderNames(List<String> excludedUploaderNames) {
1050
        this.excludedUploaderNames.clear();
1✔
1051
        this.excludedUploaderNames.addAll(excludedUploaderNames);
1✔
1052
    }
1✔
1053

1054
    public JReleaserCommand getCommand() {
1055
        return command;
1✔
1056
    }
1057

1058
    public TemplateContext props() {
1059
        TemplateContext props = new TemplateContext(model.props());
1✔
1060
        props.set(Constants.KEY_BASEDIR, getBasedir());
1✔
1061
        props.set(Constants.KEY_BASE_OUTPUT_DIRECTORY, getOutputDirectory().getParent());
1✔
1062
        props.set(Constants.KEY_OUTPUT_DIRECTORY, getOutputDirectory());
1✔
1063
        props.set(Constants.KEY_CHECKSUMS_DIRECTORY, getChecksumsDirectory());
1✔
1064
        props.set(Constants.KEY_CATALOGS_DIRECTORY, getCatalogsDirectory());
1✔
1065
        props.set(Constants.KEY_SIGNATURES_DIRECTORY, getSignaturesDirectory());
1✔
1066
        props.set(Constants.KEY_PREPARE_DIRECTORY, getPrepareDirectory());
1✔
1067
        props.set(Constants.KEY_PACKAGE_DIRECTORY, getPackageDirectory());
1✔
1068
        props.set(Constants.KEY_DOWNLOAD_DIRECTORY, getDownloadDirectory());
1✔
1069
        props.set(Constants.KEY_ASSEMBLE_DIRECTORY, getAssembleDirectory());
1✔
1070
        props.set(Constants.KEY_ARTIFACTS_DIRECTORY, getArtifactsDirectory());
1✔
1071
        props.set(Constants.KEY_DEPLOY_DIRECTORY, getDeployDirectory());
1✔
1072
        if (null != getCommand()) props.set(Constants.KEY_COMMAND, getCommand().toStep());
1✔
1073
        return props;
1✔
1074
    }
1075

1076
    public TemplateContext fullProps() {
1077
        TemplateContext props = new TemplateContext(props());
1✔
1078
        props.setAll(model.props());
1✔
1079
        return props;
1✔
1080
    }
1081

1082
    public Map<String, Object> getAdditionalProperties() {
1083
        return additionalProperties;
1✔
1084
    }
1085

1086
    @Override
1087
    public String toString() {
1088
        return "JReleaserContext[" +
×
1089
            "basedir=" + basedir.toAbsolutePath() +
×
1090
            ", outputDirectory=" + outputDirectory.toAbsolutePath() +
×
1091
            ", yolo=" + yolo +
1092
            ", dryrun=" + dryrun +
1093
            ", gitRootSearch=" + gitRootSearch +
1094
            ", strict=" + strict +
1095
            ", mode=" + mode +
1096
            "]";
1097
    }
1098

1099
    public void report() {
1100
        Project project = model.getProject();
1✔
1101

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

1130
        Map<String, Object> resolvedExtraProperties = project.resolvedExtraProperties();
1✔
1131
        safePut(project.prefix() + capitalize(KEY_VERSION_MAJOR), resolvedExtraProperties, props);
1✔
1132
        safePut(project.prefix() + capitalize(KEY_VERSION_MINOR), resolvedExtraProperties, props);
1✔
1133
        safePut(project.prefix() + capitalize(KEY_VERSION_PATCH), resolvedExtraProperties, props);
1✔
1134
        safePut(project.prefix() + capitalize(KEY_VERSION_NUMBER), resolvedExtraProperties, props);
1✔
1135
        safePut(project.prefix() + capitalize(KEY_VERSION_PRERELEASE), resolvedExtraProperties, props);
1✔
1136
        safePut(project.prefix() + capitalize(KEY_VERSION_TAG), resolvedExtraProperties, props);
1✔
1137
        safePut(project.prefix() + capitalize(KEY_VERSION_BUILD), resolvedExtraProperties, props);
1✔
1138
        safePut(project.prefix() + capitalize(KEY_VERSION_OPTIONAL), resolvedExtraProperties, props);
1✔
1139
        safePut(project.prefix() + capitalize(KEY_VERSION_YEAR), resolvedExtraProperties, props);
1✔
1140
        safePut(project.prefix() + capitalize(KEY_VERSION_MONTH), resolvedExtraProperties, props);
1✔
1141
        safePut(project.prefix() + capitalize(KEY_VERSION_DAY), resolvedExtraProperties, props);
1✔
1142
        safePut(project.prefix() + capitalize(KEY_VERSION_WEEK), resolvedExtraProperties, props);
1✔
1143
        safePut(project.prefix() + capitalize(KEY_VERSION_MICRO), resolvedExtraProperties, props);
1✔
1144
        safePut(project.prefix() + capitalize(KEY_VERSION_MODIFIER), resolvedExtraProperties, props);
1✔
1145

1146
        props.putAll(getAdditionalProperties());
1✔
1147

1148
        Path output = getOutputDirectory().resolve("output.properties");
1✔
1149

1150
        try (FileOutputStream out = new FileOutputStream(output.toFile())) {
1✔
1151
            logger.info(RB.$("context.writing.properties"),
1✔
1152
                relativizeToBasedir(output));
1✔
1153
            props.store(out, "JReleaser " + JReleaserVersion.getPlainVersion());
1✔
1154
        } catch (IOException ignored) {
×
1155
            logger.warn(RB.$("context.writing.properties.error"),
×
1156
                relativizeToBasedir(output));
×
1157
        }
1✔
1158
    }
1✔
1159

1160
    public void nag(String version, String message) {
1161
        logger.warn(RB.$("context.nag", message, version));
×
1162
    }
×
1163

1164
    public Keyring createKeyring() throws SigningException {
1165
        try {
1166
            org.jreleaser.model.internal.signing.Signing signing = model.getSigning();
1✔
1167

1168
            if (!signing.isEnabled()) {
1✔
1169
                throw new SigningException(RB.$("ERROR_signing_disabled"));
×
1170
            }
1171

1172
            if (signing.getMode() == Signing.Mode.FILE) {
1✔
1173
                return new FilesKeyring(
×
1174
                    signing.isVerify() ? basedir.resolve(signing.getPublicKey()) : null,
×
1175
                    basedir.resolve(signing.getSecretKey())
×
1176
                ).initialize(signing.isArmored());
×
1177
            }
1178

1179
            return new InMemoryKeyring(
1✔
1180
                signing.isVerify() ? signing.getPublicKey().getBytes(UTF_8) : null,
1✔
1181
                signing.getSecretKey().getBytes(UTF_8)
1✔
1182
            ).initialize(signing.isArmored());
1✔
1183
        } catch (IOException | PGPException e) {
×
1184
            throw new SigningException(RB.$("ERROR_signing_init_keyring"), e);
×
1185
        }
1186
    }
1187

1188
    public boolean isDistributionIncluded(org.jreleaser.model.internal.distributions.Distribution distribution) {
1189
        String distributionName = distribution.getName();
1✔
1190

1191
        if (!includedDistributions.isEmpty()) {
1✔
1192
            return includedDistributions.contains(distributionName);
×
1193
        }
1194

1195
        if (!excludedDistributions.isEmpty()) {
1✔
1196
            return !excludedDistributions.contains(distributionName);
×
1197
        }
1198

1199
        return true;
1✔
1200
    }
1201

1202
    public void fireSessionStartEvent() throws WorkflowListenerException {
1203
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1204
            try {
1205
                workflowListener.onSessionStart(this.asImmutable());
×
1206
            } catch (RuntimeException e) {
×
1207
                throw new WorkflowListenerException(workflowListener, e);
×
1208
            }
×
1209
        }
×
1210
    }
1✔
1211

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

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

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

1242
    public void fireAssembleStepEvent(ExecutionEvent event, Assembler assembler) throws WorkflowListenerException {
1243
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1244
            try {
1245
                workflowListener.onAssembleStep(event, this.asImmutable(), assembler);
×
1246
            } catch (RuntimeException e) {
×
1247
                throw new WorkflowListenerException(workflowListener, e);
×
1248
            }
×
1249
        }
×
1250
    }
1✔
1251

1252
    public void fireCatalogStepEvent(ExecutionEvent event, Cataloger cataloger) throws WorkflowListenerException {
1253
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1254
            try {
1255
                workflowListener.onCatalogStep(event, this.asImmutable(), cataloger);
×
1256
            } catch (RuntimeException e) {
×
1257
                throw new WorkflowListenerException(workflowListener, e);
×
1258
            }
×
1259
        }
×
1260
    }
1✔
1261

1262
    public void fireDeployStepEvent(ExecutionEvent event, Deployer deployer) throws WorkflowListenerException {
1263
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1264
            try {
1265
                workflowListener.onDeployStep(event, this.asImmutable(), deployer);
×
1266
            } catch (RuntimeException e) {
×
1267
                throw new WorkflowListenerException(workflowListener, e);
×
1268
            }
×
1269
        }
×
1270
    }
1✔
1271

1272
    public void fireDownloadStepEvent(ExecutionEvent event, Downloader downloader) throws WorkflowListenerException {
1273
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1274
            try {
1275
                workflowListener.onDownloadStep(event, this.asImmutable(), downloader);
×
1276
            } catch (RuntimeException e) {
×
1277
                throw new WorkflowListenerException(workflowListener, e);
×
1278
            }
×
1279
        }
×
1280
    }
1✔
1281

1282
    public void fireUploadStepEvent(ExecutionEvent event, Uploader uploader) throws WorkflowListenerException {
1283
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1284
            try {
1285
                workflowListener.onUploadStep(event, this.asImmutable(), uploader);
×
1286
            } catch (RuntimeException e) {
×
1287
                throw new WorkflowListenerException(workflowListener, e);
×
1288
            }
×
1289
        }
×
1290
    }
1✔
1291

1292
    public void fireReleaseStepEvent(ExecutionEvent event, Releaser releaser) throws WorkflowListenerException {
1293
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1294
            try {
1295
                workflowListener.onReleaseStep(event, this.asImmutable(), releaser);
×
1296
            } catch (RuntimeException e) {
×
1297
                throw new WorkflowListenerException(workflowListener, e);
×
1298
            }
×
1299
        }
×
1300
    }
1✔
1301

1302
    public void fireDistributionStartEvent(Distribution distribution) throws WorkflowListenerException {
1303
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1304
            try {
1305
                workflowListener.onDistributionStart(this.asImmutable(), distribution);
×
1306
            } catch (RuntimeException e) {
×
1307
                throw new WorkflowListenerException(workflowListener, e);
×
1308
            }
×
1309
        }
×
1310
    }
1✔
1311

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

1322
    public void firePackagerPackageEvent(ExecutionEvent event, Distribution distribution, Packager packager) throws WorkflowListenerException {
1323
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1324
            try {
1325
                workflowListener.onPackagerPackageStep(event, this.asImmutable(), distribution, packager);
×
1326
            } catch (RuntimeException e) {
×
1327
                throw new WorkflowListenerException(workflowListener, e);
×
1328
            }
×
1329
        }
×
1330
    }
1✔
1331

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

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

1352
    public enum Configurer {
1✔
1353
        CLI("CLI flags"),
1✔
1354
        CLI_YAML("CLI yaml DSL"),
1✔
1355
        CLI_TOML("CLI toml DSL"),
1✔
1356
        CLI_JSON("CLI json DSL"),
1✔
1357
        MAVEN("Maven DSL"),
1✔
1358
        GRADLE("Gradle DSL");
1✔
1359

1360
        private final String dsl;
1361

1362
        Configurer(String dsl) {
1✔
1363
            this.dsl = dsl;
1✔
1364
        }
1✔
1365

1366
        @Override
1367
        public String toString() {
1368
            return this.dsl;
1✔
1369
        }
1370
    }
1371

1372
    private static class SortedProperties extends Properties {
1373
        private static final long serialVersionUID = 8794541421003888869L;
1374

1375
        // Java 11 calls entrySet() when storing properties
1376
        @Override
1377
        public Set<Map.Entry<Object, Object>> entrySet() {
1378
            int javaMajorVersion = SemanticVersion.javaMajorVersion();
1✔
1379
            if (javaMajorVersion < 11) {
1✔
1380
                return super.entrySet();
×
1381
            }
1382

1383
            Map<Object, Object> map = new TreeMap<>();
1✔
1384
            for (Object k : keySet()) {
1✔
1385
                map.put(String.valueOf(k), get(k));
1✔
1386
            }
1✔
1387
            return map.entrySet();
1✔
1388
        }
1389

1390
        // Java 8 calls keys() when storing properties
1391
        @Override
1392
        public synchronized Enumeration<Object> keys() {
1393
            int javaMajorVersion = SemanticVersion.javaMajorVersion();
×
1394
            if (javaMajorVersion >= 11) {
×
1395
                return super.keys();
×
1396
            }
1397

1398
            Set<Object> keySet = keySet();
×
1399
            List<String> keys = new ArrayList<>(keySet.size());
×
1400
            for (Object key : keySet) {
×
1401
                keys.add(key.toString());
×
1402
            }
×
1403
            Collections.sort(keys);
×
1404
            return new IteratorEnumeration<>(keys.iterator());
×
1405
        }
1406
    }
1407

1408
    private static class IteratorEnumeration<E> implements Enumeration<E> {
1409
        private final Iterator<? extends E> iterator;
1410

1411
        public IteratorEnumeration(Iterator<? extends E> iterator) {
×
1412
            this.iterator = iterator;
×
1413
        }
×
1414

1415
        @Override
1416
        public boolean hasMoreElements() {
1417
            return iterator.hasNext();
×
1418
        }
1419

1420
        @Override
1421
        public E nextElement() {
1422
            return iterator.next();
×
1423
        }
1424
    }
1425
}
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