public void apply()

in plugins/docker/base-image/src/main/java/co/elastic/gradle/dockerbase/DockerBaseImageBuildPlugin.java [70:254]


    public void apply(@NotNull Project target) {

        target.getPluginManager().apply(JFrogPlugin.class);

        final BaseImageExtension extension = target.getExtensions().create("dockerBaseImage", BaseImageExtension.class);

        final Map<Architecture, Configuration> osPackageConfigurations = Arrays.stream(Architecture.values())
                .collect(Collectors.toMap(
                        Function.identity(),
                        each -> target.getConfigurations().create("_osPackageRepo_" + each.dockerName())
                ));

        registerPullTask(target, extension);

        final Configuration dockerEphemeralConfiguration = target.getConfigurations().create("dockerEphemeral");

        Arrays.stream(Architecture.values()).forEach( arch -> {
            target.getTasks().register(
                    BUILD_TASK_NAME + dockerNameIfNotCurrent(arch),
                    DockerBaseImageBuildTask.class
            ).configure(task -> {
                        task.getArchitecture().set(arch);
                        task.getOSDistribution().set(extension.getOSDistribution());
                        task.getMirrorRepositories().set(extension.getMirrorRepositories());
                        task.getLockFile().set(extension.getLockFile());
                        task.getDockerEphemeralMount().set(extension.getDockerEphemeralMount());
                        task.getInputInstructions().set(extension.getInstructions());
                        task.getMaxOutputSizeMB().set(extension.getMaxOutputSizeMB());
                        task.getInputInstructions().set(
                                instructionsFilteredForArch(target, extension, arch)
                        );
                        task.onlyIf(runningOnSupportedArchitecture(extension));
                        task.getDockerEphemeralConfiguration().set(dockerEphemeralConfiguration);
                        task.getOSPackagesConfiguration().set(osPackageConfigurations.get(arch));
                        task.dependsOn(osPackageConfigurations.get(arch));
                    });
        });

        TaskProvider<DockerBaseImageBuildTask> dockerBaseImageBuild = target.getTasks()
                .withType(DockerBaseImageBuildTask.class)
                .named(BUILD_TASK_NAME);

        MultiArchLifecyclePlugin.assembleForPlatform(target, dockerBaseImageBuild);

        Arrays.stream(Architecture.values()).forEach( arch -> {
                    registerLocalImportTask(
                            target, arch,
                            extension,
                            target.getTasks()
                                    .withType(DockerBaseImageBuildTask.class)
                                    .named(BUILD_TASK_NAME + dockerNameIfNotCurrent(arch))
                    );
        });

        registerCleanTask(target, extension);

        registerPushTask(target, extension, dockerBaseImageBuild);

        Arrays.stream(Architecture.values()).forEach( arch -> {
                    target.getTasks().register(
                            LOCKFILE_TASK_NAME + dockerNameIfNotCurrent(arch),
                            DockerLockfileTask.class,
                            task -> {
                                task.getArchitecture().set(arch);
                                task.getInputInstructions().set(instructionsFilteredForArch(target, extension, arch));
                            }
                    );
                }
        );

        target.getTasks().register(LOCKFILE_TASK_NAME + "AllWithEmulation",  task -> {
            task.dependsOn(target.getTasks().withType(DockerLockfileTask.class));
        });

        target.getTasks().withType(DockerLockfileTask.class).configureEach(task -> {
                    task.setGroup("containers");
                    task.setDescription("Generates a new lockfile with the latest version of all packages");
                    task.getOSDistribution().set(extension.getOSDistribution());
                    task.getLockFileLocation().set(extension.getLockFileLocation());
                    task.getDockerEphemeralMount().set(extension.getDockerEphemeralMount());
                    task.getOsPackageRepository().set(extension.getOsPackageRepository());
                    task.getMirrorRepositories().set(extension.getMirrorRepositories());
                    task.getDockerEphemeralConfiguration().set(dockerEphemeralConfiguration);
                    // Map the configuration to the architecture of the task
                    task.getOSPackagesConfiguration().set(task.getArchitecture().map(osPackageConfigurations::get));
                    // hard code Linux here, because we are using it inside a docker container
                    task.getJFrogCli().set(JFrogPlugin.getExecutable(target, OS.LINUX));
                    task.onlyIf(runningOnSupportedArchitecture(extension));
                }
        );

        GradleUtils.registerOrGet(target, "dockerBuild").configure(task -> {
            task.dependsOn(dockerBaseImageBuild);
            task.setGroup("containers");
        });
        GradleUtils.registerOrGet(target, "dockerLocalImport").configure(task -> {
            task.dependsOn(target.getTasks().named("dockerBaseImageLocalImport"));
            task.setGroup("containers");
        });

        target.getGradle().getTaskGraph().whenReady(graph -> {
            final String separator = target.getPath().endsWith(":") ? "" : ":";
            final String lockfileTaskPath = target.getPath() + separator + LOCKFILE_TASK_NAME;
            final String buildTaskPath = target.getPath() + separator + BUILD_TASK_NAME;
            if (graph.hasTask(lockfileTaskPath) && graph.hasTask(buildTaskPath)
            ) {
                throw new GradleException("Generating the lockfile and building an image using it in the same invocation" +
                                          " is not supported. The lockfile should be generated and checked in. It can be " +
                                          "re-generated periodically to update dependencies, but doing at the same time" +
                                          "defeats the purpose of having a lockfile.");
            }
        });

        target.afterEvaluate(p -> {
            // Assign dependencies to local image builds in other projects
            extension.getInstructions().stream()
                    .filter(each -> each instanceof FromLocalImageBuild)
                    .map(each -> (FromLocalImageBuild) each)
                    .map(FromLocalImageBuild::otherProjectPath)
                    .forEach(otherProjectPath -> {
                        dockerBaseImageBuild.configure(task ->
                                task.dependsOn(otherProjectPath + ":" + LOCAL_IMPORT_TASK_NAME)
                        );
                        Arrays.stream(Architecture.values()).forEach( arch -> {
                            target.getTasks().withType(DockerLockfileTask.class)
                                    .named(LOCKFILE_TASK_NAME + dockerNameIfNotCurrent(arch)).configure(task -> {
                                task.dependsOn(otherProjectPath + ":" + LOCAL_IMPORT_TASK_NAME + dockerNameIfNotCurrent(arch));
                                // We don't force lock-files to be updated at the same time, but if they are, we need to order them for correct results
                                task.mustRunAfter(otherProjectPath + ":" + LOCKFILE_TASK_NAME + dockerNameIfNotCurrent(arch));
                            });
                        });
                    });

            // assign copy specs to the build tasks to correctly evaluate build avoidance
            dockerBaseImageBuild.configure(task ->
                    InstructionCopySpecMapper.assignCopySpecs(
                            extension.getInstructions(), ((ImageBuildable) task).getRootCopySpec()
                    )
            );
            target.getTasks().withType(DockerLockfileTask.class).configureEach(task ->
                    InstructionCopySpecMapper.assignCopySpecs(
                            extension.getInstructions(),
                            ((ImageBuildable) task).getRootCopySpec())
            );

            if (extension.getOsPackageRepository().isPresent()) {
                final URL repoUrl = extension.getOsPackageRepository().get();
                Action<? super PasswordCredentials> credentialsAction =
                        (repoUrl.getUserInfo() != null) ?
                                config -> {
                                    final String[] userinfo = repoUrl.getUserInfo().split(":");
                                    config.setUsername(userinfo[0]);
                                    config.setPassword(userinfo[1]);
                                } : null;

                target.getRepositories().ivy(repo -> {
                    osPackageConfigurations.values().stream()
                            .map(Configuration::getName)
                            .forEach(configurationName -> configureRepoForConfiguration(
                                    repoUrl, credentialsAction, repo, configurationName
                            ));
                });
            }

            final Path lockfilePath = RegularFileUtils.toPath(extension.getLockFileLocation());
            if (Files.exists(lockfilePath)) {
                try {
                    final BaseLockfile lockfile = BaseLockfile.parse(
                            Files.newBufferedReader(lockfilePath)
                    );
                    // Add all packages to a configuration to make verification data easier
                    final Map<Architecture, Packages> lockfilePackages = lockfile.getPackages();
                    for (Map.Entry<Architecture, Configuration> configuration : osPackageConfigurations.entrySet()) {
                        if (lockfilePackages.containsKey(configuration.getKey())) {
                            lockfilePackages.get(configuration.getKey()).getPackages()
                                    .stream()
                                    .forEach(pkg -> addPackageAsDependency(target, extension, configuration, pkg));
                        }
                    }
                } catch (IOException e) {
                    throw new UncheckedIOException(e);
                }
            }
        });
    }