private void writeLockfile()

in plugins/docker/base-image/src/main/java/co/elastic/gradle/dockerbase/DockerLockfileTask.java [252:327]


    private void writeLockfile(ByteArrayOutputStream csvStream) throws IOException {
        final BaseLockfile oldLockfile;
        if (Files.exists(RegularFileUtils.toPath(getLockFileLocation()))) {
            oldLockfile = BaseLockfile.parse(Files.newBufferedReader(RegularFileUtils.toPath(getLockFileLocation())));
        } else {
            oldLockfile = new BaseLockfile(Map.of(), null);
        }
        final Map<Architecture, Packages> packages = new HashMap<>(oldLockfile.getPackages());
        Map<Architecture, UnchangingContainerReference> image;
        if (oldLockfile.getImage() != null) {
            image = new HashMap<>(oldLockfile.getImage());
        } else {
            image = null;
        }

        final String csvString = csvStream.toString().trim();
        if (csvString.isEmpty()) {
            throw new IllegalStateException("Failed to read installed packages from docker image");
        }
        try (Reader reader = new StringReader(csvString)) {
            CSVParser parser = CSVParser.parse(reader, CSVFormat.DEFAULT);
            packages.put(
                    getArchitecture().get(),
                    new Packages(
                            // Keep the latest version only. CentOS can keep multiple versions installed, e.g. kernel-core
                            Packages.getUniquePackagesWithMaxVersion(parser.getRecords().stream()
                                    .map(record -> {
                                        if (record.size() < 4) {
                                            throw new RuntimeException("CSV line from script not valid: " + record.get(0));
                                        }
                                        return new UnchangingPackage(
                                                record.get(0),
                                                record.get(1),
                                                record.get(2),
                                                record.get(3)
                                        );
                                    }).toList()
                            )
                    )
            );
        }

        Optional<UnchangingContainerReference> newImage = getActualInstructions().stream()
                .filter(each -> each instanceof From)
                .map(each -> (From) each)
                .map(each -> {
                    final String[] split = each.getReference().get().split(":", 2);
                    return new UnchangingContainerReference(
                            split[0],
                            // At this point the sha was added to the instructions because we are operating on the
                            // actual instructions
                            split[1].split("@", 2)[0],
                            getManifestDigest(each.getReference().get())
                    );
                })
                .findAny();

        if (newImage.isPresent()) {
            if (image == null) {
                image = new HashMap<>();
            }
            image.put(getArchitecture().get(), newImage.get());
        } else {
            image = null;
        }

        try (Writer writer = Files.newBufferedWriter(RegularFileUtils.toPath(getLockFileLocation()))) {
            BaseLockfile.write(
                    new BaseLockfile(
                            packages,
                            image
                    ),
                    writer
            );
        }
    }