##// 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 plugins {
1 plugins {
2 id "java-gradle-plugin"
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 gradlePlugin {
11 gradlePlugin {
12 website = 'https://code.implab.org/implab/gradle-container-plugin'
13 vcsUrl = 'https://code.implab.org/implab/gradle-container-plugin'
14
15 plugins {
12 plugins {
16 containerPlugin {
13 containerPlugin {
17 id = 'org.implab.gradle-container'
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 implementationClass = 'org.implab.gradle.containers.ContainerPlugin'
17 implementationClass = 'org.implab.gradle.containers.ContainerPlugin'
19 }
18 }
20 }
19 }
@@ -25,10 +24,4 pluginBundle {
25 vcsUrl = 'https://code.implab.org/implab/gradle-container-plugin'
24 vcsUrl = 'https://code.implab.org/implab/gradle-container-plugin'
26
25
27 tags = ['containers', 'image', 'docker', 'podman']
26 tags = ['containers', 'image', 'docker', 'podman']
28
29 plugins {
30 containerPlugin {
31 description = 'Build and publish container images with docker or podman'
32 }
27 }
33 }
34 }
@@ -1,2 +1,2
1 group=org.implab.gradle
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 package org.implab.gradle.containers;
1 package org.implab.gradle.containers;
2
2
3 import java.util.Optional;
4
5 import org.gradle.api.Project;
3 import org.gradle.api.file.DirectoryProperty;
6 import org.gradle.api.file.DirectoryProperty;
4 import org.gradle.api.file.ProjectLayout;
7 import org.gradle.api.file.ProjectLayout;
5 import org.gradle.api.file.RegularFileProperty;
8 import org.gradle.api.file.RegularFileProperty;
6 import org.gradle.api.model.ObjectFactory;
9 import org.gradle.api.model.ObjectFactory;
7 import org.gradle.api.provider.Property;
10 import org.gradle.api.provider.Property;
11 import org.gradle.api.provider.Provider;
8
12
9 public class ContainerExtension {
13 public class ContainerExtension {
10
14
@@ -14,11 +18,17 public class ContainerExtension {
14
18
15 private final Property<String> imageGroup;
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 private final DirectoryProperty contextDir;
27 private final DirectoryProperty contextDir;
18
28
19 private final RegularFileProperty imageIdFile;
29 private final RegularFileProperty imageIdFile;
20
30
21 public ContainerExtension(ObjectFactory factory, ProjectLayout layout) {
31 public ContainerExtension(ObjectFactory factory, ProjectLayout layout, Project project) {
22 contextDir = factory.directoryProperty();
32 contextDir = factory.directoryProperty();
23 contextDir.convention(layout.getBuildDirectory().dir("context"));
33 contextDir.convention(layout.getBuildDirectory().dir("context"));
24
34
@@ -30,6 +40,19 public class ContainerExtension {
30
40
31 imageAuthority = factory.property(String.class);
41 imageAuthority = factory.property(String.class);
32 imageGroup = factory.property(String.class);
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 public Property<String> getCliCmd() {
58 public Property<String> getCliCmd() {
@@ -55,4 +78,17 public class ContainerExtension {
55 public Property<String> getImageGroup() {
78 public Property<String> getImageGroup() {
56 return imageGroup;
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 } No newline at end of file
94 }
@@ -1,20 +1,18
1 package org.implab.gradle.containers;
1 package org.implab.gradle.containers;
2
2
3 import java.util.Optional;
4
5 import org.gradle.api.Plugin;
3 import org.gradle.api.Plugin;
6 import org.gradle.api.Project;
4 import org.gradle.api.Project;
7 import org.gradle.api.artifacts.Dependency;
5 import org.gradle.api.artifacts.Dependency;
8 import org.gradle.api.file.ProjectLayout;
6 import org.gradle.api.file.ProjectLayout;
9 import org.gradle.api.model.ObjectFactory;
7 import org.gradle.api.model.ObjectFactory;
10 import org.gradle.api.plugins.ExtraPropertiesExtension;
8 import org.gradle.api.plugins.ExtraPropertiesExtension;
11 import org.gradle.api.provider.Provider;
12 import org.gradle.api.tasks.Copy;
9 import org.gradle.api.tasks.Copy;
13 import org.gradle.api.tasks.Delete;
10 import org.gradle.api.tasks.Delete;
14 import org.gradle.api.tasks.TaskProvider;
11 import org.gradle.api.tasks.TaskProvider;
15 import org.implab.gradle.containers.tasks.BuildImage;
12 import org.implab.gradle.containers.tasks.BuildImage;
16 import org.implab.gradle.containers.tasks.PushImage;
13 import org.implab.gradle.containers.tasks.PushImage;
17 import org.implab.gradle.containers.tasks.SaveImage;
14 import org.implab.gradle.containers.tasks.SaveImage;
15 import org.implab.gradle.containers.tasks.TagImage;
18
16
19 public class ContainerPlugin implements Plugin<Project> {
17 public class ContainerPlugin implements Plugin<Project> {
20
18
@@ -29,7 +27,7 public class ContainerPlugin implements
29 public void apply(Project project) {
27 public void apply(Project project) {
30 ObjectFactory factory = project.getObjects();
28 ObjectFactory factory = project.getObjects();
31 ProjectLayout layout = project.getLayout();
29 ProjectLayout layout = project.getLayout();
32 containerExtension = new ContainerExtension(factory, layout);
30 containerExtension = new ContainerExtension(factory, layout, project);
33
31
34 containerExtension.getImageAuthority()
32 containerExtension.getImageAuthority()
35 .convention(project.provider(() -> (String) project.getProperties().get("imagesAuthority")));
33 .convention(project.provider(() -> (String) project.getProperties().get("imagesAuthority")));
@@ -43,6 +41,7 public class ContainerPlugin implements
43 extras.set(BuildImage.class.getSimpleName(), BuildImage.class);
41 extras.set(BuildImage.class.getSimpleName(), BuildImage.class);
44 extras.set(PushImage.class.getSimpleName(), PushImage.class);
42 extras.set(PushImage.class.getSimpleName(), PushImage.class);
45 extras.set(SaveImage.class.getSimpleName(), SaveImage.class);
43 extras.set(SaveImage.class.getSimpleName(), SaveImage.class);
44 extras.set(TagImage.class.getSimpleName(), TagImage.class);
46
45
47 project.getConfigurations().create(Dependency.DEFAULT_CONFIGURATION, c -> {
46 project.getConfigurations().create(Dependency.DEFAULT_CONFIGURATION, c -> {
48 c.setCanBeConsumed(true);
47 c.setCanBeConsumed(true);
@@ -67,13 +66,7 public class ContainerPlugin implements
67 t.getContextDirectory().set(containerExtension.getContextDirectory());
66 t.getContextDirectory().set(containerExtension.getContextDirectory());
68 t.getImageIdFile().set(containerExtension.getImageIdFile());
67 t.getImageIdFile().set(containerExtension.getImageIdFile());
69
68
70 Provider<String> imageName = containerExtension.getImageGroup().map(g -> g + "/" + project.getName())
69 t.getImageName().set(containerExtension.getImageName());
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"));
77 });
70 });
78
71
79 project.getTasks().register("clean", Delete.class, t -> {
72 project.getTasks().register("clean", Delete.class, t -> {
@@ -87,12 +80,12 public class ContainerPlugin implements
87
80
88 project.getTasks().register("pushImage", PushImage.class, t -> {
81 project.getTasks().register("pushImage", PushImage.class, t -> {
89 t.dependsOn(buildImageTask);
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 project.getTasks().register("saveImage", SaveImage.class, t -> {
86 project.getTasks().register("saveImage", SaveImage.class, t -> {
94 t.dependsOn(buildImageTask);
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 project.getArtifacts().add(Dependency.DEFAULT_CONFIGURATION, buildImageTask.flatMap(x -> x.getImageIdFile()), t -> {
91 project.getArtifacts().add(Dependency.DEFAULT_CONFIGURATION, buildImageTask.flatMap(x -> x.getImageIdFile()), t -> {
@@ -5,39 +5,20 import java.util.List;
5 import org.gradle.api.file.DirectoryProperty;
5 import org.gradle.api.file.DirectoryProperty;
6 import org.gradle.api.file.RegularFileProperty;
6 import org.gradle.api.file.RegularFileProperty;
7 import org.gradle.api.provider.Property;
7 import org.gradle.api.provider.Property;
8 import org.gradle.api.provider.Provider;
9 import org.gradle.api.tasks.Input;
8 import org.gradle.api.tasks.Input;
10 import org.gradle.api.tasks.InputDirectory;
9 import org.gradle.api.tasks.InputDirectory;
11 import org.gradle.api.tasks.Internal;
12 import org.gradle.api.tasks.OutputFile;
10 import org.gradle.api.tasks.OutputFile;
13 import org.gradle.api.tasks.SkipWhenEmpty;
11 import org.gradle.api.tasks.SkipWhenEmpty;
14 import org.implab.gradle.Utils;
12 import org.implab.gradle.Utils;
15 import org.implab.gradle.containers.ImageTag;
13 import org.implab.gradle.containers.ImageName;
16
14
17 public abstract class BuildImage extends CliTask {
15 public abstract class BuildImage extends CliTask {
18 @InputDirectory
16 @InputDirectory
19 @SkipWhenEmpty
17 @SkipWhenEmpty
20 public abstract DirectoryProperty getContextDirectory();
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 @Input
20 @Input
32 public Provider<ImageTag> getImageTag() {
21 public abstract Property<ImageName> getImageName();
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 }
41
22
42 @OutputFile
23 @OutputFile
43 public abstract RegularFileProperty getImageIdFile();
24 public abstract RegularFileProperty getImageIdFile();
@@ -52,7 +33,7 public abstract class BuildImage extends
52 super.preparingCommand(commandLine);
33 super.preparingCommand(commandLine);
53
34
54 commandLine.addAll(List.of("build", ".", "-q", "-t"));
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 @Override
39 @Override
@@ -5,20 +5,14 import java.util.concurrent.Callable;
5
5
6 import org.gradle.api.provider.ListProperty;
6 import org.gradle.api.provider.ListProperty;
7 import org.gradle.api.provider.Property;
7 import org.gradle.api.provider.Property;
8 import org.gradle.api.provider.Provider;
9 import org.gradle.api.tasks.Input;
8 import org.gradle.api.tasks.Input;
10 import org.gradle.api.tasks.Internal;
11 import org.gradle.api.tasks.Optional;
9 import org.gradle.api.tasks.Optional;
12 import org.implab.gradle.containers.ImageTag;
10 import org.implab.gradle.containers.ImageName;
13
11
14 public abstract class PushImage extends CliTask {
12 public abstract class PushImage extends CliTask {
15
13
16 @Input
14 @Input
17 public abstract Property<ImageTag> getSrcImage();
15 public abstract Property<ImageName> getImageName();
18
19 @Input
20 @Optional
21 public abstract Property<ImageTag> getDestImage();
22
16
23 @Input
17 @Input
24 @Optional
18 @Optional
@@ -33,19 +27,12 public abstract class PushImage extends
33 return this;
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 @Override
30 @Override
42 protected void preparingCommand(List<String> commandLine) {
31 protected void preparingCommand(List<String> commandLine) {
43 super.preparingCommand(commandLine);
32 super.preparingCommand(commandLine);
44
33
45 commandLine.add("push");
34 commandLine.add("push");
46 commandLine.addAll(getOptions().get());
35 commandLine.addAll(getOptions().get());
47 commandLine.add(getSrcImage().get().toString());
36 commandLine.add(getImageName().get().toString());
48 if (getDestination().isPresent())
49 commandLine.add(getDestination().get());
50 }
37 }
51 }
38 }
@@ -13,12 +13,12 import org.gradle.api.tasks.Internal;
13 import org.gradle.api.tasks.OutputFile;
13 import org.gradle.api.tasks.OutputFile;
14 import org.gradle.api.tasks.TaskExecutionException;
14 import org.gradle.api.tasks.TaskExecutionException;
15 import org.implab.gradle.Utils;
15 import org.implab.gradle.Utils;
16 import org.implab.gradle.containers.ImageTag;
16 import org.implab.gradle.containers.ImageName;
17
17
18 public abstract class SaveImage extends CliTask {
18 public abstract class SaveImage extends CliTask {
19
19
20 @Input
20 @Input
21 public abstract Property<ImageTag> getImage();
21 public abstract Property<ImageName> getImage();
22
22
23 @OutputFile
23 @OutputFile
24 public Provider<RegularFile> getArchiveFile() {
24 public Provider<RegularFile> getArchiveFile() {
@@ -5,7 +5,7
5 ```gradle
5 ```gradle
6
6
7 plugins {
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 container {
11 container {
@@ -81,3 +81,30 The task pushes the image to the remote
81
81
82 The copy task, it prepares the build context. Use it to customize
82 The copy task, it prepares the build context. Use it to customize
83 the build context.
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
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now