class Options {

    static Result<URL> cacheRepoInits(final @NotNull File cacheDir, final @NotNull List<String> repoInits) {
        if (repoInits.isEmpty()) {
            return Result.failure("refusing to cache empty repoinit script");
        }
        final byte[] repoInitBytes = getRepoInitBytes(repoInits);
        final File parentDir = cacheDir.toPath().resolve("repoinits").toFile();
        parentDir.mkdirs();
        return fileNameForRepoInitBytes(repoInitBytes)
                .map(fileName -> new File(parentDir, fileName))
                .flatMap(cacheFile -> {
                    final Result<URL> cacheFileUrl = compose1(File::toURI, result1(URI::toURL)).apply(cacheFile);
                    if (cacheFile.exists()) {
                        return cacheFileUrl;
                    } else {
                        return writeToStream(repoInitBytes, () -> new FileOutputStream(cacheFile))
                                .flatMap(constantly1(() -> cacheFileUrl));
                    }
                });
    }

      Options();
      Options(final boolean justHelp,
            final boolean justVersion,
            final boolean storeBlobs,
            final @NotNull URL planUrl,
            final @NotNull ClassLoader scanClassLoader,
            final @NotNull File cacheDir,
            final @Nullable File opearFile,
            final @Nullable String planName,
            final @Nullable File planFile,
            final @Nullable File planFileBaseDir,
            final @NotNull List<File> preInstallFiles,
            final @NotNull List<File> repoInitFiles,
            final @NotNull List<String> runModes,
            final boolean noRunModes,
            final @NotNull List<File> extendedClassPathFiles,
            final boolean noHooks,
            final @NotNull List<File> scanFiles,
            final @NotNull Function<StructuredMessage, IO<Nothing>> printer,
            final @NotNull Severity failOnSeverity);

}