|
|
@@ -0,0 +1,73 @@
|
|
|
+using GLib;
|
|
|
+
|
|
|
+namespace Spry.Cli {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Maintains a `compile_commands.json` in the application root for the
|
|
|
+ * Vala language server: meson emits the database as a build artifact in
|
|
|
+ * `builddir/`, and it is copied out to the root whenever a build
|
|
|
+ * happens (the initial build on `spry new`, and every `spry dev`
|
|
|
+ * build/rebuild). The copied file is generated state — gitignored and
|
|
|
+ * excluded from packaging.
|
|
|
+ */
|
|
|
+ public class CompileCommands : Object {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Runs the initial meson setup + build of a freshly scaffolded
|
|
|
+ * application (so the compile database exists) and copies the
|
|
|
+ * database to the project root. Failures are reported but do not
|
|
|
+ * fail scaffolding itself.
|
|
|
+ */
|
|
|
+ public static void build_initial(string app_dir, string? libdir) {
|
|
|
+ var launcher = new SubprocessLauncher(SubprocessFlags.NONE);
|
|
|
+ Tools.apply_env(launcher, libdir);
|
|
|
+ stdout.printf("[spry] Running initial build (for compile_commands.json)…\n");
|
|
|
+ if (!run_step(launcher, app_dir, { "meson", "setup", ".", "builddir" })
|
|
|
+ || !run_step(launcher, app_dir, { "ninja", "-C", "builddir" })) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ copy_from_builddir(app_dir);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static bool run_step(SubprocessLauncher launcher, string app_dir, string[] argv) {
|
|
|
+ try {
|
|
|
+ var previous = Environment.get_current_dir();
|
|
|
+ Environment.set_current_dir(app_dir);
|
|
|
+ var process = launcher.spawnv(argv);
|
|
|
+ Environment.set_current_dir(previous);
|
|
|
+ if (!process.wait_check()) {
|
|
|
+ stderr.printf("[spry] Initial build failed — compile_commands.json not generated\n");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Error e) {
|
|
|
+ stderr.printf("[spry] Initial build could not run: %s\n", e.message);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Copies `builddir/compile_commands.json` to the project root when
|
|
|
+ * it exists; a no-op otherwise (e.g. the build failed or produced
|
|
|
+ * none).
|
|
|
+ */
|
|
|
+ public static void copy_from_builddir(string app_dir) {
|
|
|
+ try {
|
|
|
+ var source = File.new_for_path(Path.build_filename(app_dir, "builddir", "compile_commands.json"));
|
|
|
+ if (!source.query_exists()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var destination = File.new_for_path(Path.build_filename(app_dir, "compile_commands.json"));
|
|
|
+ if (!destination.query_exists()
|
|
|
+ || source.query_info("time::modified", FileQueryInfoFlags.NONE).get_modification_date_time()
|
|
|
+ .difference(destination.query_info("time::modified", FileQueryInfoFlags.NONE).get_modification_date_time()) > 0) {
|
|
|
+ source.copy(destination, FileCopyFlags.OVERWRITE);
|
|
|
+ stdout.printf("[spry] compile_commands.json copied to the project root\n");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Error e) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|