• Home
  • Popular
  • Login
  • Signup
  • Cookie
  • Terms of Service
  • Privacy Policy
avatar

Posted by User Bot


30 Nov, 2024

Updated at 14 Dec, 2024

Parse and format (sort) a docker-compose file

I want to read and reformat a docker-compose.yml file with Java. If possible, I would like to do without an external lib.

Requirements:

  • An empty line should be inserted after each service
  • The services should be sorted by service name
  • Services that have a profile should be inserted at the end
  • Repeated reformatting should produce the same result

Given:

  • A valid yaml file that always starts with services:

Example:

services:
  traefik:
    #...
  abe:
    #...
    profiles:
      #...
  ab:
    #...
  abc:
    #...
    profiles:
      #...
  ab-d:
    #...

should become:

services:

  traefik:
    #...

  ab:
    #...

  ab-d:
    #...

  abc:
    #...
    profiles:
      #...

  abe:
    #...
    profiles:
      #...

Have I overlooked something here or would simplifications be possible?

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.*;

public class Main {
    private static class Service extends AbstractList implements Comparable {
        private final ArrayList lines = new ArrayList<>();

        @Override
        public String get(int index) {
            return lines.get(index);
        }

        @Override
        public int size() {
            return lines.size();
        }

        @Override
        public boolean add(String s) {
            return lines.add(s);
        }

        @Override
        public String toString() {
            return String.join("\n", lines);
        }

        @Override
        public int compareTo(Service o) {
            boolean b1 = lines.contains("  traefik:");
            boolean b2 = o.lines.contains("  traefik:");
            if (b1 || b2) {
                return b1 ? b2 ? 0 : -1 : 1;
            }
            boolean b3 = lines.contains("    profiles:");
            boolean b4 = o.lines.contains("    profiles:");
            if (b3 ^ b4) {
                return b3 ? 1 : -1;
            }
            boolean b5 = lines.isEmpty();
            boolean b6 = o.lines.isEmpty();
            if (!b5 && !b6) {
                return get(0).replaceAll(":$", "").compareTo(o.get(0).replaceAll(":$", ""));
            }
            return b5 ? b6 ? 0 : -1 : 1;
        }
    }

    public static void main(String[] args) throws Exception {
        prettify(new File("test.yml"), new File("test_neu.yml"));
    }

    public static void prettify(File from, File to) throws Exception {
        TreeSet services = new TreeSet<>();
        try (BufferedReader br = new BufferedReader(new FileReader(from))) {
            Service current = new Service();
            String l;
            while ((l = br.readLine()) != null) {
                if (l.isBlank() || "services:".equals(l)) {
                    continue;
                }
                int c = l.length() - l.replace(" ", "").length();
                if (c == 2 && !current.isEmpty()) {
                    services.add(current);
                    current = new Service();
                }
                current.add(l);
            }
            services.add(current);
        }
        try (PrintWriter pw = new PrintWriter(to)) {
            pw.println("services:");
            pw.println();
            for (Service s : services) {
                pw.println(s);
                pw.println();
            }
        }
    }
}