##// END OF EJS Templates
Reworked ImageName, added imageName property to the project extension, added TagImage task.
cin -
r4:00ef236c472b v1.1 default
parent child
Show More
@@ -0,0 +1,66
1 package org.implab.gradle.containers;
2
3 import java.io.Serializable;
4 import java.util.Optional;
5
6 public class ImageName implements Serializable {
7
8 private static final long serialVersionUID = -1990105923537254552L;
9
10 final String authority;
11
12 final String name;
13
14 final String tag;
15
16 public ImageName() {
17 name = null;
18 authority = null;
19 tag = null;
20 }
21
22 private ImageName(String authority, String name, String tag) {
23 this.authority = authority;
24 this.name = name;
25 this.tag = tag;
26 }
27
28 public String getAuthority() {
29 return authority;
30 }
31
32 public ImageName authority(String authority) {
33 return new ImageName(authority, name, tag);
34 }
35
36 public String getName() {
37 return name;
38 }
39
40 public ImageName name(String name) {
41 return new ImageName(authority, name, tag);
42 }
43
44 public String getTag() {
45 return tag;
46 }
47
48 public ImageName tag(String tag) {
49 return new ImageName(authority, name, tag);
50 }
51
52 public ImageName copy() {
53 return new ImageName(authority, name, tag);
54 }
55
56 @Override
57 public String toString() {
58 StringBuilder sb = new StringBuilder();
59
60 Optional.ofNullable(authority).ifPresent(s -> sb.append(s).append("/"));
61 Optional.ofNullable(name).ifPresent(s -> sb.append(s));
62 Optional.ofNullable(tag).ifPresent(s-> sb.append(":").append(s));
63
64 return sb.toString();
65 }
66 }
@@ -0,0 +1,42
1 package org.implab.gradle.containers.tasks;
2
3 import java.util.List;
4 import java.util.concurrent.Callable;
5
6 import org.gradle.api.provider.ListProperty;
7 import org.gradle.api.provider.Property;
8 import org.gradle.api.tasks.Input;
9 import org.gradle.api.tasks.Optional;
10 import org.implab.gradle.containers.ImageName;
11
12 public abstract class TagImage extends CliTask {
13
14 @Input
15 public abstract Property<ImageName> getSrcImage();
16
17 @Input
18 public abstract Property<ImageName> getDestImage();
19
20 @Input
21 @Optional
22 public abstract Property<String> getTransport();
23
24 @Input
25 @Optional
26 public abstract ListProperty<String> getOptions();
27
28 public TagImage option(Callable<String> provider) {
29 getOptions().add(getProject().provider(provider));
30 return this;
31 }
32
33 @Override
34 protected void preparingCommand(List<String> commandLine) {
35 super.preparingCommand(commandLine);
36
37 commandLine.add("tag");
38 commandLine.addAll(getOptions().get());
39 commandLine.add(getSrcImage().get().toString());
40 commandLine.add(getDestImage().get().toString());
41 }
42 }
@@ -1,6 +1,6
1 1 plugins {
2 2 id "java-gradle-plugin"
3 id "com.gradle.plugin-publish" version "0.15.0"
3 id "com.gradle.plugin-publish" version "0.16.0"
4 4 }
5 5
6 6
@@ -9,12 +9,11 repositories {
9 9 }
10 10
11 11 gradlePlugin {
12 website = 'https://code.implab.org/implab/gradle-container-plugin'
13 vcsUrl = 'https://code.implab.org/implab/gradle-container-plugin'
14
15 12 plugins {
16 13 containerPlugin {
17 14 id = 'org.implab.gradle-container'
15 displayName = "Container building plugin"
16 description = 'Build and publish container images with docker or podman. Simple wrapper around cli.'
18 17 implementationClass = 'org.implab.gradle.containers.ContainerPlugin'
19 18 }
20 19 }
@@ -25,10 +24,4 pluginBundle {
25 24 vcsUrl = 'https://code.implab.org/implab/gradle-container-plugin'
26 25
27 26 tags = ['containers', 'image', 'docker', 'podman']
28
29 plugins {
30 containerPlugin {
31 description = 'Build and publish container images with docker or podman'
32 }
33 }
34 27 }
@@ -1,2 +1,2
1 1 group=org.implab.gradle
2 version=1.0 No newline at end of file
2 version=1.1 No newline at end of file
@@ -1,10 +1,14
1 1 package org.implab.gradle.containers;
2 2
3 import java.util.Optional;
4
5 import org.gradle.api.Project;
3 6 import org.gradle.api.file.DirectoryProperty;
4 7 import org.gradle.api.file.ProjectLayout;
5 8 import org.gradle.api.file.RegularFileProperty;
6 9 import org.gradle.api.model.ObjectFactory;
7 10 import org.gradle.api.provider.Property;
11 import org.gradle.api.provider.Provider;
8 12
9 13 public class ContainerExtension {
10 14
@@ -14,11 +18,17 public class ContainerExtension {
14 18
15 19 private final Property<String> imageGroup;
16 20
21 private final Property<String> imageShortName;
22
23 private final Property<String> imageTag;
24
25 private final Property<ImageName> imageName;
26
17 27 private final DirectoryProperty contextDir;
18 28
19 29 private final RegularFileProperty imageIdFile;
20 30
21 public ContainerExtension(ObjectFactory factory, ProjectLayout layout) {
31 public ContainerExtension(ObjectFactory factory, ProjectLayout layout, Project project) {
22 32 contextDir = factory.directoryProperty();
23 33 contextDir.convention(layout.getBuildDirectory().dir("context"));
24 34
@@ -30,6 +40,19 public class ContainerExtension {
30 40
31 41 imageAuthority = factory.property(String.class);
32 42 imageGroup = factory.property(String.class);
43 imageShortName = factory.property(String.class);
44
45 imageShortName.convention(project.getName());
46
47 imageTag = factory.property(String.class);
48 imageTag.set(project
49 .provider(() -> Optional.ofNullable(project.getVersion()).map(v -> v.toString()).orElse("latest")));
50
51 Provider<String> imageRepository = imageGroup.map(g -> g + "/" + imageShortName.get()).orElse(imageShortName);
52
53 imageName = factory.property(ImageName.class);
54 imageName.convention(project.provider(
55 () -> new ImageName().authority(imageAuthority.get()).name(imageRepository.get()).tag(imageTag.get())));
33 56 }
34 57
35 58 public Property<String> getCliCmd() {
@@ -55,4 +78,17 public class ContainerExtension {
55 78 public Property<String> getImageGroup() {
56 79 return imageGroup;
57 80 }
81
82 public Property<ImageName> getImageName() {
83 return imageName;
84 }
85
86 public Property<String> getImageShortName() {
87 return imageShortName;
88 }
89
90 public ImageName createImageName() {
91 return new ImageName();
92 }
93
58 94 } No newline at end of file
@@ -1,20 +1,18
1 1 package org.implab.gradle.containers;
2 2
3 import java.util.Optional;
4
5 3 import org.gradle.api.Plugin;
6 4 import org.gradle.api.Project;
7 5 import org.gradle.api.artifacts.Dependency;
8 6 import org.gradle.api.file.ProjectLayout;
9 7 import org.gradle.api.model.ObjectFactory;
10 8 import org.gradle.api.plugins.ExtraPropertiesExtension;
11 import org.gradle.api.provider.Provider;
12 9 import org.gradle.api.tasks.Copy;
13 10 import org.gradle.api.tasks.Delete;
14 11 import org.gradle.api.tasks.TaskProvider;
15 12 import org.implab.gradle.containers.tasks.BuildImage;
16 13 import org.implab.gradle.containers.tasks.PushImage;
17 14 import org.implab.gradle.containers.tasks.SaveImage;
15 import org.implab.gradle.containers.tasks.TagImage;
18 16
19 17 public class ContainerPlugin implements Plugin<Project> {
20 18
@@ -29,7 +27,7 public class ContainerPlugin implements
29 27 public void apply(Project project) {
30 28 ObjectFactory factory = project.getObjects();
31 29 ProjectLayout layout = project.getLayout();
32 containerExtension = new ContainerExtension(factory, layout);
30 containerExtension = new ContainerExtension(factory, layout, project);
33 31
34 32 containerExtension.getImageAuthority()
35 33 .convention(project.provider(() -> (String) project.getProperties().get("imagesAuthority")));
@@ -43,6 +41,7 public class ContainerPlugin implements
43 41 extras.set(BuildImage.class.getSimpleName(), BuildImage.class);
44 42 extras.set(PushImage.class.getSimpleName(), PushImage.class);
45 43 extras.set(SaveImage.class.getSimpleName(), SaveImage.class);
44 extras.set(TagImage.class.getSimpleName(), TagImage.class);
46 45
47 46 project.getConfigurations().create(Dependency.DEFAULT_CONFIGURATION, c -> {
48 47 c.setCanBeConsumed(true);
@@ -67,13 +66,7 public class ContainerPlugin implements
67 66 t.getContextDirectory().set(containerExtension.getContextDirectory());
68 67 t.getImageIdFile().set(containerExtension.getImageIdFile());
69 68
70 Provider<String> imageName = containerExtension.getImageGroup().map(g -> g + "/" + project.getName())
71 .orElse(project.getName());
72
73 t.getImageAuthority().set(containerExtension.getImageAuthority());
74 t.getImageQName().convention(imageName);
75 t.getImageVersion()
76 .convention(Optional.ofNullable(project.getVersion()).map(v -> v.toString()).orElse("latest"));
69 t.getImageName().set(containerExtension.getImageName());
77 70 });
78 71
79 72 project.getTasks().register("clean", Delete.class, t -> {
@@ -87,12 +80,12 public class ContainerPlugin implements
87 80
88 81 project.getTasks().register("pushImage", PushImage.class, t -> {
89 82 t.dependsOn(buildImageTask);
90 t.getSrcImage().set(buildImageTask.flatMap(b -> b.getImageTag()));
83 t.getImageName().set(buildImageTask.flatMap(b -> b.getImageName()));
91 84 });
92 85
93 86 project.getTasks().register("saveImage", SaveImage.class, t -> {
94 87 t.dependsOn(buildImageTask);
95 t.getImage().set(buildImageTask.flatMap(b -> b.getImageTag()));
88 t.getImage().set(buildImageTask.flatMap(b -> b.getImageName()));
96 89 });
97 90
98 91 project.getArtifacts().add(Dependency.DEFAULT_CONFIGURATION, buildImageTask.flatMap(x -> x.getImageIdFile()), t -> {
@@ -5,39 +5,20 import java.util.List;
5 5 import org.gradle.api.file.DirectoryProperty;
6 6 import org.gradle.api.file.RegularFileProperty;
7 7 import org.gradle.api.provider.Property;
8 import org.gradle.api.provider.Provider;
9 8 import org.gradle.api.tasks.Input;
10 9 import org.gradle.api.tasks.InputDirectory;
11 import org.gradle.api.tasks.Internal;
12 10 import org.gradle.api.tasks.OutputFile;
13 11 import org.gradle.api.tasks.SkipWhenEmpty;
14 12 import org.implab.gradle.Utils;
15 import org.implab.gradle.containers.ImageTag;
13 import org.implab.gradle.containers.ImageName;
16 14
17 15 public abstract class BuildImage extends CliTask {
18 16 @InputDirectory
19 17 @SkipWhenEmpty
20 18 public abstract DirectoryProperty getContextDirectory();
21 19
22 @Internal
23 public abstract Property<String> getImageQName();
24
25 @Internal
26 public abstract Property<String> getImageVersion();
27
28 @Internal
29 public abstract Property<String> getImageAuthority();
30
31 20 @Input
32 public Provider<ImageTag> getImageTag() {
33 return getProject().provider(() -> {
34 ImageTag tag = new ImageTag();
35 tag.setQName(getImageQName().getOrNull());
36 tag.setAuthority(getImageAuthority().getOrNull());
37 tag.setVersion(getImageVersion().getOrNull());
38 return tag;
39 });
40 }
21 public abstract Property<ImageName> getImageName();
41 22
42 23 @OutputFile
43 24 public abstract RegularFileProperty getImageIdFile();
@@ -52,7 +33,7 public abstract class BuildImage extends
52 33 super.preparingCommand(commandLine);
53 34
54 35 commandLine.addAll(List.of("build", ".", "-q", "-t"));
55 commandLine.add(getImageTag().get().toString());
36 commandLine.add(getImageName().get().toString());
56 37 }
57 38
58 39 @Override
@@ -5,20 +5,14 import java.util.concurrent.Callable;
5 5
6 6 import org.gradle.api.provider.ListProperty;
7 7 import org.gradle.api.provider.Property;
8 import org.gradle.api.provider.Provider;
9 8 import org.gradle.api.tasks.Input;
10 import org.gradle.api.tasks.Internal;
11 9 import org.gradle.api.tasks.Optional;
12 import org.implab.gradle.containers.ImageTag;
10 import org.implab.gradle.containers.ImageName;
13 11
14 12 public abstract class PushImage extends CliTask {
15 13
16 14 @Input
17 public abstract Property<ImageTag> getSrcImage();
18
19 @Input
20 @Optional
21 public abstract Property<ImageTag> getDestImage();
15 public abstract Property<ImageName> getImageName();
22 16
23 17 @Input
24 18 @Optional
@@ -33,19 +27,12 public abstract class PushImage extends
33 27 return this;
34 28 }
35 29
36 @Internal
37 public Provider<String> getDestination() {
38 return getDestImage().flatMap(tag -> getTransport().orElse("").map(t -> t + tag.toString()));
39 }
40
41 30 @Override
42 31 protected void preparingCommand(List<String> commandLine) {
43 32 super.preparingCommand(commandLine);
44 33
45 34 commandLine.add("push");
46 35 commandLine.addAll(getOptions().get());
47 commandLine.add(getSrcImage().get().toString());
48 if (getDestination().isPresent())
49 commandLine.add(getDestination().get());
36 commandLine.add(getImageName().get().toString());
50 37 }
51 38 }
@@ -13,12 +13,12 import org.gradle.api.tasks.Internal;
13 13 import org.gradle.api.tasks.OutputFile;
14 14 import org.gradle.api.tasks.TaskExecutionException;
15 15 import org.implab.gradle.Utils;
16 import org.implab.gradle.containers.ImageTag;
16 import org.implab.gradle.containers.ImageName;
17 17
18 18 public abstract class SaveImage extends CliTask {
19 19
20 20 @Input
21 public abstract Property<ImageTag> getImage();
21 public abstract Property<ImageName> getImage();
22 22
23 23 @OutputFile
24 24 public Provider<RegularFile> getArchiveFile() {
@@ -5,7 +5,7
5 5 ```gradle
6 6
7 7 plugins {
8 id 'org.implab.gradle-container' version "1.0"
8 id 'org.implab.gradle-container' version '1.1'
9 9 }
10 10
11 11 container {
@@ -81,3 +81,30 The task pushes the image to the remote
81 81
82 82 The copy task, it prepares the build context. Use it to customize
83 83 the build context.
84
85 ### tagImage
86
87 since: 1.1
88
89 ```gradle
90 task tagLatest(type: TagImage) {
91 srcImage = container.imageName
92 destImage = container.imageName.map { it.tag("latest") }
93 }
94
95 ```
96
97 ## Changes
98
99 ### 1.1
100
101 Warning! This version isn't fully backward compatible with 1.0 version.
102
103 * Added `TagImage` task type
104 * `ImageTag` class is replaced with `ImageName` class
105 * `BuildImage`, `PushImage` tasks are now accepting only `imageName` property
106 * Added `imageName`, `imageShortName`, `imageTag` properties to `container` extension
107
108 ### 1.0
109
110 Initial release. Default tasks to build and publish container images.
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now