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

jreleaser / jreleaser / #480

08 Apr 2025 02:28PM UTC coverage: 47.827% (-0.7%) from 48.516%
#480

push

github

aalmiray
feat(release): Let github.release.makeLatest be specified as input

Closes #1847

17 of 29 new or added lines in 6 files covered. (58.62%)

374 existing lines in 32 files now uncovered.

24810 of 51874 relevant lines covered (47.83%)

0.48 hits per line

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

65.31
/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 dryrun;
128
    private final boolean strict;
129
    private final boolean gitRootSearch;
130
    private final org.jreleaser.model.api.JReleaserContext.Mode mode;
131
    private final JReleaserCommand command;
132
    private final Configurer configurer;
133
    private final Errors errors = new Errors();
1✔
134
    private final Changelog changelog = new Changelog();
1✔
135
    private final Map<String, Object> additionalProperties = new LinkedHashMap<>();
1✔
136

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

230
        @Override
231
        public Path getAssembleDirectory() {
232
            return JReleaserContext.this.getAssembleDirectory();
×
233
        }
234

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

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

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

250
        @Override
251
        public boolean isDryrun() {
252
            return JReleaserContext.this.isDryrun();
1✔
253
        }
254

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

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

265
        @Override
266
        public List<String> getIncludedAnnouncers() {
267
            return unmodifiableList(JReleaserContext.this.getIncludedAnnouncers());
×
268
        }
269

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

365
        @Override
366
        public JReleaserCommand getCommand() {
367
            return JReleaserContext.this.getCommand();
×
368
        }
369

370
        @Override
371
        public TemplateContext props() {
372
            return JReleaserContext.this.props();
×
373
        }
374

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

380
        @Override
381
        public void nag(String version, String message) {
382
            JReleaserContext.this.nag(version, message);
×
383
        }
×
384

385
        @Override
386
        public Keyring createKeyring() throws SigningException {
387
            return JReleaserContext.this.createKeyring();
1✔
388
        }
389

390
        @Override
391
        public Changelog getChangelog() {
392
            return JReleaserContext.this.changelog;
×
393
        }
394

395
        @Override
396
        public Map<String, Object> getAdditionalProperties() {
397
            return unmodifiableMap(JReleaserContext.this.getAdditionalProperties());
×
398
        }
399
    };
400

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

417
    public JReleaserContext(JReleaserLogger logger,
418
                            Configurer configurer,
419
                            org.jreleaser.model.api.JReleaserContext.Mode mode,
420
                            JReleaserCommand command,
421
                            JReleaserModel model,
422
                            Path basedir,
423
                            Path outputDirectory,
424
                            boolean dryrun,
425
                            boolean gitRootSearch,
426
                            boolean strict,
427
                            List<String> selectedPlatforms,
428
                            List<String> rejectedPlatforms) {
1✔
429
        this.logger = logger;
1✔
430
        this.configurer = configurer;
1✔
431
        this.mode = mode;
1✔
432
        this.command = command;
1✔
433
        this.model = model;
1✔
434
        this.basedir = basedir;
1✔
435
        this.outputDirectory = outputDirectory;
1✔
436
        this.dryrun = dryrun;
1✔
437
        this.gitRootSearch = gitRootSearch;
1✔
438
        this.strict = strict;
1✔
439
        this.selectedPlatforms.addAll(selectedPlatforms.stream()
1✔
440
            .filter(PlatformUtils::isSupported)
1✔
441
            .collect(toList()));
1✔
442

443
        try {
444
            logger.increaseIndent();
1✔
445
            logger.debug(RB.$("context.path.set", Constants.KEY_BASEDIR, getBasedir()));
1✔
446
            logger.debug(RB.$("context.path.set", Constants.KEY_BASE_OUTPUT_DIRECTORY, getOutputDirectory().getParent()));
1✔
447
            logger.debug(RB.$("context.path.set", Constants.KEY_OUTPUT_DIRECTORY, getOutputDirectory()));
1✔
448
            logger.debug(RB.$("context.path.set", Constants.KEY_CHECKSUMS_DIRECTORY, getChecksumsDirectory()));
1✔
449
            logger.debug(RB.$("context.path.set", Constants.KEY_CATALOGS_DIRECTORY, getCatalogsDirectory()));
1✔
450
            logger.debug(RB.$("context.path.set", Constants.KEY_SIGNATURES_DIRECTORY, getSignaturesDirectory()));
1✔
451
            logger.debug(RB.$("context.path.set", Constants.KEY_PREPARE_DIRECTORY, getPrepareDirectory()));
1✔
452
            logger.debug(RB.$("context.path.set", Constants.KEY_PACKAGE_DIRECTORY, getPackageDirectory()));
1✔
453
            logger.debug(RB.$("context.path.set", Constants.KEY_DOWNLOAD_DIRECTORY, getDownloadDirectory()));
1✔
454
            logger.debug(RB.$("context.path.set", Constants.KEY_ASSEMBLE_DIRECTORY, getAssembleDirectory()));
1✔
455
            logger.debug(RB.$("context.path.set", Constants.KEY_ARTIFACTS_DIRECTORY, getArtifactsDirectory()));
1✔
456
            logger.debug(RB.$("context.path.set", Constants.KEY_DEPLOY_DIRECTORY, getDeployDirectory()));
1✔
457
        } finally {
458
            logger.decreaseIndent();
1✔
459
        }
460

461
        List<String> unmatchedPlatforms = new ArrayList<>(selectedPlatforms);
1✔
462
        unmatchedPlatforms.removeAll(this.selectedPlatforms);
1✔
463
        if (!unmatchedPlatforms.isEmpty()) {
1✔
464
            logger.warn(RB.$("context.platform.selection.active"));
×
465
            logger.error(RB.$("context.platform.selection.no.match"), unmatchedPlatforms);
×
466
            logger.error(RB.$("context.platform.selection.valid"),
×
467
                System.lineSeparator(), PlatformUtils.getSupportedOsNames(),
×
468
                System.lineSeparator(), PlatformUtils.getSupportedOsArchs());
×
469
            throw new JReleaserException(RB.$("context.platform.selection.unmatched", unmatchedPlatforms));
×
470
        }
471

472
        if (!this.selectedPlatforms.isEmpty()) {
1✔
473
            logger.warn(RB.$("context.platform.selection.active"));
1✔
474
            logger.warn(RB.$("context.platform.selection.artifacts"), this.selectedPlatforms);
1✔
475
        }
476

477
        this.rejectedPlatforms.addAll(rejectedPlatforms);
1✔
478
        if (!this.rejectedPlatforms.isEmpty()) {
1✔
479
            logger.warn(RB.$("context.platform.selection.active"));
×
480
            logger.warn(RB.$("context.platform.rejection.artifacts"), this.rejectedPlatforms);
×
481
        }
482
    }
1✔
483

484
    public org.jreleaser.model.api.JReleaserContext asImmutable() {
485
        return immutable;
1✔
486
    }
487

488
    public Object eval(String script) {
489
        return scriptEvaluator.eval(this, script);
×
490
    }
491

492
    public Path relativize(Path basedir, Path other) {
493
        return basedir.toAbsolutePath().relativize(other.toAbsolutePath());
1✔
494
    }
495

496
    public Path relativizeToBasedir(Path other) {
497
        return relativize(basedir, other);
1✔
498
    }
499

500
    public Path relativize(Path basedir, String other) {
501
        return relativize(basedir, Paths.get(other));
×
502
    }
503

504
    public Path relativizeToBasedir(String other) {
505
        return relativize(basedir, other);
×
506
    }
507

508
    public Errors validateModel() {
509
        if (errors.hasErrors()) return errors;
1✔
510

511
        this.model.getEnvironment().initProps(this);
1✔
512

513
        logger.info(RB.$("context.configuration.validation"));
1✔
514
        logger.info(RB.$("context.configuration.strict", strict));
1✔
515

516
        if (mode.validateConfig()) {
1✔
517
            adjustDistributions();
1✔
518
        }
519

520
        try {
521
            JReleaserModelValidator.validate(this, this.mode, errors);
1✔
522
        } catch (Exception e) {
×
523
            logger.trace(e);
×
524
            errors.configuration(e.toString());
×
525
        }
1✔
526

527
        if (errors.hasWarnings()) {
1✔
528
            logger.warn("== JReleaser ==");
1✔
529
            errors.logWarnings(logger);
1✔
530
        }
531
        if (errors.hasErrors()) {
1✔
532
            logger.error("== JReleaser ==");
×
533
            errors.logErrors(logger);
×
534
        }
535

536
        return errors;
1✔
537
    }
538

539
    private void adjustDistributions() {
540
        logger.debug(RB.$("context.adjust.assemblies"));
1✔
541

542
        // resolve assemblers
543
        try {
544
            JReleaserModelValidator.validate(this, org.jreleaser.model.api.JReleaserContext.Mode.ASSEMBLE, errors);
1✔
545
            JReleaserModelResolver.resolve(this, errors);
1✔
546
        } catch (Exception e) {
×
547
            logger.trace(e);
×
548
            errors.configuration(e.toString());
×
549
        }
1✔
550

551
        // match distributions
552
        for (org.jreleaser.model.internal.assemble.Assembler<?> assembler : model.getAssemble().findAllAssemblers()) {
1✔
553
            if (!assembler.isExported()) continue;
1✔
554

555
            org.jreleaser.model.internal.distributions.Distribution distribution = model.getDistributions().get(assembler.getName());
1✔
556
            if (null == distribution) {
1✔
557
                distribution = new org.jreleaser.model.internal.distributions.Distribution();
1✔
558
                distribution.setType(assembler.getDistributionType());
1✔
559
                distribution.setStereotype(assembler.getStereotype());
1✔
560
                distribution.setName(assembler.getName());
1✔
561
                model.getDistributions().put(assembler.getName(), distribution);
1✔
562
            }
563
            distribution.setName(assembler.getName());
1✔
564
            distribution.setType(assembler.getDistributionType());
1✔
565

566
            distribution.setActive(Active.NEVER);
1✔
567
            if (isDistributionSelected(distribution.getName())) {
1✔
568
                distribution.setActive(assembler.getActive());
1✔
569
            }
570

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

596
            Map<String, Object> extraProperties = new LinkedHashMap<>(distribution.getExtraProperties());
1✔
597
            extraProperties.putAll(assembler.getExtraProperties());
1✔
598
            distribution.mergeExtraProperties(extraProperties);
1✔
599
        }
1✔
600

601
        resolveArtifactPatterns();
1✔
602
    }
1✔
603

604
    private void resolveArtifactPatterns() {
605
        for (org.jreleaser.model.internal.distributions.Distribution distribution : model.getDistributions().values()) {
1✔
606
            if (distribution.isApplyDefaultMatrix()) {
1✔
607
                distribution.setMatrix(model.getMatrix());
×
608
            }
609

610
            if (!distribution.getMatrix().isEmpty() && isNotBlank(distribution.getArtifactPattern().getPath())) {
1✔
611
                List<Artifact> artifacts = new ArrayList<>();
×
612
                for (Map<String, String> matrixRow : distribution.getMatrix().resolve()) {
×
613
                    artifacts.add(createArtifact(distribution.getArtifactPattern(), matrixRow));
×
614
                }
×
615
                mergeArtifacts(artifacts, distribution);
×
616
            }
617
        }
1✔
618
    }
1✔
619

620
    private Artifact createArtifact(Artifact artifactPattern, Map<String, String> matrix) {
621
        Artifact artifact = new Artifact();
×
622
        artifact.setPlatform(matrix.get(KEY_PLATFORM));
×
623

624
        artifact.setPath(replaceWithMatrix(artifactPattern.getPath(), matrix));
×
625
        artifact.setTransform(replaceWithMatrix(artifactPattern.getTransform(), matrix));
×
626

627
        for (Map.Entry<String, Object> property : artifactPattern.getExtraProperties().entrySet()) {
×
628
            artifact.addExtraProperty(property.getKey(), replaceWithMatrix(property.getValue(), matrix));
×
629
        }
×
630

631
        for (Map.Entry<String, String> property : matrix.entrySet()) {
×
632
            if (property.getKey().startsWith("extraProperties.")) {
×
633
                String key = property.getKey().substring("extraProperties.".length());
×
634
                artifact.addExtraProperty(key, property.getValue());
×
635
            }
636
        }
×
637

638
        return artifact;
×
639
    }
640

641
    private void mergeArtifacts(org.jreleaser.model.internal.assemble.Assembler<?> assembler, org.jreleaser.model.internal.distributions.Distribution distribution) {
642
        for (Artifact incoming : assembler.getOutputs()) {
1✔
643
            Optional<Artifact> artifact = distribution.getArtifacts().stream()
1✔
644
                .filter(other -> {
1✔
645
                    if (isPlatformSelected(incoming)) incoming.select();
1✔
646
                    if (isPlatformSelected(other)) other.select();
1✔
647
                    if (incoming.isSelected() && other.isSelected()) {
1✔
648
                        Path p1 = incoming.getResolvedPath(this, assembler);
1✔
649
                        Path p2 = other.getResolvedPath(this, distribution);
1✔
650
                        return p1.equals(p2);
1✔
651
                    }
652
                    return false;
×
653
                })
654
                .findFirst();
1✔
655
            if (artifact.isPresent()) {
1✔
656
                artifact.get().mergeWith(incoming);
1✔
657
            } else {
658
                distribution.addArtifact(incoming);
1✔
659
            }
660
        }
1✔
661
    }
1✔
662

663
    private void mergeArtifacts(List<Artifact> artifacts, org.jreleaser.model.internal.distributions.Distribution distribution) {
664
        for (Artifact incoming : artifacts) {
×
665
            Optional<Artifact> artifact = distribution.getArtifacts().stream()
×
666
                .filter(other -> {
×
667
                    if (isPlatformSelected(incoming)) incoming.select();
×
668
                    if (isPlatformSelected(other)) other.select();
×
669
                    if (incoming.isSelected() && other.isSelected()) {
×
670
                        Path p1 = incoming.getResolvedPath(this, distribution);
×
671
                        Path p2 = other.getResolvedPath(this, distribution);
×
672
                        return p1.equals(p2);
×
673
                    }
674
                    return false;
×
675
                })
676
                .findFirst();
×
677
            if (artifact.isPresent()) {
×
678
                artifact.get().mergeWith(incoming);
×
679
            } else {
680
                distribution.addArtifact(incoming);
×
681
            }
682
        }
×
683
    }
×
684

685
    public boolean isDistributionSelected(String distributionName) {
686
        if (!getIncludedDistributions().isEmpty() && getIncludedDistributions().contains(distributionName)) {
1✔
687
            return true;
×
688
        } else if (!getExcludedDistributions().isEmpty() && !getExcludedDistributions().contains(distributionName)) {
1✔
689
            return true;
×
690
        } else if (getIncludedDistributions().isEmpty() && getExcludedDistributions().isEmpty()) {
1✔
691
            return true;
1✔
692
        }
693

694
        return false;
×
695
    }
696

697
    public boolean isPlatformSelected(Artifact artifact) {
698
        return isPlatformSelected(artifact.getPlatform(), new Platform());
1✔
699
    }
700

701
    public boolean isPlatformSelected(Artifact artifact, Platform platform) {
702
        return isPlatformSelected(artifact.getPlatform(), platform);
×
703
    }
704

705
    public boolean isPlatformSelected(String platform) {
706
        return isPlatformSelected(platform, new Platform());
1✔
707
    }
708

709
    public boolean isPlatformSelected(String platform, Platform replacements) {
710
        if (isBlank(platform)) return true;
1✔
711

712
        if (!selectedPlatforms.isEmpty()) {
1✔
713
            return selectedPlatforms.stream()
1✔
714
                .anyMatch(selected -> PlatformUtils.isCompatible(replacements.applyReplacements(selected), platform));
1✔
715
        }
716

717
        if (!rejectedPlatforms.isEmpty()) {
1✔
718
            return rejectedPlatforms.stream()
×
719
                .noneMatch(selected -> PlatformUtils.isCompatible(replacements.applyReplacements(selected), platform));
×
720
        }
721

722
        return true;
1✔
723
    }
724

725
    public JReleaserLogger getLogger() {
726
        return logger;
1✔
727
    }
728

729
    public Configurer getConfigurer() {
730
        return configurer;
1✔
731
    }
732

733
    public org.jreleaser.model.api.JReleaserContext.Mode getMode() {
734
        return mode;
1✔
735
    }
736

737
    public JReleaserModel getModel() {
738
        return model;
1✔
739
    }
740

741
    public Path getBasedir() {
742
        return basedir;
1✔
743
    }
744

745
    public Path getOutputDirectory() {
746
        return outputDirectory;
1✔
747
    }
748

749
    public Path getChecksumsDirectory() {
750
        return outputDirectory.resolve("checksums");
1✔
751
    }
752

753
    public Path getCatalogsDirectory() {
754
        return outputDirectory.resolve("catalogs");
1✔
755
    }
756

757
    public Path getSignaturesDirectory() {
758
        return outputDirectory.resolve("signatures");
1✔
759
    }
760

761
    public Path getPrepareDirectory() {
762
        return outputDirectory.resolve("prepare");
1✔
763
    }
764

765
    public Path getPackageDirectory() {
766
        return outputDirectory.resolve("package");
1✔
767
    }
768

769
    public Path getAssembleDirectory() {
770
        return outputDirectory.resolve("assemble");
1✔
771
    }
772

773
    public Path getDownloadDirectory() {
774
        return outputDirectory.resolve("download");
1✔
775
    }
776

777
    public Path getArtifactsDirectory() {
778
        return outputDirectory.resolve("artifacts");
1✔
779
    }
780

781
    public Path getDeployDirectory() {
782
        return outputDirectory.resolve("deploy");
1✔
783
    }
784

785
    public boolean isDryrun() {
786
        return dryrun;
1✔
787
    }
788

789
    public boolean isGitRootSearch() {
790
        return gitRootSearch;
1✔
791
    }
792

793
    public boolean isStrict() {
794
        return strict;
1✔
795
    }
796

797
    public Changelog getChangelog() {
798
        return changelog;
1✔
799
    }
800

801
    public org.jreleaser.model.spi.release.Releaser<?> getReleaser() {
UNCOV
802
        return releaser;
×
803
    }
804

805
    public void setReleaser(org.jreleaser.model.spi.release.Releaser<?> releaser) {
806
        this.releaser = releaser;
1✔
807
    }
1✔
808

809
    private List<String> normalize(List<String> list) {
810
        if (null == list || list.isEmpty()) return Collections.emptyList();
1✔
811

812
        List<String> tmp = new ArrayList<>(list);
×
813
        for (int i = 0; i < tmp.size(); i++) {
×
814
            String s = tmp.get(i).trim();
×
815
            if (!s.contains("-")) {
×
816
                s = StringUtils.getHyphenatedName(s);
×
817
            }
818
            tmp.set(i, s.toLowerCase(Locale.ENGLISH));
×
819
        }
820

821
        return tmp;
×
822
    }
823

824
    private List<String> compact(List<String> list) {
825
        if (null == list || list.isEmpty()) return Collections.emptyList();
1✔
826

827
        return list.stream()
1✔
828
            .map(s -> s.toLowerCase(Locale.ENGLISH))
1✔
829
            .map(s -> s.replace("-", ""))
1✔
830
            .map(s -> s.replace(" ", ""))
1✔
831
            .collect(toList());
1✔
832
    }
833

834
    public List<WorkflowListener> getWorkflowListeners() {
835
        return workflowListeners;
×
836
    }
837

838
    public void setWorkflowListeners(Collection<WorkflowListener> workflowListeners) {
839
        this.workflowListeners.clear();
1✔
840
        this.workflowListeners.addAll(workflowListeners);
1✔
841
    }
1✔
842

843
    public List<String> getIncludedAnnouncers() {
844
        return includedAnnouncers;
1✔
845
    }
846

847
    public void setIncludedAnnouncers(List<String> includedAnnouncers) {
848
        this.includedAnnouncers.clear();
1✔
849
        this.includedAnnouncers.addAll(normalize(includedAnnouncers));
1✔
850
    }
1✔
851

852
    public List<String> getIncludedAssemblers() {
853
        return includedAssemblers;
1✔
854
    }
855

856
    public void setIncludedAssemblers(List<String> includedAssemblerTypes) {
857
        this.includedAssemblers.clear();
1✔
858
        this.includedAssemblers.addAll(normalize(includedAssemblerTypes));
1✔
859
    }
1✔
860

861
    public List<String> getIncludedCatalogers() {
862
        return includedCatalogers;
1✔
863
    }
864

865
    public void setIncludedCatalogers(List<String> includedCatalogers) {
866
        this.includedCatalogers.clear();
1✔
867
        this.includedCatalogers.addAll(normalize(includedCatalogers));
1✔
868
    }
1✔
869

870
    public List<String> getIncludedDistributions() {
871
        return includedDistributions;
1✔
872
    }
873

874
    public void setIncludedDistributions(List<String> includedDistributions) {
875
        this.includedDistributions.clear();
1✔
876
        this.includedDistributions.addAll(includedDistributions);
1✔
877
    }
1✔
878

879
    public List<String> getIncludedPackagers() {
880
        return includedPackagers;
1✔
881
    }
882

883
    public void setIncludedPackagers(List<String> includedPackagers) {
884
        this.includedPackagers.clear();
1✔
885
        this.includedPackagers.addAll(compact(includedPackagers));
1✔
886
    }
1✔
887

888
    public List<String> getIncludedDownloaderTypes() {
889
        return includedDownloaderTypes;
1✔
890
    }
891

892
    public void setIncludedDownloaderTypes(List<String> includedDownloaderTypes) {
893
        this.includedDownloaderTypes.clear();
1✔
894
        this.includedDownloaderTypes.addAll(normalize(includedDownloaderTypes));
1✔
895
    }
1✔
896

897
    public List<String> getIncludedDownloaderNames() {
898
        return includedDownloaderNames;
1✔
899
    }
900

901
    public void setIncludedDownloaderNames(List<String> includedDownloaderNames) {
902
        this.includedDownloaderNames.clear();
1✔
903
        this.includedDownloaderNames.addAll(includedDownloaderNames);
1✔
904
    }
1✔
905

906
    public List<String> getIncludedDeployerTypes() {
907
        return includedDeployerTypes;
1✔
908
    }
909

910
    public void setIncludedDeployerTypes(List<String> includedDeployerTypes) {
911
        this.includedDeployerTypes.clear();
1✔
912
        this.includedDeployerTypes.addAll(normalize(includedDeployerTypes));
1✔
913
    }
1✔
914

915
    public List<String> getIncludedDeployerNames() {
916
        return includedDeployerNames;
1✔
917
    }
918

919
    public void setIncludedDeployerNames(List<String> includedDeployerNames) {
920
        this.includedDeployerNames.clear();
1✔
921
        this.includedDeployerNames.addAll(includedDeployerNames);
1✔
922
    }
1✔
923

924
    public List<String> getIncludedUploaderTypes() {
925
        return includedUploaderTypes;
1✔
926
    }
927

928
    public void setIncludedUploaderTypes(List<String> includedUploaderTypes) {
929
        this.includedUploaderTypes.clear();
1✔
930
        this.includedUploaderTypes.addAll(normalize(includedUploaderTypes));
1✔
931
    }
1✔
932

933
    public List<String> getIncludedUploaderNames() {
934
        return includedUploaderNames;
1✔
935
    }
936

937
    public void setIncludedUploaderNames(List<String> includedUploaderNames) {
938
        this.includedUploaderNames.clear();
1✔
939
        this.includedUploaderNames.addAll(includedUploaderNames);
1✔
940
    }
1✔
941

942
    public List<String> getExcludedAnnouncers() {
943
        return excludedAnnouncers;
1✔
944
    }
945

946
    public void setExcludedAnnouncers(List<String> excludedAnnouncers) {
947
        this.excludedAnnouncers.clear();
1✔
948
        this.excludedAnnouncers.addAll(normalize(excludedAnnouncers));
1✔
949
    }
1✔
950

951
    public List<String> getExcludedAssemblers() {
952
        return excludedAssemblers;
1✔
953
    }
954

955
    public void setExcludedAssemblers(List<String> excludedAssemblerTypes) {
956
        this.excludedAssemblers.clear();
1✔
957
        this.excludedAssemblers.addAll(normalize(excludedAssemblerTypes));
1✔
958
    }
1✔
959

960
    public List<String> getExcludedCatalogers() {
961
        return excludedCatalogers;
1✔
962
    }
963

964
    public void setExcludedCatalogers(List<String> excludedCatalogers) {
965
        this.excludedCatalogers.clear();
1✔
966
        this.excludedCatalogers.addAll(normalize(excludedCatalogers));
1✔
967
    }
1✔
968

969
    public List<String> getExcludedDistributions() {
970
        return excludedDistributions;
1✔
971
    }
972

973
    public void setExcludedDistributions(List<String> excludedDistributions) {
974
        this.excludedDistributions.clear();
1✔
975
        this.excludedDistributions.addAll(excludedDistributions);
1✔
976
    }
1✔
977

978
    public List<String> getExcludedPackagers() {
979
        return excludedPackagers;
1✔
980
    }
981

982
    public void setExcludedPackagers(List<String> excludedPackagers) {
983
        this.excludedPackagers.clear();
1✔
984
        this.excludedPackagers.addAll(compact(excludedPackagers));
1✔
985
    }
1✔
986

987
    public List<String> getExcludedDownloaderTypes() {
988
        return excludedDownloaderTypes;
1✔
989
    }
990

991
    public void setExcludedDownloaderTypes(List<String> excludedDownloaderTypes) {
992
        this.excludedDownloaderTypes.clear();
1✔
993
        this.excludedDownloaderTypes.addAll(normalize(excludedDownloaderTypes));
1✔
994
    }
1✔
995

996
    public List<String> getExcludedDownloaderNames() {
997
        return excludedDownloaderNames;
1✔
998
    }
999

1000
    public void setExcludedDownloaderNames(List<String> excludedDownloaderNames) {
1001
        this.excludedDownloaderNames.clear();
1✔
1002
        this.excludedDownloaderNames.addAll(excludedDownloaderNames);
1✔
1003
    }
1✔
1004

1005
    public List<String> getExcludedDeployerTypes() {
1006
        return excludedDeployerTypes;
1✔
1007
    }
1008

1009
    public void setExcludedDeployerTypes(List<String> excludedDeployerTypes) {
1010
        this.excludedDeployerTypes.clear();
1✔
1011
        this.excludedDeployerTypes.addAll(normalize(excludedDeployerTypes));
1✔
1012
    }
1✔
1013

1014
    public List<String> getExcludedDeployerNames() {
1015
        return excludedDeployerNames;
1✔
1016
    }
1017

1018
    public void setExcludedDeployerNames(List<String> excludedDeployerNames) {
1019
        this.excludedDeployerNames.clear();
1✔
1020
        this.excludedDeployerNames.addAll(excludedDeployerNames);
1✔
1021
    }
1✔
1022

1023
    public List<String> getExcludedUploaderTypes() {
1024
        return excludedUploaderTypes;
1✔
1025
    }
1026

1027
    public void setExcludedUploaderTypes(List<String> excludedUploaderTypes) {
1028
        this.excludedUploaderTypes.clear();
1✔
1029
        this.excludedUploaderTypes.addAll(normalize(excludedUploaderTypes));
1✔
1030
    }
1✔
1031

1032
    public List<String> getExcludedUploaderNames() {
1033
        return excludedUploaderNames;
1✔
1034
    }
1035

1036
    public void setExcludedUploaderNames(List<String> excludedUploaderNames) {
1037
        this.excludedUploaderNames.clear();
1✔
1038
        this.excludedUploaderNames.addAll(excludedUploaderNames);
1✔
1039
    }
1✔
1040

1041
    public JReleaserCommand getCommand() {
1042
        return command;
1✔
1043
    }
1044

1045
    public TemplateContext props() {
1046
        TemplateContext props = new TemplateContext(model.props());
1✔
1047
        props.set(Constants.KEY_BASEDIR, getBasedir());
1✔
1048
        props.set(Constants.KEY_BASE_OUTPUT_DIRECTORY, getOutputDirectory().getParent());
1✔
1049
        props.set(Constants.KEY_OUTPUT_DIRECTORY, getOutputDirectory());
1✔
1050
        props.set(Constants.KEY_CHECKSUMS_DIRECTORY, getChecksumsDirectory());
1✔
1051
        props.set(Constants.KEY_CATALOGS_DIRECTORY, getCatalogsDirectory());
1✔
1052
        props.set(Constants.KEY_SIGNATURES_DIRECTORY, getSignaturesDirectory());
1✔
1053
        props.set(Constants.KEY_PREPARE_DIRECTORY, getPrepareDirectory());
1✔
1054
        props.set(Constants.KEY_PACKAGE_DIRECTORY, getPackageDirectory());
1✔
1055
        props.set(Constants.KEY_DOWNLOAD_DIRECTORY, getDownloadDirectory());
1✔
1056
        props.set(Constants.KEY_ASSEMBLE_DIRECTORY, getAssembleDirectory());
1✔
1057
        props.set(Constants.KEY_ARTIFACTS_DIRECTORY, getArtifactsDirectory());
1✔
1058
        props.set(Constants.KEY_DEPLOY_DIRECTORY, getDeployDirectory());
1✔
1059
        if (null != getCommand()) props.set(Constants.KEY_COMMAND, getCommand().toStep());
1✔
1060
        return props;
1✔
1061
    }
1062

1063
    public TemplateContext fullProps() {
1064
        TemplateContext props = new TemplateContext(props());
1✔
1065
        props.setAll(model.props());
1✔
1066
        return props;
1✔
1067
    }
1068

1069
    public Map<String, Object> getAdditionalProperties() {
1070
        return additionalProperties;
1✔
1071
    }
1072

1073
    @Override
1074
    public String toString() {
1075
        return "JReleaserContext[" +
×
1076
            "basedir=" + basedir.toAbsolutePath() +
×
1077
            ", outputDirectory=" + outputDirectory.toAbsolutePath() +
×
1078
            ", dryrun=" + dryrun +
1079
            ", gitRootSearch=" + gitRootSearch +
1080
            ", strict=" + strict +
1081
            ", mode=" + mode +
1082
            "]";
1083
    }
1084

1085
    public void report() {
1086
        Project project = model.getProject();
1✔
1087

1088
        SortedProperties props = new SortedProperties();
1✔
1089
        props.put(KEY_TIMESTAMP, model.getTimestamp());
1✔
1090
        props.put(KEY_PLATFORM, PlatformUtils.getCurrentFull());
1✔
1091
        props.put(KEY_PLATFORM_REPLACED, model.getPlatform().applyReplacements(PlatformUtils.getCurrentFull()));
1✔
1092
        if (null != model.getCommit()) {
1✔
1093
            props.put(KEY_COMMIT_SHORT_HASH, model.getCommit().getShortHash());
1✔
1094
            props.put(KEY_COMMIT_FULL_HASH, model.getCommit().getFullHash());
1✔
1095
        }
1096
        props.put(KEY_PROJECT_NAME, project.getName());
1✔
1097
        props.put(KEY_PROJECT_VERSION, project.getVersion());
1✔
1098
        props.put(KEY_PROJECT_SNAPSHOT, String.valueOf(project.isSnapshot()));
1✔
1099
        if (null != model.getCommit()) {
1✔
1100
            BaseReleaser<?, ?> releaser = model.getRelease().getReleaser();
1✔
1101
            if (null != releaser) {
1✔
1102
                safePut(KEY_TAG_NAME, releaser.getEffectiveTagName(model), props);
1✔
1103
                String previousTagName = releaser.getResolvedPreviousTagName(model);
1✔
1104
                safePut(KEY_PREVIOUS_TAG_NAME, previousTagName, props);
1✔
1105
                safePut("releaseBranch", releaser.getBranch(), props);
1✔
1106
                if (releaser.isReleaseSupported()) {
1✔
1107
                    safePut(KEY_RELEASE_NAME, releaser.getEffectiveReleaseName(), props);
1✔
1108
                    safePut(KEY_MILESTONE_NAME, releaser.getMilestone().getEffectiveName(), props);
1✔
1109
                }
1110
            }
1111
        }
1112
        props.put("javaVersion", System.getProperty("java.version"));
1✔
1113
        props.put("javaVendor", System.getProperty("java.vendor"));
1✔
1114
        props.put("javaVmVersion", System.getProperty("java.vm.version"));
1✔
1115

1116
        Map<String, Object> resolvedExtraProperties = project.resolvedExtraProperties();
1✔
1117
        safePut(project.prefix() + capitalize(KEY_VERSION_MAJOR), resolvedExtraProperties, props);
1✔
1118
        safePut(project.prefix() + capitalize(KEY_VERSION_MINOR), resolvedExtraProperties, props);
1✔
1119
        safePut(project.prefix() + capitalize(KEY_VERSION_PATCH), resolvedExtraProperties, props);
1✔
1120
        safePut(project.prefix() + capitalize(KEY_VERSION_NUMBER), resolvedExtraProperties, props);
1✔
1121
        safePut(project.prefix() + capitalize(KEY_VERSION_PRERELEASE), resolvedExtraProperties, props);
1✔
1122
        safePut(project.prefix() + capitalize(KEY_VERSION_TAG), resolvedExtraProperties, props);
1✔
1123
        safePut(project.prefix() + capitalize(KEY_VERSION_BUILD), resolvedExtraProperties, props);
1✔
1124
        safePut(project.prefix() + capitalize(KEY_VERSION_OPTIONAL), resolvedExtraProperties, props);
1✔
1125
        safePut(project.prefix() + capitalize(KEY_VERSION_YEAR), resolvedExtraProperties, props);
1✔
1126
        safePut(project.prefix() + capitalize(KEY_VERSION_MONTH), resolvedExtraProperties, props);
1✔
1127
        safePut(project.prefix() + capitalize(KEY_VERSION_DAY), resolvedExtraProperties, props);
1✔
1128
        safePut(project.prefix() + capitalize(KEY_VERSION_WEEK), resolvedExtraProperties, props);
1✔
1129
        safePut(project.prefix() + capitalize(KEY_VERSION_MICRO), resolvedExtraProperties, props);
1✔
1130
        safePut(project.prefix() + capitalize(KEY_VERSION_MODIFIER), resolvedExtraProperties, props);
1✔
1131

1132
        props.putAll(getAdditionalProperties());
1✔
1133

1134
        Path output = getOutputDirectory().resolve("output.properties");
1✔
1135

1136
        try (FileOutputStream out = new FileOutputStream(output.toFile())) {
1✔
1137
            logger.info(RB.$("context.writing.properties"),
1✔
1138
                relativizeToBasedir(output));
1✔
1139
            props.store(out, "JReleaser " + JReleaserVersion.getPlainVersion());
1✔
1140
        } catch (IOException ignored) {
×
1141
            logger.warn(RB.$("context.writing.properties.error"),
×
1142
                relativizeToBasedir(output));
×
1143
        }
1✔
1144
    }
1✔
1145

1146
    public void nag(String version, String message) {
1147
        logger.warn(RB.$("context.nag", message, version));
×
1148
    }
×
1149

1150
    public Keyring createKeyring() throws SigningException {
1151
        try {
1152
            org.jreleaser.model.internal.signing.Signing signing = model.getSigning();
1✔
1153

1154
            if (!signing.isEnabled()) {
1✔
1155
                throw new SigningException(RB.$("ERROR_signing_disabled"));
×
1156
            }
1157

1158
            if (signing.getMode() == Signing.Mode.FILE) {
1✔
1159
                return new FilesKeyring(
×
1160
                    signing.isVerify() ? basedir.resolve(signing.getPublicKey()) : null,
×
1161
                    basedir.resolve(signing.getSecretKey())
×
1162
                ).initialize(signing.isArmored());
×
1163
            }
1164

1165
            return new InMemoryKeyring(
1✔
1166
                signing.isVerify() ? signing.getPublicKey().getBytes(UTF_8) : null,
1✔
1167
                signing.getSecretKey().getBytes(UTF_8)
1✔
1168
            ).initialize(signing.isArmored());
1✔
1169
        } catch (IOException | PGPException e) {
×
1170
            throw new SigningException(RB.$("ERROR_signing_init_keyring"), e);
×
1171
        }
1172
    }
1173

1174
    public boolean isDistributionIncluded(org.jreleaser.model.internal.distributions.Distribution distribution) {
1175
        String distributionName = distribution.getName();
1✔
1176

1177
        if (!includedDistributions.isEmpty()) {
1✔
1178
            return includedDistributions.contains(distributionName);
×
1179
        }
1180

1181
        if (!excludedDistributions.isEmpty()) {
1✔
1182
            return !excludedDistributions.contains(distributionName);
×
1183
        }
1184

1185
        return true;
1✔
1186
    }
1187

1188
    public void fireSessionStartEvent() throws WorkflowListenerException {
1189
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1190
            try {
1191
                workflowListener.onSessionStart(this.asImmutable());
×
1192
            } catch (RuntimeException e) {
×
1193
                throw new WorkflowListenerException(workflowListener, e);
×
1194
            }
×
1195
        }
×
1196
    }
1✔
1197

1198
    public void fireSessionEndEvent() throws WorkflowListenerException {
1199
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1200
            try {
1201
                workflowListener.onSessionEnd(this.asImmutable());
×
1202
            } catch (RuntimeException e) {
×
1203
                throw new WorkflowListenerException(workflowListener, e);
×
1204
            }
×
1205
        }
×
1206
    }
1✔
1207

1208
    public void fireWorkflowEvent(ExecutionEvent event) throws WorkflowListenerException {
1209
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1210
            try {
1211
                workflowListener.onWorkflowStep(event, this.asImmutable());
×
1212
            } catch (RuntimeException e) {
×
1213
                throw new WorkflowListenerException(workflowListener, e);
×
1214
            }
×
1215
        }
×
1216
    }
1✔
1217

1218
    public void fireAnnounceStepEvent(ExecutionEvent event, Announcer announcer) throws WorkflowListenerException {
1219
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1220
            try {
1221
                workflowListener.onAnnounceStep(event, this.asImmutable(), announcer);
×
1222
            } catch (RuntimeException e) {
×
1223
                throw new WorkflowListenerException(workflowListener, e);
×
1224
            }
×
1225
        }
×
1226
    }
1✔
1227

1228
    public void fireAssembleStepEvent(ExecutionEvent event, Assembler assembler) throws WorkflowListenerException {
1229
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1230
            try {
1231
                workflowListener.onAssembleStep(event, this.asImmutable(), assembler);
×
1232
            } catch (RuntimeException e) {
×
1233
                throw new WorkflowListenerException(workflowListener, e);
×
1234
            }
×
1235
        }
×
1236
    }
1✔
1237

1238
    public void fireCatalogStepEvent(ExecutionEvent event, Cataloger cataloger) throws WorkflowListenerException {
1239
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1240
            try {
1241
                workflowListener.onCatalogStep(event, this.asImmutable(), cataloger);
×
1242
            } catch (RuntimeException e) {
×
1243
                throw new WorkflowListenerException(workflowListener, e);
×
1244
            }
×
1245
        }
×
1246
    }
1✔
1247

1248
    public void fireDeployStepEvent(ExecutionEvent event, Deployer deployer) throws WorkflowListenerException {
1249
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1250
            try {
1251
                workflowListener.onDeployStep(event, this.asImmutable(), deployer);
×
1252
            } catch (RuntimeException e) {
×
1253
                throw new WorkflowListenerException(workflowListener, e);
×
1254
            }
×
1255
        }
×
1256
    }
1✔
1257

1258
    public void fireDownloadStepEvent(ExecutionEvent event, Downloader downloader) throws WorkflowListenerException {
1259
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1260
            try {
1261
                workflowListener.onDownloadStep(event, this.asImmutable(), downloader);
×
1262
            } catch (RuntimeException e) {
×
1263
                throw new WorkflowListenerException(workflowListener, e);
×
1264
            }
×
1265
        }
×
1266
    }
1✔
1267

1268
    public void fireUploadStepEvent(ExecutionEvent event, Uploader uploader) throws WorkflowListenerException {
1269
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1270
            try {
1271
                workflowListener.onUploadStep(event, this.asImmutable(), uploader);
×
1272
            } catch (RuntimeException e) {
×
1273
                throw new WorkflowListenerException(workflowListener, e);
×
1274
            }
×
1275
        }
×
1276
    }
1✔
1277

1278
    public void fireReleaseStepEvent(ExecutionEvent event, Releaser releaser) throws WorkflowListenerException {
1279
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1280
            try {
1281
                workflowListener.onReleaseStep(event, this.asImmutable(), releaser);
×
1282
            } catch (RuntimeException e) {
×
1283
                throw new WorkflowListenerException(workflowListener, e);
×
1284
            }
×
1285
        }
×
1286
    }
1✔
1287

1288
    public void fireDistributionStartEvent(Distribution distribution) throws WorkflowListenerException {
1289
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1290
            try {
1291
                workflowListener.onDistributionStart(this.asImmutable(), distribution);
×
1292
            } catch (RuntimeException e) {
×
1293
                throw new WorkflowListenerException(workflowListener, e);
×
1294
            }
×
1295
        }
×
1296
    }
1✔
1297

1298
    public void fireDistributionEndEvent(Distribution distribution) throws WorkflowListenerException {
1299
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1300
            try {
1301
                workflowListener.onDistributionEnd(this.asImmutable(), distribution);
×
1302
            } catch (RuntimeException e) {
×
1303
                throw new WorkflowListenerException(workflowListener, e);
×
1304
            }
×
1305
        }
×
1306
    }
1✔
1307

1308
    public void firePackagerPackageEvent(ExecutionEvent event, Distribution distribution, Packager packager) throws WorkflowListenerException {
1309
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1310
            try {
1311
                workflowListener.onPackagerPackageStep(event, this.asImmutable(), distribution, packager);
×
1312
            } catch (RuntimeException e) {
×
1313
                throw new WorkflowListenerException(workflowListener, e);
×
1314
            }
×
1315
        }
×
1316
    }
1✔
1317

1318
    public void firePackagerPublishEvent(ExecutionEvent event, Distribution distribution, Packager packager) throws WorkflowListenerException {
1319
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1320
            try {
1321
                workflowListener.onPackagerPublishStep(event, this.asImmutable(), distribution, packager);
×
1322
            } catch (RuntimeException e) {
×
1323
                throw new WorkflowListenerException(workflowListener, e);
×
1324
            }
×
1325
        }
×
1326
    }
1✔
1327

1328
    public void firePackagerPrepareEvent(ExecutionEvent event, Distribution distribution, Packager packager) throws WorkflowListenerException {
1329
        for (WorkflowListener workflowListener : workflowListeners) {
1✔
1330
            try {
1331
                workflowListener.onPackagerPrepareStep(event, this.asImmutable(), distribution, packager);
×
1332
            } catch (RuntimeException e) {
×
1333
                throw new WorkflowListenerException(workflowListener, e);
×
1334
            }
×
1335
        }
×
1336
    }
1✔
1337

1338
    public enum Configurer {
1✔
1339
        CLI("CLI flags"),
1✔
1340
        CLI_YAML("CLI yaml DSL"),
1✔
1341
        CLI_TOML("CLI toml DSL"),
1✔
1342
        CLI_JSON("CLI json DSL"),
1✔
1343
        MAVEN("Maven DSL"),
1✔
1344
        GRADLE("Gradle DSL");
1✔
1345

1346
        private final String dsl;
1347

1348
        Configurer(String dsl) {
1✔
1349
            this.dsl = dsl;
1✔
1350
        }
1✔
1351

1352
        @Override
1353
        public String toString() {
1354
            return this.dsl;
1✔
1355
        }
1356
    }
1357

1358
    private static class SortedProperties extends Properties {
1359
        private static final long serialVersionUID = 8794541421003888869L;
1360

1361
        // Java 11 calls entrySet() when storing properties
1362
        @Override
1363
        public Set<Map.Entry<Object, Object>> entrySet() {
1364
            int javaMajorVersion = SemanticVersion.javaMajorVersion();
1✔
1365
            if (javaMajorVersion < 11) {
1✔
1366
                return super.entrySet();
×
1367
            }
1368

1369
            Map<Object, Object> map = new TreeMap<>();
1✔
1370
            for (Object k : keySet()) {
1✔
1371
                map.put(String.valueOf(k), get(k));
1✔
1372
            }
1✔
1373
            return map.entrySet();
1✔
1374
        }
1375

1376
        // Java 8 calls keys() when storing properties
1377
        @Override
1378
        public synchronized Enumeration<Object> keys() {
1379
            int javaMajorVersion = SemanticVersion.javaMajorVersion();
×
1380
            if (javaMajorVersion >= 11) {
×
1381
                return super.keys();
×
1382
            }
1383

1384
            Set<Object> keySet = keySet();
×
1385
            List<String> keys = new ArrayList<>(keySet.size());
×
1386
            for (Object key : keySet) {
×
1387
                keys.add(key.toString());
×
1388
            }
×
1389
            Collections.sort(keys);
×
1390
            return new IteratorEnumeration<>(keys.iterator());
×
1391
        }
1392
    }
1393

1394
    private static class IteratorEnumeration<E> implements Enumeration<E> {
1395
        private final Iterator<? extends E> iterator;
1396

1397
        public IteratorEnumeration(Iterator<? extends E> iterator) {
×
1398
            this.iterator = iterator;
×
1399
        }
×
1400

1401
        @Override
1402
        public boolean hasMoreElements() {
1403
            return iterator.hasNext();
×
1404
        }
1405

1406
        @Override
1407
        public E nextElement() {
1408
            return iterator.next();
×
1409
        }
1410
    }
1411
}
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