Skip to content

Commit

Permalink
Add ModuleStreamV2.search_profiles()
Browse files Browse the repository at this point in the history
Signed-off-by: Stephen Gallagher <[email protected]>
  • Loading branch information
sgallagher committed Feb 12, 2020
1 parent 35ac116 commit f8029e0
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 0 deletions.
17 changes: 17 additions & 0 deletions modulemd/include/modulemd-2.0/modulemd-module-stream-v2.h
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,23 @@ modulemd_module_stream_v2_get_profile (ModulemdModuleStreamV2 *self,
const gchar *profile_name);


/**
* modulemd_module_stream_v2_search_profiles:
* @self: This #ModulemdModuleStreamV2 object.
* @profile_pattern: (nullable): A globbing pattern to locate one or more
* profiles in this #ModulemdModuleStreamV2 object. The names will be compared
* using [fnmatch(3)](https://www.mankier.com/3/fnmatch).
*
* Returns: (transfer container) (element-type ModulemdProfile): The list of
* #ModulemdProfile objects whose name matched @profile_pattern. This function
* cannot fail, but it may return a zero-length list if no matches were found.
* The returned profiles will be sorted alphabetically by profile name.
*/
GPtrArray *
modulemd_module_stream_v2_search_profiles (ModulemdModuleStreamV2 *self,
const gchar *profile_pattern);


/**
* modulemd_module_stream_v2_add_rpm_api:
* @self: (in): This #ModulemdModuleStreamV2 object.
Expand Down
46 changes: 46 additions & 0 deletions modulemd/modulemd-module-stream-v2.c
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,52 @@ modulemd_module_stream_v2_get_profile (ModulemdModuleStreamV2 *self,
}


struct profile_match_ctx
{
GHashTable *profiles;
GPtrArray *found;
const gchar *pattern;
};

static void
profile_match (gpointer data, gpointer user_data)
{
struct profile_match_ctx *match_ctx = (struct profile_match_ctx *)user_data;

/* Add it to the found list if it matches the pattern */
if (modulemd_fnmatch (match_ctx->pattern, (const gchar *)data))
{
g_ptr_array_add (match_ctx->found,
g_object_ref (g_hash_table_lookup (
match_ctx->profiles, (const gchar *)data)));
}
}

GPtrArray *
modulemd_module_stream_v2_search_profiles (ModulemdModuleStreamV2 *self,
const gchar *profile_pattern)
{
/* The list of profiles will probably never be large, so we'll optimize for
* the worst-case and preallocate the array to the number of profiles.
*/
GPtrArray *found =
g_ptr_array_new_full (g_hash_table_size (self->profiles), g_object_unref);

g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V2 (self), found);

g_autoptr (GPtrArray) profile_names =
modulemd_ordered_str_keys (self->profiles, modulemd_strcmp_sort);

struct profile_match_ctx match_ctx = { .profiles = self->profiles,
.found = found,
.pattern = profile_pattern };

g_ptr_array_foreach (profile_names, profile_match, &match_ctx);

return found;
}


void
modulemd_module_stream_v2_add_rpm_api (ModulemdModuleStreamV2 *self,
const gchar *rpm)
Expand Down
88 changes: 88 additions & 0 deletions modulemd/tests/ModulemdTests/modulestream.py
Original file line number Diff line number Diff line change
Expand Up @@ -1311,6 +1311,94 @@ def test_xmd_issue_290(self):
self.assertIsNotNone(output_yaml)
pass

def test_search_profiles(self):
stream = Modulemd.ModuleStreamV2.new("themodule", "thestream")

# First with no profiles added. Make sure we get back a zero-length
# array

profiles = stream.search_profiles(None)
self.assertIsNotNone(profiles)
self.assertEqual(len(profiles), 0)

profiles = stream.search_profiles("*")
self.assertIsNotNone(profiles)
self.assertEqual(len(profiles), 0)

profiles = stream.search_profiles("thefirstprofile")
self.assertIsNotNone(profiles)
self.assertEqual(len(profiles), 0)

# Now add three profiles, and confirm that searches are
# returned in alphabetical order
stream.add_profile(Modulemd.Profile.new("thesecondprofile"))
stream.add_profile(Modulemd.Profile.new("thefirstprofile"))
stream.add_profile(Modulemd.Profile.new("thethirdprofile"))

profiles = stream.search_profiles(None)
self.assertIsNotNone(profiles)
self.assertEqual(len(profiles), 3)
self.assertIsInstance(profiles[0], Modulemd.Profile)
self.assertEqual(profiles[0].get_name(), "thefirstprofile")
self.assertIsInstance(profiles[1], Modulemd.Profile)
self.assertEqual(profiles[1].get_name(), "thesecondprofile")
self.assertIsInstance(profiles[2], Modulemd.Profile)
self.assertEqual(profiles[2].get_name(), "thethirdprofile")

profiles = stream.search_profiles("*")
self.assertIsNotNone(profiles)
self.assertEqual(len(profiles), 3)
self.assertIsInstance(profiles[0], Modulemd.Profile)
self.assertEqual(profiles[0].get_name(), "thefirstprofile")
self.assertIsInstance(profiles[1], Modulemd.Profile)
self.assertEqual(profiles[1].get_name(), "thesecondprofile")
self.assertIsInstance(profiles[2], Modulemd.Profile)
self.assertEqual(profiles[2].get_name(), "thethirdprofile")

profiles = stream.search_profiles("thefirstprofile")
self.assertIsNotNone(profiles)
self.assertEqual(len(profiles), 1)
self.assertIsInstance(profiles[0], Modulemd.Profile)
self.assertEqual(profiles[0].get_name(), "thefirstprofile")

profiles = stream.search_profiles("*profile")
self.assertIsNotNone(profiles)
self.assertEqual(len(profiles), 3)
self.assertIsInstance(profiles[0], Modulemd.Profile)
self.assertEqual(profiles[0].get_name(), "thefirstprofile")
self.assertIsInstance(profiles[1], Modulemd.Profile)
self.assertEqual(profiles[1].get_name(), "thesecondprofile")
self.assertIsInstance(profiles[2], Modulemd.Profile)
self.assertEqual(profiles[2].get_name(), "thethirdprofile")

profiles = stream.search_profiles("*dprofile*")
self.assertIsNotNone(profiles)
self.assertEqual(len(profiles), 2)
self.assertIsInstance(profiles[0], Modulemd.Profile)
self.assertEqual(profiles[0].get_name(), "thesecondprofile")
self.assertIsInstance(profiles[1], Modulemd.Profile)
self.assertEqual(profiles[1].get_name(), "thethirdprofile")

profiles = stream.search_profiles("the*profile")
self.assertIsNotNone(profiles)
self.assertEqual(len(profiles), 3)
self.assertIsInstance(profiles[0], Modulemd.Profile)
self.assertEqual(profiles[0].get_name(), "thefirstprofile")
self.assertIsInstance(profiles[1], Modulemd.Profile)
self.assertEqual(profiles[1].get_name(), "thesecondprofile")
self.assertIsInstance(profiles[2], Modulemd.Profile)
self.assertEqual(profiles[2].get_name(), "thethirdprofile")

profiles = stream.search_profiles("the*")
self.assertIsNotNone(profiles)
self.assertEqual(len(profiles), 3)
self.assertIsInstance(profiles[0], Modulemd.Profile)
self.assertEqual(profiles[0].get_name(), "thefirstprofile")
self.assertIsInstance(profiles[1], Modulemd.Profile)
self.assertEqual(profiles[1].get_name(), "thesecondprofile")
self.assertIsInstance(profiles[2], Modulemd.Profile)
self.assertEqual(profiles[2].get_name(), "thethirdprofile")


if __name__ == "__main__":
unittest.main()

0 comments on commit f8029e0

Please sign in to comment.