private int run()

in dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java [448:971]


    private int run() throws Exception {
        if (!empty && !files.isEmpty() && sourceDir != null) {
            // cannot have both files and source dir at the same time
            printer().printErr("Cannot specify both file(s) and source-dir at the same time.");
            return 1;
        }

        // special if user type: camel run .
        if (sourceDir == null && (files != null && files.size() == 1 && ".".equals(files.get(0)))) {
            files.clear();
            File[] fs = new File(".").listFiles();
            if (fs != null) {
                for (File f : fs) {
                    // skip hidden files
                    if (f.isFile() && !f.isHidden()) {
                        files.add(f.getName());
                    }
                }
            }
        }

        if (!exportRun) {
            if (RuntimeType.quarkus == runtime) {
                return runQuarkus();
            } else if (RuntimeType.springBoot == runtime) {
                return runSpringBoot();
            }
        }

        File work = CommandLineHelper.getWorkDir();
        removeDir(work);
        if (!work.exists() && !work.mkdirs()) {
            printer().println("WARN: Failed to create working directory: " + work.getAbsolutePath());
        }

        Properties profileProperties = !empty ? loadProfileProperties() : null;
        configureLogging();
        if (openapi != null) {
            generateOpenApi();
        }

        // route code as option
        if (!empty && code != null) {
            // code may refer to an existing file
            String name = "CodeRoute";
            boolean file = false;
            File f = new File(code);
            if (f.isFile() && f.exists()) {
                // must be a java file
                boolean java = f.getName().endsWith(".java");
                if (!java) {
                    printer().printErr("Only java source files is accepted when using --code parameter");
                    return 1;
                }
                code = Files.readString(f.toPath());
                name = FileUtil.onlyName(f.getName());
                file = true;
            }
            // store code in temporary file
            String codeFile = loadFromCode(code, name, file);
            // use code as first file
            files.add(0, codeFile);
        }

        boolean autoDetectFiles = files.isEmpty() || RUN_JAVA_SH.equals(files.get(0));

        // if no specific file to run then try to auto-detect
        if (!empty && autoDetectFiles) {
            if (sourceDir != null) {
                // silent-run then auto-detect all initial files for source-dir
                String[] allFiles = new File(sourceDir).list();
                if (allFiles != null) {
                    for (String f : allFiles) {
                        files.add(sourceDir + File.separator + f);
                    }
                }
            } else {
                String routes
                        = profileProperties != null ? profileProperties.getProperty("camel.main.routesIncludePattern") : null;
                if (routes == null) {
                    if (!exportRun) {
                        String run = "run";
                        if (transformRun) {
                            run = "transform";
                        } else if (debugRun) {
                            run = "debug";
                        }
                        System.err
                                .println("Cannot " + run
                                         + " because application.properties file does not exist or camel.main.routesIncludePattern is not configured");
                        return 1;
                    } else {
                        // silent-run then auto-detect all files
                        String[] allFiles = new File(".").list();
                        if (allFiles != null) {
                            files.addAll(Arrays.asList(allFiles));
                        }
                    }
                }
            }
        }
        // filter out duplicate files
        if (!files.isEmpty()) {
            files = files.stream().distinct().collect(Collectors.toList());
        }

        final KameletMain main = createMainInstance();
        main.setProfile(profile);
        if (repositories != null && !repositories.isBlank()) {
            main.setRepositories(String.join(",", repositories));
        }
        main.setDownload(download);
        main.setPackageScanJars(packageScanJars);
        main.setFresh(fresh);
        main.setMavenSettings(mavenSettings);
        main.setMavenSettingsSecurity(mavenSettingsSecurity);
        main.setMavenCentralEnabled(mavenCentralEnabled);
        main.setMavenApacheSnapshotEnabled(mavenApacheSnapshotEnabled);
        main.setDownloadListener(new RunDownloadListener());
        main.setAppName("Apache Camel (JBang)");

        if (stub != null) {
            if ("all".equals(stub)) {
                stub = "*";
            }
            // we need to match by wildcard, to make it easier
            StringJoiner sj = new StringJoiner(",");
            for (String n : stub.split(",")) {
                // you can either refer to a name or a specific endpoint
                // if there is a colon then we assume its a specific endpoint then we should not add wildcard
                boolean colon = n.contains(":");
                if (!colon && !n.endsWith("*")) {
                    n = n + "*";
                }
                sj.add(n);
            }
            stub = sj.toString();
            writeSetting(main, profileProperties, "camel.jbang.stub", stub);
            main.setStubPattern(stub);
        }

        if (dev) {
            writeSetting(main, profileProperties, "camel.main.routesReloadEnabled", "true");
            // allow quick shutdown during development
            writeSetting(main, profileProperties, "camel.main.shutdownTimeout", "5");
        }
        if (sourceDir != null) {
            writeSetting(main, profileProperties, "camel.jbang.sourceDir", sourceDir);
        }
        if (trace) {
            writeSetting(main, profileProperties, "camel.main.tracing", "true");
        }
        if (modeline) {
            writeSetting(main, profileProperties, "camel.main.modeline", "true");
        }
        if (ignoreLoadingError) {
            writeSetting(main, profileProperties, "camel.jbang.ignoreLoadingError", "true");
        }
        if (lazyBean) {
            writeSetting(main, profileProperties, "camel.jbang.lazyBean", "true");
        }
        if (prompt) {
            writeSetting(main, profileProperties, "camel.jbang.prompt", "true");
        }
        writeSetting(main, profileProperties, "camel.jbang.compileWorkDir",
                CommandLineHelper.CAMEL_JBANG_WORK_DIR + File.separator + "compile");

        if (gav != null) {
            writeSetting(main, profileProperties, "camel.jbang.gav", gav);
        }
        writeSetting(main, profileProperties, "camel.jbang.open-api", openapi);
        if (repositories != null) {
            writeSetting(main, profileProperties, "camel.jbang.repos", String.join(",", repositories));
        }
        writeSetting(main, profileProperties, "camel.jbang.health", health ? "true" : "false");
        writeSetting(main, profileProperties, "camel.jbang.metrics", metrics ? "true" : "false");
        writeSetting(main, profileProperties, "camel.jbang.console", console ? "true" : "false");
        writeSetting(main, profileProperties, "camel.jbang.verbose", verbose ? "true" : "false");
        // the runtime version of Camel is what is loaded via the catalog
        writeSetting(main, profileProperties, "camel.jbang.camel-version", new DefaultCamelCatalog().getCatalogVersion());
        writeSetting(main, profileProperties, "camel.jbang.springBootVersion", springBootVersion);
        writeSetting(main, profileProperties, "camel.jbang.quarkusVersion", quarkusVersion);
        writeSetting(main, profileProperties, "camel.jbang.quarkusGroupId", quarkusGroupId);
        writeSetting(main, profileProperties, "camel.jbang.quarkusArtifactId", quarkusArtifactId);

        if (observe) {
            main.addInitialProperty("camel.jbang.dependencies", "camel:observability-services");
        }

        // command line arguments
        if (property != null) {
            for (String p : property) {
                String k = StringHelper.before(p, "=");
                String v = StringHelper.after(p, "=");
                if (k != null && v != null) {
                    main.addArgumentProperty(k, v);
                    writeSettings(k, v);
                }
            }
        }

        if (exportRun) {
            if (!verbose) {
                main.setSilent(true);
            }
            main.addInitialProperty("camel.jbang.export", "true");
            // enable stub in silent mode so we do not use real components
            main.setStubPattern("*");
            // do not run for very long in silent run
            main.addInitialProperty("camel.main.autoStartup", "false");
            main.addInitialProperty("camel.main.durationMaxSeconds", "1");
        } else if (debugRun) {
            main.addInitialProperty("camel.jbang.debug", "true");
        } else if (transformRun) {
            main.setSilent(true);
            // enable stub in silent mode so we do not use real components
            main.setStubPattern("*");
            // do not run for very long in silent run
            main.addInitialProperty("camel.main.autoStartup", "false");
            main.addInitialProperty("camel.main.durationMaxSeconds", "1");
        } else if (transformMessageRun) {
            // do not start any routes
            main.addInitialProperty("camel.main.autoStartup", "false");
        } else if (scriptRun) {
            // auto terminate if being idle
            main.addInitialProperty("camel.main.durationMaxIdleSeconds", "1");
        }
        // any custom initial property
        doAddInitialProperty(main);

        writeSetting(main, profileProperties, "camel.main.durationMaxMessages",
                () -> maxMessages > 0 ? String.valueOf(maxMessages) : null);
        writeSetting(main, profileProperties, "camel.main.durationMaxSeconds",
                () -> maxSeconds > 0 ? String.valueOf(maxSeconds) : null);
        writeSetting(main, profileProperties, "camel.main.durationMaxIdleSeconds",
                () -> maxIdleSeconds > 0 ? String.valueOf(maxIdleSeconds) : null);
        writeSetting(main, profileProperties, "camel.jbang.platform-http.port",
                () -> port > 0 && port != 8080 ? String.valueOf(port) : null);
        writeSetting(main, profileProperties, "camel.jbang.jfr", jfr || jfrProfile != null ? "jfr" : null); // TODO: "true" instead of "jfr" ?
        writeSetting(main, profileProperties, "camel.jbang.jfr-profile", jfrProfile != null ? jfrProfile : null);

        writeSetting(main, profileProperties, "camel.jbang.kameletsVersion", kameletsVersion);

        StringJoiner js = new StringJoiner(",");
        StringJoiner sjReload = new StringJoiner(",");
        StringJoiner sjClasspathFiles = new StringJoiner(",");
        StringJoiner sjScriptFiles = new StringJoiner(",");
        StringJoiner sjTlsFiles = new StringJoiner(",");
        StringJoiner sjKamelets = new StringJoiner(",");
        StringJoiner sjJKubeFiles = new StringJoiner(",");

        // include generated openapi to files to run
        if (openapi != null) {
            files.add(OPENAPI_GENERATED_FILE);
        }

        // if we only run pom.xml/build.gradle then auto discover from the Maven/Gradle based project
        if (files.size() == 1 && ("pom.xml".equals(files.get(0)) || "build.gradle".equals(files.get(0)))) {
            // use a better name when running
            if (name == null || "CamelJBang".equals(name)) {
                name = RunHelper.mavenArtifactId();
            }
            // find source files
            files = RunHelper.scanMavenOrGradleProject();
            // include extra dependencies from pom.xml
            var pomDependencies = RunHelper.scanMavenDependenciesFromPom();
            addDependencies(pomDependencies.toArray(new String[0]));
        }

        if (profile != null) {
            // need to include profile application properties if exists
            String name = "application-" + profile + ".properties";
            if (new File(name).exists() && !files.contains(name)) {
                files.add(name);
            }
        }

        for (String file : files) {
            if (file.startsWith("clipboard") && !(new File(file).exists())) {
                file = loadFromClipboard(file);
            } else if (skipFile(file)) {
                continue;
            } else if (isScriptFile(file)) {
                // script files
                sjScriptFiles.add(file);
                continue;
            } else if (isTlsFile(file)) {
                // tls files
                sjTlsFiles.add(file);
                continue;
            } else if (jkubeFile(file)) {
                // jkube
                sjJKubeFiles.add(file);
                continue;
            } else if (!knownFile(file) && !file.endsWith(".properties")) {
                // unknown files to be added on classpath
                sjClasspathFiles.add(file);
                continue;
            }

            // process known files as its likely DSLs or configuration files

            // check for properties files
            if (file.endsWith(".properties")) {
                if (acceptPropertiesFile(file)) {
                    if (!ResourceHelper.hasScheme(file) && !file.startsWith("github:")) {
                        file = "file:" + file;
                    }
                    if (ObjectHelper.isEmpty(propertiesFiles)) {
                        propertiesFiles = file;
                    } else {
                        propertiesFiles = propertiesFiles + "," + file;
                    }
                    if (dev && file.startsWith("file:")) {
                        // we can only reload if file based
                        sjReload.add(file.substring(5));
                    }
                }
                continue;
            }

            // Camel DSL files
            if (!ResourceHelper.hasScheme(file) && !file.startsWith("github:")) {
                file = "file:" + file;
            }
            if (file.startsWith("file:")) {
                // check if file exist
                File inputFile = new File(file.substring(5));
                if (!inputFile.exists() && !inputFile.isFile()) {
                    printer().printErr("File does not exist: " + file);
                    return 1;
                }
            }

            if (file.startsWith("file:") && file.endsWith(".kamelet.yaml")) {
                sjKamelets.add(file);
            }

            // automatic map github https urls to github resolver
            if (file.startsWith("https://github.com/")) {
                file = evalGithubSource(main, file);
                if (file == null) {
                    continue; // all mapped continue to next
                }
            } else if (file.startsWith("https://gist.github.com/")) {
                file = evalGistSource(main, file);
                if (file == null) {
                    continue; // all mapped continue to next
                }
            }

            if ("CamelJBang".equals(name)) {
                // no specific name was given so lets use the name from the first integration file
                // remove scheme and keep only the name (no path or ext)
                String s = StringHelper.after(file, ":");
                if (s.contains(":")) {
                    // its maybe a gist/github url so we need only the last part which has the name
                    s = StringHelper.afterLast(s, ":");
                }
                name = FileUtil.onlyName(s);
            }

            js.add(file);
            if (dev && file.startsWith("file:")) {
                // we can only reload if file based
                sjReload.add(file.substring(5));
            }
        }
        writeSetting(main, profileProperties, "camel.main.name", name);

        if (sourceDir != null) {
            // must be an existing directory
            File dir = new File(sourceDir);
            if (!dir.exists() && !dir.isDirectory()) {
                printer().printErr("Directory does not exist: " + sourceDir);
                return 1;
            }
            // make it a pattern as we load all files from this directory
            // (optional=true as there may be non Camel routes files as well)
            String sdir = "file:" + sourceDir + "/**?optional=true";
            main.addInitialProperty("camel.main.routesIncludePattern", sdir);
            writeSettings("camel.main.routesIncludePattern", sdir);
        } else if (js.length() > 0) {
            main.addInitialProperty("camel.main.routesIncludePattern", js.toString());
            writeSettings("camel.main.routesIncludePattern", js.toString());
        } else {
            writeSetting(main, profileProperties, "camel.main.routesIncludePattern", () -> null);
        }
        if (sjClasspathFiles.length() > 0) {
            main.addInitialProperty("camel.jbang.classpathFiles", sjClasspathFiles.toString());
            writeSettings("camel.jbang.classpathFiles", sjClasspathFiles.toString());
        } else {
            writeSetting(main, profileProperties, "camel.jbang.classpathFiles", () -> null);
        }
        if (sjScriptFiles.length() > 0) {
            main.addInitialProperty("camel.jbang.scriptFiles", sjScriptFiles.toString());
            writeSettings("camel.jbang.scriptFiles", sjScriptFiles.toString());
        } else {
            writeSetting(main, profileProperties, "camel.jbang.scriptFiles", () -> null);
        }
        if (sjTlsFiles.length() > 0) {
            main.addInitialProperty("camel.jbang.tlsFiles", sjTlsFiles.toString());
            writeSettings("camel.jbang.tlsFiles", sjTlsFiles.toString());
        } else {
            writeSetting(main, profileProperties, "camel.jbang.tlsFiles", () -> null);
        }
        if (sjJKubeFiles.length() > 0) {
            main.addInitialProperty("camel.jbang.jkubeFiles", sjJKubeFiles.toString());
            writeSettings("camel.jbang.jkubeFiles", sjJKubeFiles.toString());
        } else {
            writeSetting(main, profileProperties, "camel.jbang.jkubeFiles", () -> null);
        }

        if (sjKamelets.length() > 0) {
            String loc = main.getInitialProperties().getProperty("camel.component.kamelet.location");
            if (loc != null) {
                loc = loc + "," + sjKamelets;
            } else {
                loc = sjKamelets.toString();
            }
            main.addInitialProperty("camel.component.kamelet.location", loc);
            writeSettings("camel.component.kamelet.location", loc);
        } else {
            writeSetting(main, profileProperties, "camel.component.kamelet.location", () -> null);
        }

        // we can only reload if file based
        setupReload(main, sjReload);

        if (propertiesFiles != null) {
            String[] filesLocation = propertiesFiles.split(",");
            // sort so general application.properties comes first (we should load profile first)
            List<String> names = new ArrayList<>(List.of(filesLocation));
            names.sort((o1, o2) -> {
                // make sure application.properties is last
                if (o1.endsWith("application.properties")) {
                    return 1;
                } else if (o2.endsWith("application.properties")) {
                    return -1;
                }
                return 0;
            });
            StringBuilder locations = new StringBuilder();
            for (String file : names) {
                if (!file.startsWith("file:")) {
                    if (!file.startsWith("/")) {
                        file = FileSystems.getDefault().getPath("").toAbsolutePath() + File.separator + file;
                    }
                    file = "file://" + file;
                }
                if (!locations.isEmpty()) {
                    locations.append(",");
                }
                locations.append(file);
            }
            // there may be existing properties
            String loc = main.getInitialProperties().getProperty("camel.component.properties.location");
            if (loc != null) {
                loc = loc + "," + locations;
            } else {
                loc = locations.toString();
            }
            main.addInitialProperty("camel.component.properties.location", loc);
            writeSettings("camel.component.properties.location", loc);
            main.setPropertyPlaceholderLocations(loc);
        }

        // merge existing dependencies with --deps
        addDependencies(RuntimeUtil.getDependenciesAsArray(profileProperties));
        if (!dependencies.isEmpty()) {
            var joined = String.join(",", dependencies);
            main.addInitialProperty("camel.jbang.dependencies", joined);
            writeSettings("camel.jbang.dependencies", joined);
        }

        // if we have a specific camel version then make sure we really need to switch
        if (camelVersion != null) {
            CamelCatalog catalog = new DefaultCamelCatalog();
            String v = catalog.getCatalogVersion();
            if (camelVersion.equals(v)) {
                // same version, so we use current
                camelVersion = null;
            }
        }

        // okay we have validated all input and are ready to run
        // (if exporting then we cannot run a different version)
        if (!exportRun && camelVersion != null || isDebugMode()) {
            // TODO: debug camel specific version
            boolean custom = false;
            if (camelVersion != null) {
                // run in another JVM with different camel version (foreground or background)
                custom = camelVersion.contains("-") && !camelVersion.endsWith("-SNAPSHOT");
                if (custom) {
                    // regular camel versions can also be a milestone or release candidate
                    custom = !camelVersion.matches(".*-(RC|M)\\d$");
                }
            }
            if (custom) {
                // custom camel distribution
                return runCustomCamelVersion(main);
            } else {
                // apache camel distribution or remote debug enabled
                return runCamelVersion(main);
            }
        } else if (debugRun) {
            // spawn new JVM to debug in background
            return runDebug(main);
        } else if (background) {
            // spawn new JVM to run in background
            return runBackground(main);
        } else {
            // run default in current JVM with same camel version
            try {
                return runKameletMain(main);
            } catch (FailedToCreateRouteException ex) {
                if (ignoreLoadingError) {
                    printer().printErr(ex);
                    return 0;
                }
                throw ex;
            }
        }
    }