public List getActualInstructions()

in plugins/docker/base-image/src/main/java/co/elastic/gradle/dockerbase/DockerBaseImageBuildTask.java [110:197]


    public List<ContainerImageBuildInstruction> getActualInstructions() {
        BaseLockfile lockfile = getLockFile().get();
        List<ContainerImageBuildInstruction> instructions = getInputInstructions().get();

        if (lockfile.getImage() == null) {
            if (instructions.stream()
                    .anyMatch(each -> each instanceof From)) {
                throw new GradleException("Missing image in lockfile. Does the lockfile need to be regenerated?");
            }
        }

        final Architecture architecture = getArchitecture().get();
        Packages packages = lockfile.getPackages().get(architecture);
        if (packages == null) {
            throw new GradleException("The lockfile does not have any packages for " + architecture);
        }

        final Set<String> allPackages = instructions.stream()
                .filter(each -> each instanceof Install)
                .map(each -> (Install) each)
                .flatMap(each -> each.getPackages().stream())
                .collect(Collectors.toSet());

        return Stream.concat(
                instructions.stream()
                        .map(instruction -> {
                            if (instruction instanceof From from) {
                                if (lockfile.getImage() == null) {
                                    throw new GradleException("Missing image in lockfile, does it need to be regenerated?");
                                }
                                UnchangingContainerReference lockedImage = lockfile.getImage().get(Architecture.current());
                                if (from.getReference().get().contains("@")) {
                                    throw new IllegalStateException(
                                            "The sha should come from the lockfile and thus should " +
                                            "not be specified in the input instructions."
                                    );
                                }
                                if (!from.getReference().get().contains(lockedImage.getRepository()) ||
                                    !from.getReference().get().contains(lockedImage.getTag())
                                ) {
                                    throw new GradleException(
                                            "Can't find " + from.getReference().get() + " in the lockfile. " +
                                            "Does the lockfile need to be regenerated?\n" + lockedImage.getTag()
                                    );
                                }
                                return new From(
                                        getProviderFactory().provider(() -> String.format(
                                                "%s:%s@%s",
                                                lockedImage.getRepository(),
                                                lockedImage.getTag(),
                                                lockedImage.getDigest()
                                        ))
                                );
                            } else if (instruction instanceof Install install) {
                                final List<String> missingPackages = install.getPackages().stream()
                                        .filter(each -> packages.findByName(each).isEmpty())
                                        .toList();
                                if (!missingPackages.isEmpty()) {
                                    throw new GradleException(
                                            "Does the lockfile need to be regenerated? The following packages are missing from the lockfile:\n" +
                                            String.join(",", missingPackages)
                                    );
                                }
                                final OSDistribution distribution = getOSDistribution().get();
                                return new Install(
                                        install.getPackages().stream()
                                                .map(packages::findByName)
                                                .map(Optional::get)
                                                .map(each -> each.getPackageName(distribution))
                                                .toList()
                                );
                            } else {
                                return instruction;
                            }
                        }),
                Stream.of(
                        // Add an installation instruction for packages in the lockfile but not the DSL.
                        // These are the implicit packages from the base image, but we want to be sure they are at the
                        // same version as specified in the lockfile.
                        new Install(
                                packages.getPackages().stream()
                                        .filter(each -> !allPackages.contains(each.getName()))
                                        .map(each -> each.getPackageName(getOSDistribution().get()))
                                        .toList()
                        )
                )
        ).toList();
    }