Commit e50f76c7 authored by Jan Tojnar's avatar Jan Tojnar
Browse files

makeHardcodeGsettingsPatch: Add support for `schemaExistsFunction`

evolution-ews introduced a check for optional schemas, which would skip our hardcoded code paths.
https://gitlab.gnome.org/GNOME/evolution-ews/-/commit/a0c514bd345c67fe0fd2ed6ef48a25649b1f4d8e

Let’s update the semantic patch to also replace the invocations of specified `schemaExistsFunction` for known schemas with `true`.
parent 5a60a1a9
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -27,6 +27,10 @@
    For example, `{ "org.gnome.evolution" = "EVOLUTION_SCHEMA_PATH"; }`
    hardcodes looking for `org.gnome.evolution` into `@EVOLUTION_SCHEMA_PATH@`.

  - `schemaExistsFunction`: name of the function that is used for checking
    if optional schema exists. Its invocation will be replaced with TRUE
    for known schemas.

  - `patches`: A list of patches to apply before generating the patch.

  Example:
@@ -54,6 +58,7 @@
  src,
  patches ? [ ],
  schemaIdToVariableMapping,
  schemaExistsFunction ? null,
}:

runCommand "hardcode-gsettings.patch"
@@ -71,6 +76,7 @@ runCommand "hardcode-gsettings.patch"
    patchPhase
    set -x
    cp ${builtins.toFile "glib-schema-to-var.json" (builtins.toJSON schemaIdToVariableMapping)} ./glib-schema-to-var.json
    cp ${builtins.toFile "glib-schema-exists-function.json" (builtins.toJSON schemaExistsFunction)} ./glib-schema-exists-function.json
    git init
    git add -A
    spatch --sp-file "${./hardcode-gsettings.cocci}" --dir . --in-place
+20 −0
Original line number Diff line number Diff line
@@ -34,6 +34,17 @@ def get_schema_directory(schema_id):
        return f'"@{schema_to_var[schema_id]}@"'
    raise Exception(f"Unknown schema path {schema_id!r}, please add it to ./glib-schema-to-var.json")


@script:python schema_exists_fn@
fn;
@@
import json

with open("./glib-schema-exists-function.json") as fn_file:
    if (fn := json.load(fn_file)):
        coccinelle.fn = fn


@find_cpp_constants@
identifier const_name;
expression val;
@@ -143,3 +154,12 @@ fresh identifier SCHEMA_DIRECTORY = script:python(SCHEMA_ID) { get_schema_direct
+   schema = g_settings_schema_source_lookup(schema_source, SCHEMA_ID, FALSE);
+   settings = g_settings_new_full(schema, NULL, PATH);
+}


@replace_schema_exists_fns depends on ever record_cpp_constants || never record_cpp_constants@
// We want to run after #define constants have been collected but even if there are no #defines.
expression SCHEMA_ID;
identifier schema_exists_fn.fn;
@@
-fn(SCHEMA_ID)
+true
+32 −11
Original line number Diff line number Diff line
@@ -13,14 +13,16 @@ let
      expected,
      src,
      patches ? [ ],
      schemaIdToVariableMapping,
      args,
    }:

    let
      patch = makeHardcodeGsettingsPatch ({
        inherit src schemaIdToVariableMapping;
        inherit patches;
      });
      patch = makeHardcodeGsettingsPatch (
        args
        // {
          inherit src patches;
        }
      );
    in
    runCommandLocal "makeHardcodeGsettingsPatch-tests-${name}"

@@ -54,11 +56,13 @@ in
  basic = mkTest {
    name = "basic";
    src = ./fixtures/example-project;
    args = {
      schemaIdToVariableMapping = {
        "org.gnome.evolution-data-server.addressbook" = "EDS";
        "org.gnome.evolution.calendar" = "EVO";
        "org.gnome.seahorse.nautilus.window" = "SEANAUT";
      };
    };
    expected = ./fixtures/example-project-patched;
  };

@@ -69,9 +73,26 @@ in
      # Avoid using wrapper function, which the generator cannot handle.
      ./fixtures/example-project-wrapped-settings-constructor-resolve.patch
    ];
    args = {
      schemaIdToVariableMapping = {
        "org.gnome.evolution-data-server.addressbook" = "EDS";
      };
    };
    expected = ./fixtures/example-project-wrapped-settings-constructor-patched;
  };

  existsFn = mkTest {
    name = "exists-fn";
    src = ./fixtures/example-project;
    args = {
      schemaIdToVariableMapping = {
        "org.gnome.evolution-data-server.addressbook" = "EDS";
        "org.gnome.evolution.calendar" = "EVO";
        "org.gnome.seahorse.nautilus.window" = "SEANAUT";
      };
      schemaExistsFunction = "e_ews_common_utils_gsettings_schema_exists";
    };
    expected = ./fixtures/example-project-patched-with-exists-fn;
  };

}
+129 −0
Original line number Diff line number Diff line
#include <gio/gio.h>
#include <glib-object.h>

void schema_id_literal() {
  GSettings *settings;
  {
    g_autoptr(GSettingsSchemaSource) schema_source;
    g_autoptr(GSettingsSchema) schema;
    schema_source = g_settings_schema_source_new_from_directory("@EDS@", g_settings_schema_source_get_default(), TRUE, NULL);
    schema = g_settings_schema_source_lookup(schema_source, "org.gnome.evolution-data-server.addressbook", FALSE);
    settings = g_settings_new_full(schema, NULL, NULL);
  }
  g_object_unref(settings);
}

#define SELF_UID_PATH_ID "org.gnome.evolution-data-server.addressbook"
int schema_id_from_constant() {
  GSettings *settings;
  {
    g_autoptr(GSettingsSchemaSource) schema_source;
    g_autoptr(GSettingsSchema) schema;
    schema_source = g_settings_schema_source_new_from_directory("@EDS@", g_settings_schema_source_get_default(), TRUE, NULL);
    schema = g_settings_schema_source_lookup(schema_source, SELF_UID_PATH_ID, FALSE);
    settings = g_settings_new_full(schema, NULL, NULL);
  }
  g_object_unref(settings);
}

void schema_id_autoptr() {
  g_autoptr(GSettings) settings = NULL;
  {
    g_autoptr(GSettingsSchemaSource) schema_source;
    g_autoptr(GSettingsSchema) schema;
    schema_source = g_settings_schema_source_new_from_directory("@EVO@", g_settings_schema_source_get_default(), TRUE, NULL);
    schema = g_settings_schema_source_lookup(schema_source, "org.gnome.evolution.calendar", FALSE);
    settings = g_settings_new_full(schema, NULL, NULL);
  }
}

void schema_id_with_backend() {
  GSettings *settings;
  {
    g_autoptr(GSettingsSchemaSource) schema_source;
    g_autoptr(GSettingsSchema) schema;
    schema_source = g_settings_schema_source_new_from_directory("@EDS@", g_settings_schema_source_get_default(), TRUE, NULL);
    schema = g_settings_schema_source_lookup(schema_source, "org.gnome.evolution-data-server.addressbook", FALSE);
    settings = g_settings_new_full(schema, g_settings_backend_get_default(), NULL);
  }
  g_object_unref(settings);
}

void schema_id_with_backend_and_path() {
  GSettings *settings;
  {
    g_autoptr(GSettingsSchemaSource) schema_source;
    g_autoptr(GSettingsSchema) schema;
    schema_source = g_settings_schema_source_new_from_directory("@SEANAUT@", g_settings_schema_source_get_default(), TRUE, NULL);
    schema = g_settings_schema_source_lookup(schema_source, "org.gnome.seahorse.nautilus.window", FALSE);
    settings = g_settings_new_full(schema, g_settings_backend_get_default(), "/org/gnome/seahorse/nautilus/windows/123/");
  }
  g_object_unref(settings);
}

void schema_id_with_path() {
  GSettings *settings;
  {
    g_autoptr(GSettingsSchemaSource) schema_source;
    g_autoptr(GSettingsSchema) schema;
    schema_source = g_settings_schema_source_new_from_directory("@SEANAUT@", g_settings_schema_source_get_default(), TRUE, NULL);
    schema = g_settings_schema_source_lookup(schema_source, "org.gnome.seahorse.nautilus.window", FALSE);
    settings = g_settings_new_full(schema, NULL, "/org/gnome/seahorse/nautilus/windows/123/");
  }
  g_object_unref(settings);
}

void exists_fn_guard() {
  if (!true) {
    return;
  }

  g_autoptr(GSettings) settings = NULL;
  {
    g_autoptr(GSettingsSchemaSource) schema_source;
    g_autoptr(GSettingsSchema) schema;
    schema_source = g_settings_schema_source_new_from_directory("@EVO@", g_settings_schema_source_get_default(), TRUE, NULL);
    schema = g_settings_schema_source_lookup(schema_source, "org.gnome.evolution.calendar", FALSE);
    settings = g_settings_new_full(schema, NULL, NULL);
  }
}

void exists_fn_nested() {
  if (true) {
    g_autoptr(GSettings) settings = NULL;
    {
      g_autoptr(GSettingsSchemaSource) schema_source;
      g_autoptr(GSettingsSchema) schema;
      schema_source = g_settings_schema_source_new_from_directory("@EVO@", g_settings_schema_source_get_default(), TRUE, NULL);
      schema = g_settings_schema_source_lookup(schema_source, "org.gnome.evolution.calendar", FALSE);
      settings = g_settings_new_full(schema, NULL, NULL);
    }
  }
}

void exists_fn_unknown() {
  if (true) {
    g_autoptr(GSettings) settings = NULL;
    {
      g_autoptr(GSettingsSchemaSource) schema_source;
      g_autoptr(GSettingsSchema) schema;
      schema_source = g_settings_schema_source_new_from_directory("@EVO@", g_settings_schema_source_get_default(), TRUE, NULL);
      schema = g_settings_schema_source_lookup(schema_source, "org.gnome.evolution.calendar", FALSE);
      settings = g_settings_new_full(schema, NULL, NULL);
    }
  }
}

int main() {
  schema_id_literal();
  schema_id_from_constant();
  schema_id_autoptr();
  schema_id_with_backend();
  schema_id_with_backend_and_path();
  schema_id_with_path();
  exists_fn_guard();
  exists_fn_nested();
  exists_fn_unknown();

  return 0;
}
+44 −0
Original line number Diff line number Diff line
@@ -73,6 +73,47 @@ void schema_id_with_path() {
  g_object_unref(settings);
}

void exists_fn_guard() {
  if (!e_ews_common_utils_gsettings_schema_exists("org.gnome.evolution.calendar")) {
    return;
  }

  g_autoptr(GSettings) settings = NULL;
  {
    g_autoptr(GSettingsSchemaSource) schema_source;
    g_autoptr(GSettingsSchema) schema;
    schema_source = g_settings_schema_source_new_from_directory("@EVO@", g_settings_schema_source_get_default(), TRUE, NULL);
    schema = g_settings_schema_source_lookup(schema_source, "org.gnome.evolution.calendar", FALSE);
    settings = g_settings_new_full(schema, NULL, NULL);
  }
}

void exists_fn_nested() {
  if (e_ews_common_utils_gsettings_schema_exists("org.gnome.evolution.calendar")) {
    g_autoptr(GSettings) settings = NULL;
    {
      g_autoptr(GSettingsSchemaSource) schema_source;
      g_autoptr(GSettingsSchema) schema;
      schema_source = g_settings_schema_source_new_from_directory("@EVO@", g_settings_schema_source_get_default(), TRUE, NULL);
      schema = g_settings_schema_source_lookup(schema_source, "org.gnome.evolution.calendar", FALSE);
      settings = g_settings_new_full(schema, NULL, NULL);
    }
  }
}

void exists_fn_unknown() {
  if (e_ews_common_utils_gsettings_schema_exists("org.gnome.foo")) {
    g_autoptr(GSettings) settings = NULL;
    {
      g_autoptr(GSettingsSchemaSource) schema_source;
      g_autoptr(GSettingsSchema) schema;
      schema_source = g_settings_schema_source_new_from_directory("@EVO@", g_settings_schema_source_get_default(), TRUE, NULL);
      schema = g_settings_schema_source_lookup(schema_source, "org.gnome.evolution.calendar", FALSE);
      settings = g_settings_new_full(schema, NULL, NULL);
    }
  }
}

int main() {
  schema_id_literal();
  schema_id_from_constant();
@@ -80,6 +121,9 @@ int main() {
  schema_id_with_backend();
  schema_id_with_backend_and_path();
  schema_id_with_path();
  exists_fn_guard();
  exists_fn_nested();
  exists_fn_unknown();

  return 0;
}
Loading