Skip to content

Commit 77dadaf

Browse files
author
Mathieu Gabelle
committed
refactor: migrate to property v2
migration of abstract class
1 parent 77d6ad2 commit 77dadaf

19 files changed

+463
-533
lines changed

src/main/java/io/kestra/plugin/git/AbstractCloningTask.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package io.kestra.plugin.git;
22

3-
import io.kestra.core.models.annotations.PluginProperty;
3+
import io.kestra.core.models.property.Property;
44
import io.swagger.v3.oas.annotations.media.Schema;
55
import lombok.Getter;
66
import lombok.NoArgsConstructor;
@@ -13,6 +13,5 @@ public abstract class AbstractCloningTask extends AbstractGitTask {
1313
@Schema(
1414
title = "Whether to clone submodules."
1515
)
16-
@PluginProperty
17-
protected Boolean cloneSubmodules;
16+
protected Property<Boolean> cloneSubmodules;
1817
}
Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package io.kestra.plugin.git;
22

3-
import io.kestra.core.models.annotations.PluginProperty;
3+
import io.kestra.core.models.property.Property;
44
import io.kestra.core.models.tasks.Task;
55
import io.kestra.core.runners.RunContext;
66
import io.kestra.plugin.git.services.SshTransportConfigCallback;
@@ -18,68 +18,55 @@
1818
@NoArgsConstructor
1919
@Getter
2020
public abstract class AbstractGitTask extends Task {
21-
private static final Pattern PEBBLE_TEMPLATE_PATTERN = Pattern.compile("^\\s*\\{\\{");
2221

2322
@Schema(
2423
title = "The URI to clone from."
2524
)
26-
@PluginProperty(dynamic = true)
27-
protected String url;
25+
protected Property<String> url;
2826

2927
@Schema(
3028
title = "The username or organization."
3129
)
32-
@PluginProperty(dynamic = true)
33-
protected String username;
30+
protected Property<String> username;
3431

3532
@Schema(
3633
title = "The password or Personal Access Token (PAT). When you authenticate the task with a PAT, any flows or files pushed to Git from Kestra will be pushed from the user associated with that PAT. This way, you don't need to configure the commit author (the `authorName` and `authorEmail` properties)."
3734
)
38-
@PluginProperty(dynamic = true)
39-
protected String password;
35+
protected Property<String> password;
4036

4137
@Schema(
4238
title = "PEM-format private key content that is paired with a public key registered on Git.",
4339
description = "To generate an ECDSA PEM format key from OpenSSH, use the following command: `ssh-keygen -t ecdsa -b 256 -m PEM`. " +
4440
"You can then set this property with your private key content and put your public key on Git."
4541
)
46-
@PluginProperty(dynamic = true)
47-
protected String privateKey;
42+
protected Property<String> privateKey;
4843

4944
@Schema(
5045
title = "The passphrase for the `privateKey`."
5146
)
52-
@PluginProperty(dynamic = true)
53-
protected String passphrase;
47+
protected Property<String> passphrase;
5448

5549

5650
@Schema(
5751
title = "The initial Git branch."
5852
)
59-
@PluginProperty(dynamic = true)
60-
public abstract String getBranch();
53+
public abstract Property<String> getBranch();
6154

6255
public <T extends TransportCommand<T, ?>> T authentified(T command, RunContext runContext) throws Exception {
6356
if (this.username != null && this.password != null) {
6457
command.setCredentialsProvider(new UsernamePasswordCredentialsProvider(
65-
runContext.render(this.username),
66-
runContext.render(this.password)
58+
runContext.render(this.username).as(String.class).orElseThrow(),
59+
runContext.render(this.password).as(String.class).orElseThrow()
6760
));
6861
}
6962

7063
if (this.privateKey != null) {
7164
command.setTransportConfigCallback(new SshTransportConfigCallback(
72-
runContext.render(this.privateKey).getBytes(StandardCharsets.UTF_8),
73-
runContext.render(this.passphrase)
65+
runContext.render(this.privateKey).as(String.class).orElseThrow().getBytes(StandardCharsets.UTF_8),
66+
runContext.render(this.passphrase).as(String.class).orElse(null)
7467
));
7568
}
7669

7770
return command;
7871
}
79-
80-
protected void detectPasswordLeaks() {
81-
if (this.password != null && !PEBBLE_TEMPLATE_PATTERN.matcher(this.password).find()) {
82-
throw new IllegalArgumentException("It looks like you have hard-coded Git credentials. Make sure to pass the credential securely using a Pebble expression (e.g. using secrets or environment variables).");
83-
}
84-
}
8572
}

src/main/java/io/kestra/plugin/git/AbstractPushTask.java

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package io.kestra.plugin.git;
22

33
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
4-
import io.kestra.core.models.annotations.PluginProperty;
4+
import io.kestra.core.models.property.Property;
55
import io.kestra.core.models.tasks.RunnableTask;
66
import io.kestra.core.runners.RunContext;
77
import io.kestra.core.serializers.JacksonMapper;
@@ -46,41 +46,39 @@
4646
@NoArgsConstructor
4747
@Getter
4848
public abstract class AbstractPushTask<O extends AbstractPushTask.Output> extends AbstractCloningTask implements RunnableTask<O> {
49-
@PluginProperty(dynamic = true)
50-
protected String commitMessage;
49+
protected Property<String> commitMessage;
5150

5251
@Schema(
5352
title = "If `true`, the task will only output modifications without pushing any file to Git yet. If `false` (default), all listed files will be pushed to Git immediately."
5453
)
55-
@PluginProperty
5654
@Builder.Default
57-
private boolean dryRun = false;
55+
private Property<Boolean> dryRun = Property.of(false);
5856

5957
@Schema(
6058
title = "The commit author email.",
6159
description = "If null, no author will be set on this commit."
6260
)
63-
@PluginProperty(dynamic = true)
64-
private String authorEmail;
61+
private Property<String> authorEmail;
6562

6663
@Schema(
6764
title = "The commit author name.",
6865
description = "If null, the username will be used instead.",
6966
defaultValue = "`username`"
7067
)
71-
@PluginProperty(dynamic = true)
72-
private String authorName;
68+
private Property<String> authorName;
7369

74-
public abstract String getCommitMessage();
70+
public String renderCommitMessage(RunContext runContext) throws IllegalVariableEvaluationException {
71+
return runContext.render(this.getCommitMessage()).as(String.class).orElseThrow();
72+
}
7573

76-
public abstract String getGitDirectory();
74+
public abstract Property<String> getGitDirectory();
7775

7876
public abstract Object globs();
7977

80-
public abstract String fetchedNamespace();
78+
public abstract Property<String> fetchedNamespace();
8179

8280
private Path createGitDirectory(RunContext runContext) throws IllegalVariableEvaluationException {
83-
Path flowDirectory = runContext.workingDir().resolve(Path.of(runContext.render(this.getGitDirectory())));
81+
Path flowDirectory = runContext.workingDir().resolve(Path.of(runContext.render(this.getGitDirectory()).as(String.class).orElseThrow()));
8482
flowDirectory.toFile().mkdirs();
8583
return flowDirectory;
8684
}
@@ -130,14 +128,14 @@ protected void writeResourceFile(Path path, InputStream inputStream) throws IOEx
130128
Files.copy(inputStream, path, REPLACE_EXISTING);
131129
}
132130

133-
private URI createDiffFile(RunContext runContext, Git git) throws IOException, GitAPIException {
131+
private URI createDiffFile(RunContext runContext, Git git) throws IOException, GitAPIException, IllegalVariableEvaluationException {
134132
File diffFile = runContext.workingDir().createTempFile(".ion").toFile();
135133
try (DiffFormatter diffFormatter = new DiffFormatter(null);
136134
BufferedWriter diffWriter = new BufferedWriter(new FileWriter(diffFile))) {
137135
diffFormatter.setRepository(git.getRepository());
138136

139137
DiffCommand diff = git.diff();
140-
if (this.dryRun) {
138+
if (runContext.render(this.dryRun).as(Boolean.class).orElse(false)) {
141139
diff = diff.setCached(true);
142140
} else {
143141
diff = diff.setOldTree(treeIterator(git, "HEAD~1"))
@@ -204,21 +202,21 @@ private Output push(Git git, RunContext runContext, GitService gitService) throw
204202
String commitId = null;
205203
ObjectId commit;
206204
try {
207-
String httpUrl = gitService.getHttpUrl(runContext.render(this.url));
208-
if (this.isDryRun()) {
205+
String httpUrl = gitService.getHttpUrl(runContext.render(this.url).as(String.class).orElse(null));
206+
if (runContext.render(dryRun).as(Boolean.class).orElse(false)) {
209207
logger.info(
210208
"Dry run — no changes will be pushed to {} for now until you set the `dryRun` parameter to false",
211209
httpUrl
212210
);
213211
} else {
214-
String renderedBranch = runContext.render(this.getBranch());
212+
String renderedBranch = runContext.render(this.getBranch()).as(String.class).orElse(null);
215213
logger.info(
216214
"Pushing to {} on branch {}",
217215
httpUrl,
218216
renderedBranch
219217
);
220218

221-
String message = runContext.render(this.getCommitMessage());
219+
String message = this.renderCommitMessage(runContext);
222220
ObjectId head = git.getRepository().resolve(Constants.HEAD);
223221
commit = git.commit()
224222
.setAllowEmpty(false)
@@ -247,8 +245,9 @@ private Output push(Git git, RunContext runContext, GitService gitService) throw
247245
}
248246

249247
private PersonIdent author(RunContext runContext) throws IllegalVariableEvaluationException {
250-
String name = Optional.ofNullable(this.authorName).orElse(runContext.render(this.username));
251-
String authorEmail = this.authorEmail;
248+
String name = runContext.render(this.authorName).as(String.class)
249+
.orElse(runContext.render(this.username).as(String.class).orElse(null));
250+
String authorEmail = runContext.render(this.authorEmail).as(String.class).orElse(null);
252251
if (authorEmail == null || name == null) {
253252
return null;
254253
}
@@ -274,9 +273,10 @@ public O run(RunContext runContext) throws Exception {
274273
GitService gitService = new GitService(this);
275274

276275
gitService.namespaceAccessGuard(runContext, this.fetchedNamespace());
277-
this.detectPasswordLeaks();
278276

279-
Git git = gitService.cloneBranch(runContext, runContext.render(this.getBranch()), this.cloneSubmodules);
277+
Git git = gitService.cloneBranch(runContext,
278+
runContext.render(this.getBranch()).as(String.class).orElse(null),
279+
runContext.render(this.cloneSubmodules).as(Boolean.class).orElse(false));
280280

281281
Path localGitDirectory = this.createGitDirectory(runContext);
282282

@@ -291,7 +291,7 @@ public O run(RunContext runContext) throws Exception {
291291
this.writeResourceFiles(contentByPath);
292292

293293
AddCommand add = git.add();
294-
add.addFilepattern(runContext.render(this.getGitDirectory()));
294+
add.addFilepattern(runContext.render(this.getGitDirectory()).as(String.class).orElse(null));
295295
add.call();
296296

297297
Output pushOutput = this.push(git, runContext, gitService);

src/main/java/io/kestra/plugin/git/AbstractSyncTask.java

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
44
import io.kestra.core.models.annotations.PluginProperty;
5+
import io.kestra.core.models.property.Property;
56
import io.kestra.core.models.tasks.RunnableTask;
67
import io.kestra.core.runners.RunContext;
78
import io.kestra.core.serializers.JacksonMapper;
@@ -43,18 +44,17 @@ public abstract class AbstractSyncTask<T, O extends AbstractSyncTask.Output> ext
4344
@Schema(
4445
title = "If `true`, the task will only output modifications without performing any modification to Kestra. If `false` (default), all listed modifications will be applied."
4546
)
46-
@PluginProperty
4747
@Builder.Default
48-
private boolean dryRun = false;
48+
private Property<Boolean> dryRun = Property.of(false);
4949

5050
public abstract boolean isDelete();
5151

52-
public abstract String getGitDirectory();
52+
public abstract Property<String> getGitDirectory();
5353

54-
public abstract String fetchedNamespace();
54+
public abstract Property<String> fetchedNamespace();
5555

5656
private Path createGitDirectory(RunContext runContext) throws IllegalVariableEvaluationException {
57-
Path syncDirectory = runContext.workingDir().resolve(Path.of(runContext.render(this.getGitDirectory())));
57+
Path syncDirectory = runContext.workingDir().resolve(Path.of(runContext.render(this.getGitDirectory()).as(String.class).orElseThrow()));
5858
syncDirectory.toFile().mkdirs();
5959
return syncDirectory;
6060
}
@@ -81,7 +81,7 @@ protected Map<URI, Supplier<InputStream>> gitResourcesContentByUri(Path baseDire
8181
protected boolean traverseDirectories() {
8282
return true;
8383
}
84-
84+
8585
protected boolean mustKeep(RunContext runContext, T instanceResource) {
8686
return false;
8787
}
@@ -100,7 +100,7 @@ private URI createDiffFile(RunContext runContext, String renderedNamespace, Map<
100100
try (BufferedWriter diffWriter = new BufferedWriter(new FileWriter(diffFile))) {
101101
List<SyncResult> syncResults = new ArrayList<>();
102102

103-
String renderedGitDirectory = runContext.render(this.getGitDirectory());
103+
String renderedGitDirectory = runContext.render(this.getGitDirectory()).as(String.class).orElse(null);
104104
if (deletedResources != null) {
105105
deletedResources.stream()
106106
.map(throwFunction(deletedResource -> wrapper(
@@ -146,17 +146,19 @@ private URI createDiffFile(RunContext runContext, String renderedNamespace, Map<
146146
}
147147

148148
public O run(RunContext runContext) throws Exception {
149-
this.detectPasswordLeaks();
150149
GitService gitService = new GitService(this);
151150

152151
gitService.namespaceAccessGuard(runContext, this.fetchedNamespace());
153152

154-
Git git = gitService.cloneBranch(runContext, runContext.render(this.getBranch()), this.cloneSubmodules);
153+
Git git = gitService.cloneBranch(runContext,
154+
runContext.render(this.getBranch()).as(String.class).orElse(null),
155+
runContext.render(this.cloneSubmodules).as(Boolean.class).orElse(false)
156+
);
155157

156158
Path localGitDirectory = this.createGitDirectory(runContext);
157159
Map<URI, Supplier<InputStream>> gitContentByUri = this.gitResourcesContentByUri(localGitDirectory);
158160

159-
String renderedNamespace = runContext.render(this.fetchedNamespace());
161+
String renderedNamespace = runContext.render(this.fetchedNamespace()).as(String.class).orElse(null);
160162

161163
Map<URI, T> beforeUpdateResourcesByUri = this.fetchResources(runContext, renderedNamespace)
162164
.stream()
@@ -170,7 +172,7 @@ public O run(RunContext runContext) throws Exception {
170172
.map(throwFunction(e -> {
171173
InputStream inputStream = e.getValue().get();
172174
T resource;
173-
if (this.dryRun) {
175+
if (runContext.render(dryRun).as(Boolean.class).orElseThrow()) {
174176
resource = this.simulateResourceWrite(runContext, renderedNamespace, e.getKey(), inputStream);
175177
} else {
176178
resource = this.writeResource(runContext, renderedNamespace, e.getKey(), inputStream);
@@ -198,7 +200,7 @@ public O run(RunContext runContext) throws Exception {
198200
return;
199201
}
200202

201-
if (!this.dryRun) {
203+
if (!runContext.render(dryRun).as(Boolean.class).orElseThrow()) {
202204
this.deleteResource(runContext, renderedNamespace, e.getValue());
203205
}
204206

src/main/java/io/kestra/plugin/git/Clone.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import io.kestra.core.models.annotations.Example;
44
import io.kestra.core.models.annotations.Plugin;
55
import io.kestra.core.models.annotations.PluginProperty;
6+
import io.kestra.core.models.property.Property;
67
import io.kestra.core.models.tasks.RunnableTask;
78
import io.kestra.core.runners.RunContext;
89
import io.swagger.v3.oas.annotations.media.Schema;
@@ -78,7 +79,7 @@
7879
code = """
7980
id: git_python
8081
namespace: company.team
81-
82+
8283
tasks:
8384
- id: file_system
8485
type: io.kestra.plugin.core.flow.WorkingDirectory
@@ -105,7 +106,7 @@ public class Clone extends AbstractCloningTask implements RunnableTask<Clone.Out
105106
@PluginProperty(dynamic = true)
106107
private String directory;
107108

108-
private String branch;
109+
private Property<String> branch;
109110

110111
@Schema(
111112
title = "Creates a shallow clone with a history truncated to the specified number of commits."
@@ -118,7 +119,7 @@ public class Clone extends AbstractCloningTask implements RunnableTask<Clone.Out
118119
@Override
119120
public Clone.Output run(RunContext runContext) throws Exception {
120121
Logger logger = runContext.logger();
121-
String url = runContext.render(this.url);
122+
String url = runContext.render(this.url).as(String.class).orElse(null);
122123

123124
Path path = runContext.workingDir().path();
124125
if (this.directory != null) {
@@ -131,15 +132,15 @@ public Clone.Output run(RunContext runContext) throws Exception {
131132
.setDirectory(path.toFile());
132133

133134
if (this.branch != null) {
134-
cloneCommand.setBranch(runContext.render(this.branch));
135+
cloneCommand.setBranch(runContext.render(this.branch).as(String.class).orElseThrow());
135136
}
136137

137138
if (this.depth != null) {
138139
cloneCommand.setDepth(this.depth);
139140
}
140141

141142
if (this.cloneSubmodules != null) {
142-
cloneCommand.setCloneSubmodules(this.cloneSubmodules);
143+
cloneCommand.setCloneSubmodules(runContext.render(this.cloneSubmodules).as(Boolean.class).orElse(false));
143144
}
144145

145146
cloneCommand = authentified(cloneCommand, runContext);
@@ -155,7 +156,7 @@ public Clone.Output run(RunContext runContext) throws Exception {
155156

156157
@Override
157158
@NotNull
158-
public String getUrl() {
159+
public Property<String> getUrl() {
159160
return super.getUrl();
160161
}
161162

0 commit comments

Comments
 (0)