From 665df159da5ebac553f7cd6973ba7ed2dde32072 Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Thu, 29 Aug 2019 08:33:38 -0400 Subject: [PATCH] Add helpers for reading compressed files Currently supports gzip, bzip2 and xz compression formats. Signed-off-by: Stephen Gallagher --- .travis/centos/Dockerfile.deps.tmpl | 2 + .travis/fedora/Dockerfile.deps.tmpl | 2 + .travis/mageia/Dockerfile.deps.tmpl | 2 + .travis/opensuse/Dockerfile.deps.tmpl | 2 + libmodulemd.spec.in | 2 + meson.build | 7 + meson_options.txt | 2 + .../modulemd-2.0/modulemd-compression.h | 69 +++ .../include/modulemd-2.0/modulemd-errors.h | 9 +- modulemd/include/modulemd-2.0/modulemd.h | 1 + .../private/modulemd-compression-private.h | 113 +++++ modulemd/meson.build | 9 + modulemd/modulemd-compression.c | 278 ++++++++++ modulemd/modulemd-docs.xml | 2 + modulemd/tests/test-modulemd-compression.c | 254 +++++++++ modulemd/tests/test_data/compression/bzipped | Bin 0 -> 2920 bytes .../test_data/compression/bzipped.yaml.bz2 | Bin 0 -> 2920 bytes modulemd/tests/test_data/compression/empty | 0 modulemd/tests/test_data/compression/gzipped | Bin 0 -> 2664 bytes .../test_data/compression/gzipped.yaml.gz | Bin 0 -> 2664 bytes .../tests/test_data/compression/uncompressed | 480 ++++++++++++++++++ .../test_data/compression/uncompressed.yaml | 480 ++++++++++++++++++ modulemd/tests/test_data/compression/xzipped | Bin 0 -> 2564 bytes .../test_data/compression/xzipped.yaml.xz | Bin 0 -> 2564 bytes 24 files changed, 1713 insertions(+), 1 deletion(-) create mode 100644 modulemd/include/modulemd-2.0/modulemd-compression.h create mode 100644 modulemd/include/private/modulemd-compression-private.h create mode 100644 modulemd/modulemd-compression.c create mode 100644 modulemd/tests/test-modulemd-compression.c create mode 100644 modulemd/tests/test_data/compression/bzipped create mode 100644 modulemd/tests/test_data/compression/bzipped.yaml.bz2 create mode 100644 modulemd/tests/test_data/compression/empty create mode 100644 modulemd/tests/test_data/compression/gzipped create mode 100644 modulemd/tests/test_data/compression/gzipped.yaml.gz create mode 100644 modulemd/tests/test_data/compression/uncompressed create mode 100644 modulemd/tests/test_data/compression/uncompressed.yaml create mode 100644 modulemd/tests/test_data/compression/xzipped create mode 100644 modulemd/tests/test_data/compression/xzipped.yaml.xz diff --git a/.travis/centos/Dockerfile.deps.tmpl b/.travis/centos/Dockerfile.deps.tmpl index d8fdd39ab..67001b026 100644 --- a/.travis/centos/Dockerfile.deps.tmpl +++ b/.travis/centos/Dockerfile.deps.tmpl @@ -9,6 +9,7 @@ RUN yum -y install epel-release \ clang \ createrepo_c \ elinks \ + file-devel \ gcc \ gcc-c++ \ git-core \ @@ -28,6 +29,7 @@ RUN yum -y install epel-release \ python3-rpm-macros \ redhat-rpm-config \ rpm-build \ + rpm-devel \ rpmdevtools \ sudo \ && yum -y clean all diff --git a/.travis/fedora/Dockerfile.deps.tmpl b/.travis/fedora/Dockerfile.deps.tmpl index 52f96955c..48efec7f9 100644 --- a/.travis/fedora/Dockerfile.deps.tmpl +++ b/.travis/fedora/Dockerfile.deps.tmpl @@ -11,6 +11,7 @@ RUN dnf -y --setopt=install_weak_deps=False --setopt=tsflags='' install \ "libmodulemd >= 2.3" \ curl \ elinks \ + file-devel \ gcc \ gcc-c++ \ git-core \ @@ -35,6 +36,7 @@ RUN dnf -y --setopt=install_weak_deps=False --setopt=tsflags='' install \ python3-rpm-macros \ redhat-rpm-config \ rpm-build \ + rpm-devel \ rpmdevtools \ ruby \ "rubygem(json)" \ diff --git a/.travis/mageia/Dockerfile.deps.tmpl b/.travis/mageia/Dockerfile.deps.tmpl index fcefcb061..4fd149617 100755 --- a/.travis/mageia/Dockerfile.deps.tmpl +++ b/.travis/mageia/Dockerfile.deps.tmpl @@ -10,6 +10,7 @@ RUN dnf -y --setopt=install_weak_deps=False --setopt=tsflags='' install \ createrepo_c \ curl \ elinks \ + file-devel \ gcc \ gcc-c++ \ git-core \ @@ -32,6 +33,7 @@ RUN dnf -y --setopt=install_weak_deps=False --setopt=tsflags='' install \ python3-rpm-macros \ rpm-mageia-setup-build \ rpm-build \ + rpm-devel \ rpmdevtools \ ruby \ "rubygem(json)" \ diff --git a/.travis/opensuse/Dockerfile.deps.tmpl b/.travis/opensuse/Dockerfile.deps.tmpl index f03c68e4e..5ba4b9e35 100644 --- a/.travis/opensuse/Dockerfile.deps.tmpl +++ b/.travis/opensuse/Dockerfile.deps.tmpl @@ -12,6 +12,7 @@ RUN zypper install --no-confirm --no-recommends \ clang-checker \ createrepo_c \ elinks \ + file-devel \ gcc \ gcc-c++ \ git-core \ @@ -32,6 +33,7 @@ RUN zypper install --no-confirm --no-recommends \ python3-pycodestyle \ python-rpm-macros \ rpm-build \ + rpm-devel \ rpmdevtools \ sudo \ valgrind \ diff --git a/libmodulemd.spec.in b/libmodulemd.spec.in index c76e6782a..22646d7d7 100644 --- a/libmodulemd.spec.in +++ b/libmodulemd.spec.in @@ -33,6 +33,8 @@ BuildRequires: python3-devel BuildRequires: python3-gobject-base BuildRequires: valgrind BuildRequires: glib2-doc +BuildRequires: rpm-devel +BuildRequires: file-devel # Patches diff --git a/meson.build b/meson.build index 113a7019a..fde31e29d 100644 --- a/meson.build +++ b/meson.build @@ -37,6 +37,7 @@ test_cflags = [ '-Werror=return-type', '-Werror=array-bounds', '-Werror=write-strings', + '-D_POSIX_SOURCE', '-DG_LOG_USE_STRUCTURED', '-DG_LOG_DOMAIN="libmodulemd"', ] @@ -53,6 +54,12 @@ gobject = dependency('gobject-2.0') yaml = dependency('yaml-0.1') gtkdoc = dependency('gtk-doc') +with_rpmio = get_option('rpmio') +with_libmagic = get_option('libmagic') + +rpm = dependency('rpm', required : with_rpmio) +magic = cc.find_library('magic', required : with_libmagic) + glib_prefix = dependency('glib-2.0').get_pkgconfig_variable('prefix') glib_docpath = join_paths(glib_prefix, 'share', 'gtk-doc', 'html') diff --git a/meson_options.txt b/meson_options.txt index c55392703..b8f2b7db2 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -16,3 +16,5 @@ option('skip_introspection', type : 'boolean', value : false) option('python_name', type : 'string') option('with_py2_overrides', type : 'boolean', value : true) option('with_py3_overrides', type : 'boolean', value : true) +option('rpmio', type : 'feature', value : 'enabled') +option('libmagic', type : 'feature', value : 'enabled') diff --git a/modulemd/include/modulemd-2.0/modulemd-compression.h b/modulemd/include/modulemd-2.0/modulemd-compression.h new file mode 100644 index 000000000..d4f026c4f --- /dev/null +++ b/modulemd/include/modulemd-2.0/modulemd-compression.h @@ -0,0 +1,69 @@ +/* + * This file is part of libmodulemd + * Copyright (C) 2019 Red Hat, Inc. + * + * Fedora-License-Identifier: MIT + * SPDX-2.0-License-Identifier: MIT + * SPDX-3.0-License-Identifier: MIT + * + * This program is free software. + * For more information on the license, see COPYING. + * For more information on free software, see . + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +/** + * SECTION: modulemd-compression + * @title: Modulemd Compression Helpers + * @stability: stable + * @short_description: Utility functions for working with compressed files. + */ + + +/** + * ModulemdCompressionTypeEnum: + * @MODULEMD_COMPRESSION_TYPE_DETECTION_FAILED: Autodetection failure + * @MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION: Unknown compression + * @MODULEMD_COMPRESSION_TYPE_NO_COMPRESSION: No compression + * @MODULEMD_COMPRESSION_TYPE_GZ_COMPRESSION: gzip compression + * @MODULEMD_COMPRESSION_TYPE_BZ2_COMPRESSION: bzip2 compression + * @MODULEMD_COMPRESSION_TYPE_XZ_COMPRESSION: LZMA compression + * @MODULEMD_COMPRESSION_TYPE_ZCK_COMPRESSION: zchunk compression + * @MODULEMD_COMPRESSION_TYPE_SENTINEL: Enum list terminator + * Since: 2.8 + */ +typedef enum +{ + MODULEMD_COMPRESSION_TYPE_DETECTION_FAILED = -2, + MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION, + MODULEMD_COMPRESSION_TYPE_NO_COMPRESSION, + MODULEMD_COMPRESSION_TYPE_GZ_COMPRESSION, + MODULEMD_COMPRESSION_TYPE_BZ2_COMPRESSION, + MODULEMD_COMPRESSION_TYPE_XZ_COMPRESSION, + MODULEMD_COMPRESSION_TYPE_ZCK_COMPRESSION, + MODULEMD_COMPRESSION_TYPE_SENTINEL, +} ModulemdCompressionTypeEnum; + + +/** + * modulemd_compression_type: + * @name: (in): The name of the compression type. Valid options are: + * "gz", "gzip", "bz2", "bzip2", "xz" and "zck". + * + * Returns: The #ModulemdCompressionTypeEnum value corresponding to the + * provided string if available or + * #MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION if the string does not match + * a known type. + * + * Since: 2.8 + */ +ModulemdCompressionTypeEnum +modulemd_compression_type (const gchar *name); + + +G_END_DECLS diff --git a/modulemd/include/modulemd-2.0/modulemd-errors.h b/modulemd/include/modulemd-2.0/modulemd-errors.h index 0e3aaac2d..dacd45249 100644 --- a/modulemd/include/modulemd-2.0/modulemd-errors.h +++ b/modulemd/include/modulemd-2.0/modulemd-errors.h @@ -38,6 +38,11 @@ G_BEGIN_DECLS * @MODULEMD_ERROR_TOO_MANY_MATCHES: Represents an error indicating that * multiple streams matched when searching for a specific module * stream. Since: 2.2 + * @MODULEMD_ERROR_MAGIC: Could not detect the mime type of a file for + * automatic detection of compression format. Since: 2.8 + * @MODULEMD_ERROR_NOT_IMPLEMENTED: The requested function is not implemented + * on this platform, likely due to needing a newer version of a dependency + * library. Since: 2.8 * * Since: 2.0 */ @@ -47,7 +52,9 @@ typedef enum MODULEMD_ERROR_VALIDATE, MODULEMD_ERROR_FILE_ACCESS, MODULEMD_ERROR_NO_MATCHES, - MODULEMD_ERROR_TOO_MANY_MATCHES + MODULEMD_ERROR_TOO_MANY_MATCHES, + MODULEMD_ERROR_MAGIC, + MODULEMD_ERROR_NOT_IMPLEMENTED } ModulemdErrorEnum; /** diff --git a/modulemd/include/modulemd-2.0/modulemd.h b/modulemd/include/modulemd-2.0/modulemd.h index e1f844b61..4cf816a91 100644 --- a/modulemd/include/modulemd-2.0/modulemd.h +++ b/modulemd/include/modulemd-2.0/modulemd.h @@ -17,6 +17,7 @@ #include "modulemd-component.h" #include "modulemd-component-module.h" #include "modulemd-component-rpm.h" +#include "modulemd-compression.h" #include "modulemd-defaults.h" #include "modulemd-defaults-v1.h" #include "modulemd-dependencies.h" diff --git a/modulemd/include/private/modulemd-compression-private.h b/modulemd/include/private/modulemd-compression-private.h new file mode 100644 index 000000000..ef6bdf651 --- /dev/null +++ b/modulemd/include/private/modulemd-compression-private.h @@ -0,0 +1,113 @@ +/* + * This file is part of libmodulemd + * Copyright (C) 2018 Red Hat, Inc. + * + * Fedora-License-Identifier: MIT + * SPDX-2.0-License-Identifier: MIT + * SPDX-3.0-License-Identifier: MIT + * + * This program is free software. + * For more information on the license, see COPYING. + * For more information on free software, see . + */ + +#pragma once + +#include + +#include "config.h" +#include "modulemd-compression.h" + +#ifdef HAVE_RPMIO +#include +#endif + +/** + * SECTION: modulemd-compression-private + * @title: Modulemd Compression Helpers (Private) + * @stability: Private + * @short_description: Internal utility functions for working with compressed + * files. + */ + + +#ifdef HAVE_RPMIO +/** + * mmd_Fclose: + * @fd: (in): A FD_t from rpmio.h to be closed + * + * Wrapper for rpmio's Fclose() function to use with + * #G_DEFINE_AUTO_CLEANUP_FREE_FUNC() + * + * Since: 2.8 + */ +void +mmd_Fclose (FD_t fd); + +G_DEFINE_AUTO_CLEANUP_FREE_FUNC (FD_t, mmd_Fclose, NULL); +#endif + + +/** + * modulemd_detect_compression: + * @filename: (in): The original filename that matches @fd. + * @fd: (in): An open file descriptor pointing at a real file. + * @error: (out): A #GError containing the reason this function failed. + * + * Returns: The #ModulemdCompressionTypeEnum detected from this file + * descriptor. In the event of an error, returns + * #MODULEMD_COMPRESSION_TYPE_DETECTION_FAILED and sets @error + * appropriately. Returns #MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION if + * all detection methods complete but the type is still indeterminate. + * + * Since: 2.8 + */ +ModulemdCompressionTypeEnum +modulemd_detect_compression (const gchar *filename, int fd, GError **error); + + +/** + * modulemd_compression_suffix: + * @comtype: (in): A #ModulemdCompressionTypeEnum. + * + * Returns: (transfer none): A static string representing the filename suffix + * that a file of this compression type should have. + * + * Since: 2.8 + */ +const gchar * +modulemd_compression_suffix (ModulemdCompressionTypeEnum comtype); + + +/** + * modulemd_get_rpmio_fmode: + * @mode: (in): A mode argument that will be passed to `fopen(3)`. + * @comtype: (in): A #ModulemdCompressionTypeEnum. + * + * Returns: (transfer full): A string suitable for passing to rpmio's + * `Fopen()` function. NULL if @mode is NULL or the @comtype is invalid. + * + * Since: 2.8 + */ +gchar * +modulemd_get_rpmio_fmode (const gchar *mode, + ModulemdCompressionTypeEnum comtype); + + +/** + * compressed_stream_read_fn: + * @data: (inout): A private pointer to the data being read. + * @buffer: (out): The buffer to write the data from the source. + * @size: (in): The size of the buffer. + * @size_read: (out): The actual number of bytes read from the source. + * + * A #ModulemdReadHandler that uses rpmio's `Fread()` function to handle + * compressed files. + * + * Since: 2.8 + */ +gint +compressed_stream_read_fn (void *data, + unsigned char *buffer, + size_t size, + size_t *size_read); diff --git a/modulemd/meson.build b/modulemd/meson.build index 67b792ffa..5a0ba1cca 100644 --- a/modulemd/meson.build +++ b/modulemd/meson.build @@ -57,6 +57,7 @@ modulemd_srcs = files( 'modulemd-component.c', 'modulemd-component-module.c', 'modulemd-component-rpm.c', + 'modulemd-compression.c', 'modulemd-defaults.c', 'modulemd-defaults-v1.c', 'modulemd-dependencies.c', @@ -86,6 +87,7 @@ modulemd_hdrs = files( 'include/modulemd-2.0/modulemd-component.h', 'include/modulemd-2.0/modulemd-component-module.h', 'include/modulemd-2.0/modulemd-component-rpm.h', + 'include/modulemd-2.0/modulemd-compression.h', 'include/modulemd-2.0/modulemd-defaults.h', 'include/modulemd-2.0/modulemd-defaults-v1.h', 'include/modulemd-2.0/modulemd-dependencies.h', @@ -111,6 +113,7 @@ modulemd_priv_hdrs = files( 'include/private/modulemd-component-private.h', 'include/private/modulemd-component-module-private.h', 'include/private/modulemd-component-rpm-private.h', + 'include/private/modulemd-compression-private.h', 'include/private/modulemd-dependencies-private.h', 'include/private/modulemd-profile-private.h', 'include/private/modulemd-defaults-private.h', @@ -133,6 +136,7 @@ test_srcs = files( 'tests/test-modulemd-buildopts.c', 'tests/test-modulemd-component-module.c', 'tests/test-modulemd-component-rpm.c', + 'tests/test-modulemd-compression.c', 'tests/test-modulemd-defaults.c', 'tests/test-modulemd-defaults-v1.c', 'tests/test-modulemd-dependencies.c', @@ -180,6 +184,8 @@ enums = gnome.mkenums_simple ('modulemd-enums', sources : modulemd_hdrs) cdata = configuration_data() cdata.set_quoted('LIBMODULEMD_VERSION', libmodulemd_version) +cdata.set('HAVE_RPMIO', rpm.found()) +cdata.set('HAVE_LIBMAGIC', magic.found()) configure_file( output : 'config.h', configuration : cdata @@ -191,6 +197,8 @@ modulemd_lib = library( include_directories : include_dirs, dependencies : [ gobject, + magic, + rpm, yaml, build_lib, ], @@ -298,6 +306,7 @@ c_tests = { 'buildopts' : [ 'tests/test-modulemd-buildopts.c' ], 'component_module' : [ 'tests/test-modulemd-component-module.c' ], 'component_rpm' : [ 'tests/test-modulemd-component-rpm.c' ], +'compression' : [ 'tests/test-modulemd-compression.c' ], 'defaults' : [ 'tests/test-modulemd-defaults.c' ], 'defaultsv1' : [ 'tests/test-modulemd-defaults-v1.c' ], 'dependencies' : [ 'tests/test-modulemd-dependencies.c' ], diff --git a/modulemd/modulemd-compression.c b/modulemd/modulemd-compression.c new file mode 100644 index 000000000..9047b7128 --- /dev/null +++ b/modulemd/modulemd-compression.c @@ -0,0 +1,278 @@ +/* + * This file is part of libmodulemd + * Copyright (C) 2019 Red Hat, Inc. + * + * Fedora-License-Identifier: MIT + * SPDX-2.0-License-Identifier: MIT + * SPDX-3.0-License-Identifier: MIT + * + * This program is free software. + * For more information on the license, see COPYING. + * For more information on free software, see . + */ + +#include +#include +#include +#include + + +#ifdef HAVE_RPMIO +#include +#endif + +#include "modulemd-compression.h" +#include "modulemd-errors.h" + +#include "private/modulemd-util.h" +#include "private/modulemd-compression-private.h" + +#ifdef HAVE_LIBMAGIC +#include +G_DEFINE_AUTO_CLEANUP_FREE_FUNC (magic_t, magic_close, NULL) +#endif + + +ModulemdCompressionTypeEnum +modulemd_detect_compression (const gchar *filename, int fd, GError **error) +{ + ModulemdCompressionTypeEnum type = + MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION; + + g_return_val_if_fail (filename, MODULEMD_COMPRESSION_TYPE_DETECTION_FAILED); + g_return_val_if_fail (!error || *error == NULL, + MODULEMD_COMPRESSION_TYPE_DETECTION_FAILED); + + if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) + { + g_set_error (error, + MODULEMD_ERROR, + MODULEMD_ERROR_FILE_ACCESS, + "File %s does not exist or is not a regular file", + filename); + return MODULEMD_COMPRESSION_TYPE_DETECTION_FAILED; + } + + + /* If the filename has a known suffix, assume it is accurate */ + if (g_str_has_suffix (filename, ".gz") || + g_str_has_suffix (filename, ".gzip") || + g_str_has_suffix (filename, ".gunzip")) + { + return MODULEMD_COMPRESSION_TYPE_GZ_COMPRESSION; + } + else if (g_str_has_suffix (filename, ".bz2") || + g_str_has_suffix (filename, ".bzip2")) + { + return MODULEMD_COMPRESSION_TYPE_BZ2_COMPRESSION; + } + else if (g_str_has_suffix (filename, ".xz")) + { + return MODULEMD_COMPRESSION_TYPE_XZ_COMPRESSION; + } + else if (g_str_has_suffix (filename, ".yaml") || + g_str_has_suffix (filename, ".yml") || + g_str_has_suffix (filename, ".txt")) + { + return MODULEMD_COMPRESSION_TYPE_NO_COMPRESSION; + } + +#ifdef HAVE_LIBMAGIC + /* No known suffix? Try using libmagic from file-utils */ + const char *mime_type; + g_auto (magic_t) magic = NULL; + int magic_fd = dup (fd); + + magic = magic_open (MAGIC_MIME); + if (magic == NULL) + { + g_set_error (error, + MODULEMD_ERROR, + MODULEMD_ERROR_MAGIC, + "magic_open() failed: Cannot allocate the magic cookie"); + return MODULEMD_COMPRESSION_TYPE_DETECTION_FAILED; + } + + if (magic_load (magic, NULL) == -1) + { + g_set_error (error, + MODULEMD_ERROR, + MODULEMD_ERROR_MAGIC, + "magic_load() failed: %s", + magic_error (magic)); + return MODULEMD_COMPRESSION_TYPE_DETECTION_FAILED; + } + + mime_type = magic_descriptor (magic, magic_fd); + close (magic_fd); + /* Reset the file descriptor to the start of the file, if it has moved */ + lseek (fd, 0, SEEK_SET); + + if (mime_type) + { + g_debug ( + "%s: Detected mime type: %s (%s)", __func__, mime_type, filename); + + if (g_str_has_prefix (mime_type, "application/x-gzip") || + g_str_has_prefix (mime_type, "application/gzip") || + g_str_has_prefix (mime_type, "application/gzip-compressed") || + g_str_has_prefix (mime_type, "application/gzipped") || + g_str_has_prefix (mime_type, "application/x-gzip-compressed") || + g_str_has_prefix (mime_type, "application/x-compress") || + g_str_has_prefix (mime_type, "application/x-gzip") || + g_str_has_prefix (mime_type, "application/x-gunzip") || + g_str_has_prefix (mime_type, "multipart/x-gzip")) + { + type = MODULEMD_COMPRESSION_TYPE_GZ_COMPRESSION; + } + + else if (g_str_has_prefix (mime_type, "application/x-bzip2") || + g_str_has_prefix (mime_type, "application/x-bz2") || + g_str_has_prefix (mime_type, "application/bzip2") || + g_str_has_prefix (mime_type, "application/bz2")) + { + type = MODULEMD_COMPRESSION_TYPE_BZ2_COMPRESSION; + } + + else if (g_str_has_prefix (mime_type, "application/x-xz")) + { + type = MODULEMD_COMPRESSION_TYPE_XZ_COMPRESSION; + } + + else if (g_str_has_prefix (mime_type, "text/plain") || + g_str_has_prefix (mime_type, "text/x-yaml") || + g_str_has_prefix (mime_type, "application/x-yaml")) + { + type = MODULEMD_COMPRESSION_TYPE_NO_COMPRESSION; + } + } + else + { + g_set_error (error, + MODULEMD_ERROR, + MODULEMD_ERROR_MAGIC, + "mime_type() detection failed: %s", + magic_error (magic)); + return MODULEMD_COMPRESSION_TYPE_DETECTION_FAILED; + } +#endif /* HAVE_LIBMAGIC */ + + return type; +} + +ModulemdCompressionTypeEnum +modulemd_compression_type (const gchar *name) +{ + if (!name) + return MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION; + + int type = MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION; + + if (!g_strcmp0 (name, "gz") || !g_strcmp0 (name, "gzip") || + !g_strcmp0 (name, "gunzip")) + type = MODULEMD_COMPRESSION_TYPE_GZ_COMPRESSION; + if (!g_strcmp0 (name, "bz2") || !g_strcmp0 (name, "bzip2")) + type = MODULEMD_COMPRESSION_TYPE_BZ2_COMPRESSION; + if (!g_strcmp0 (name, "xz")) + type = MODULEMD_COMPRESSION_TYPE_XZ_COMPRESSION; + if (!g_strcmp0 (name, "zck")) + type = MODULEMD_COMPRESSION_TYPE_ZCK_COMPRESSION; + + return type; +} + +const gchar * +modulemd_compression_suffix (ModulemdCompressionTypeEnum comtype) +{ + switch (comtype) + { + case MODULEMD_COMPRESSION_TYPE_GZ_COMPRESSION: return ".gz"; + case MODULEMD_COMPRESSION_TYPE_BZ2_COMPRESSION: return ".bz2"; + case MODULEMD_COMPRESSION_TYPE_XZ_COMPRESSION: return ".xz"; + default: return NULL; + } +} + + +static const gchar * +get_comtype_string (ModulemdCompressionTypeEnum comtype) +{ + /* see rpmio/rpmio.c in the RPM sources for the origin of these + * magic strings. + */ + switch (comtype) + { + case MODULEMD_COMPRESSION_TYPE_NO_COMPRESSION: return "fdio"; break; + + case MODULEMD_COMPRESSION_TYPE_GZ_COMPRESSION: return "gzdio"; break; + + case MODULEMD_COMPRESSION_TYPE_BZ2_COMPRESSION: return "bzdio"; break; + + case MODULEMD_COMPRESSION_TYPE_XZ_COMPRESSION: return "xzdio"; break; + + default: + g_info ("Unknown compression type: %d", comtype); + return NULL; + break; + } +} + + +gchar * +modulemd_get_rpmio_fmode (const gchar *mode, + ModulemdCompressionTypeEnum comtype) +{ + const gchar *type_string; + + if (!mode) + return NULL; + + type_string = get_comtype_string (comtype); + + if (type_string == NULL) + return NULL; + + return g_strdup_printf ("%s.%s", mode, type_string); +} + + +#ifdef HAVE_RPMIO +gint +compressed_stream_read_fn (void *data, + unsigned char *buffer, + size_t size, + size_t *size_read) +{ + FD_t rpmio_fd = (FD_t)data; + + *size_read = Fread (buffer, sizeof (*buffer), size, rpmio_fd); + + if (size_read < 0) + { + g_warning ("Got error [%d] reading the file", Ferror (rpmio_fd)); + return 0; + } + + return 1; +} +#else +gint +compressed_stream_read_fn (void *data, + unsigned char *buffer, + size_t size, + size_t *size_read) +{ + /* Not implemented without librpm available */ + return 0; +} +#endif + + +#ifdef HAVE_RPMIO +void +mmd_Fclose (FD_t fd) +{ + Fclose (fd); +} + +#endif diff --git a/modulemd/modulemd-docs.xml b/modulemd/modulemd-docs.xml index 23c832f64..6b15b8fab 100644 --- a/modulemd/modulemd-docs.xml +++ b/modulemd/modulemd-docs.xml @@ -40,6 +40,7 @@ + @@ -63,6 +64,7 @@ + diff --git a/modulemd/tests/test-modulemd-compression.c b/modulemd/tests/test-modulemd-compression.c new file mode 100644 index 000000000..c72ff77f4 --- /dev/null +++ b/modulemd/tests/test-modulemd-compression.c @@ -0,0 +1,254 @@ +/* + * This file is part of libmodulemd + * Copyright (C) 2018 Red Hat, Inc. + * + * Fedora-License-Identifier: MIT + * SPDX-2.0-License-Identifier: MIT + * SPDX-3.0-License-Identifier: MIT + * + * This program is free software. + * For more information on the license, see COPYING. + * For more information on free software, see . + */ + +#include +#include + +#include "modulemd-compression.h" +#include "private/modulemd-compression-private.h" +#include "private/test-utils.h" +#include "private/modulemd-yaml.h" + + +/* == Public Functions == */ +static void +test_modulemd_compression_type (void) +{ + g_assert_cmpint (modulemd_compression_type ("gz"), + ==, + MODULEMD_COMPRESSION_TYPE_GZ_COMPRESSION); + + + g_assert_cmpint (modulemd_compression_type ("gzip"), + ==, + MODULEMD_COMPRESSION_TYPE_GZ_COMPRESSION); + + g_assert_cmpint (modulemd_compression_type ("bz2"), + ==, + MODULEMD_COMPRESSION_TYPE_BZ2_COMPRESSION); + + g_assert_cmpint (modulemd_compression_type ("bzip2"), + ==, + MODULEMD_COMPRESSION_TYPE_BZ2_COMPRESSION); + + g_assert_cmpint (modulemd_compression_type ("xz"), + ==, + MODULEMD_COMPRESSION_TYPE_XZ_COMPRESSION); + + g_assert_cmpint (modulemd_compression_type ("garbage"), + ==, + MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION); + + g_assert_cmpint (modulemd_compression_type (NULL), + ==, + MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION); +} + + +struct expected_compression_t +{ + const char *filename; + ModulemdCompressionTypeEnum type; +}; + +/* == Private Functions == */ +static void +test_modulemd_detect_compression (void) +{ + int fd; + g_autofree gchar *filename = NULL; + g_autoptr (FILE) filestream = NULL; + g_autoptr (GError) error = NULL; + + struct expected_compression_t expected[] = { + { .filename = "bzipped.yaml.bz2", + .type = MODULEMD_COMPRESSION_TYPE_BZ2_COMPRESSION }, + { .filename = "gzipped.yaml.gz", + .type = MODULEMD_COMPRESSION_TYPE_GZ_COMPRESSION }, + { .filename = "xzipped.yaml.xz", + .type = MODULEMD_COMPRESSION_TYPE_XZ_COMPRESSION }, + { .filename = "uncompressed.yaml", + .type = MODULEMD_COMPRESSION_TYPE_NO_COMPRESSION }, + { .filename = "empty", + .type = MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION }, + { .filename = NULL } + }; + + /* == Detect by file extension == */ + for (size_t i = 0; expected[i].filename; i++) + { + filename = g_strdup_printf ("%s/compression/%s", + g_getenv ("TEST_DATA_PATH"), + expected[i].filename); + g_debug ("Getting compression type for %s", filename); + filestream = g_fopen (filename, "rb"); + g_assert_nonnull (filestream); + fd = fileno (filestream); + g_assert_cmpint (modulemd_detect_compression (filename, fd, &error), + ==, + expected[i].type); + g_assert_no_error (error); + g_clear_error (&error); + g_clear_pointer (&filestream, fclose); + g_clear_pointer (&filename, g_free); + } + + + /* == Test detection by libmagic == */ +#ifdef HAVE_LIBMAGIC + struct expected_compression_t expected_magic[] = { + { .filename = "bzipped", + .type = MODULEMD_COMPRESSION_TYPE_BZ2_COMPRESSION }, + { .filename = "gzipped", + .type = MODULEMD_COMPRESSION_TYPE_GZ_COMPRESSION }, + { .filename = "xzipped", + .type = MODULEMD_COMPRESSION_TYPE_XZ_COMPRESSION }, + { .filename = "uncompressed", + .type = MODULEMD_COMPRESSION_TYPE_NO_COMPRESSION }, + { .filename = "empty", + .type = MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION }, + { .filename = NULL } + }; +#else + struct expected_compression_t expected_magic[] = { + { .filename = "bzipped", + .type = MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION }, + { .filename = "gzipped", + .type = MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION }, + { .filename = "xzipped", + .type = MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION }, + { .filename = "uncompressed", + .type = MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION }, + { .filename = "empty", + .type = MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION }, + { .filename = NULL } + }; +#endif + + for (size_t j = 0; expected_magic[j].filename; j++) + { + filename = g_strdup_printf ("%s/compression/%s", + g_getenv ("TEST_DATA_PATH"), + expected_magic[j].filename); + filestream = g_fopen (filename, "rb"); + g_assert_nonnull (filestream); + fd = fileno (filestream); + g_assert_cmpint (modulemd_detect_compression (filename, fd, &error), + ==, + expected_magic[j].type); + g_assert_no_error (error); + g_clear_error (&error); + g_clear_pointer (&filestream, fclose); + g_clear_pointer (&filename, g_free); + } +} + + +struct expected_suffix_t +{ + ModulemdCompressionTypeEnum type; + const char *suffix; +}; + +static void +test_modulemd_compression_suffix (void) +{ + struct expected_suffix_t expected[] = { + { .type = MODULEMD_COMPRESSION_TYPE_DETECTION_FAILED, .suffix = NULL }, + { .type = MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION, .suffix = NULL }, + { .type = MODULEMD_COMPRESSION_TYPE_NO_COMPRESSION, .suffix = NULL }, + { .type = MODULEMD_COMPRESSION_TYPE_GZ_COMPRESSION, .suffix = ".gz" }, + { .type = MODULEMD_COMPRESSION_TYPE_BZ2_COMPRESSION, .suffix = ".bz2" }, + { .type = MODULEMD_COMPRESSION_TYPE_XZ_COMPRESSION, .suffix = ".xz" }, + { .type = MODULEMD_COMPRESSION_TYPE_SENTINEL, .suffix = NULL } + }; + + for (size_t i = 0; expected[i].type != MODULEMD_COMPRESSION_TYPE_SENTINEL; + i++) + { + g_assert_cmpstr (modulemd_compression_suffix (expected[i].type), + ==, + expected[i].suffix); + } +} + + +struct expected_fmode_t +{ + ModulemdCompressionTypeEnum type; + const gchar *suffix; +}; + +static void +test_modulemd_get_rpmio_fmode (void) +{ + struct expected_fmode_t expected[] = { + { .type = MODULEMD_COMPRESSION_TYPE_DETECTION_FAILED, .suffix = NULL }, + { .type = MODULEMD_COMPRESSION_TYPE_UNKNOWN_COMPRESSION, .suffix = NULL }, + { .type = MODULEMD_COMPRESSION_TYPE_NO_COMPRESSION, .suffix = "fdio" }, + { .type = MODULEMD_COMPRESSION_TYPE_GZ_COMPRESSION, .suffix = "gzdio" }, + { .type = MODULEMD_COMPRESSION_TYPE_BZ2_COMPRESSION, .suffix = "bzdio" }, + { .type = MODULEMD_COMPRESSION_TYPE_XZ_COMPRESSION, .suffix = "xzdio" }, + { .type = MODULEMD_COMPRESSION_TYPE_SENTINEL, .suffix = NULL } + }; + + const char *mode[] = { "r", "w", "a", "r+", "w+", "a+", NULL }; + g_autofree gchar *fmode = NULL; + g_autofree gchar *expected_fmode = NULL; + + for (size_t i = 0; expected[i].type != MODULEMD_COMPRESSION_TYPE_SENTINEL; + i++) + { + for (size_t j = 0; mode[j]; j++) + { + fmode = modulemd_get_rpmio_fmode (mode[j], expected[i].type); + if (expected[i].suffix == NULL) + { + g_assert_null (fmode); + g_clear_pointer (&fmode, g_free); + continue; + } + + expected_fmode = + g_strdup_printf ("%s.%s", mode[j], expected[i].suffix); + g_assert_cmpstr (fmode, ==, expected_fmode); + + g_clear_pointer (&expected_fmode, g_free); + g_clear_pointer (&fmode, g_free); + } + } +} + + +int +main (int argc, char *argv[]) +{ + setlocale (LC_ALL, ""); + + g_test_init (&argc, &argv, NULL); + g_test_bug_base ("https://bugzilla.redhat.com/show_bug.cgi?id="); + + g_test_add_func ("/modulemd/compression/type", + test_modulemd_compression_type); + + g_test_add_func ("/modulemd/compression/detect", + test_modulemd_detect_compression); + + g_test_add_func ("/modulemd/compression/suffix", + test_modulemd_compression_suffix); + + g_test_add_func ("/modulemd/compression/rmpio/fmode", + test_modulemd_get_rpmio_fmode); + + return g_test_run (); +} diff --git a/modulemd/tests/test_data/compression/bzipped b/modulemd/tests/test_data/compression/bzipped new file mode 100644 index 0000000000000000000000000000000000000000..95ab6cd61032973ba6789ae9de53f20aeca068d4 GIT binary patch literal 2920 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 literal 0 HcmV?d00001 diff --git a/modulemd/tests/test_data/compression/bzipped.yaml.bz2 b/modulemd/tests/test_data/compression/bzipped.yaml.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..95ab6cd61032973ba6789ae9de53f20aeca068d4 GIT binary patch literal 2920 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 literal 0 HcmV?d00001 diff --git a/modulemd/tests/test_data/compression/empty b/modulemd/tests/test_data/compression/empty new file mode 100644 index 000000000..e69de29bb diff --git a/modulemd/tests/test_data/compression/gzipped b/modulemd/tests/test_data/compression/gzipped new file mode 100644 index 0000000000000000000000000000000000000000..738f67db017b4971436fe58dca521b629ec661d9 GIT binary patch literal 2664 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 + Django is a high-level Python Web framework that encourages rapid development + and a clean, pragmatic design. It focuses on automating as much as possible and + adhering to the DRY (Don't Repeat Yourself) principle. + license: + module: + - MIT + xmd: + mbs: + scmurl: https://src.fedoraproject.org/modules/django.git?#90c50f8ad1cb5ca41d62632699c375dce6353adf + commit: 90c50f8ad1cb5ca41d62632699c375dce6353adf + buildrequires: + platform: + ref: virtual + stream: f28 + filtered_rpms: [] + version: 4 + rpms: + python-django: + ref: 1c3a01558a435b56f8ef4f8fc0e5c1cd35f006a5 + requires: + platform: + ref: virtual + stream: f28 + filtered_rpms: [] + version: 4 + dependencies: + - buildrequires: + platform: [f28] + requires: + platform: [f28] + references: + community: https://www.djangoproject.com + documentation: https://docs.djangoproject.com + tracker: https://code.djangoproject.com/query + profiles: + default: + rpms: + - python2-django + python2_development: + rpms: + - python2-django + api: + rpms: + - python2-django + components: + rpms: + python-django: + rationale: The Django python web framework + repository: git://pkgs.fedoraproject.org/rpms/python-django + cache: http://pkgs.fedoraproject.org/repo/pkgs/python-django + ref: 1.6 + artifacts: + rpms: + - python-django-bash-completion-0:1.6.11.7-1.module_1560+089ce146.noarch + - python2-django-0:1.6.11.7-1.module_1560+089ce146.noarch +... +--- +document: modulemd +version: 2 +data: + name: nodejs + stream: 6 + version: 20180308155546 + context: c2c572ec + summary: Javascript runtime + description: >- + Node.js is a platform built on Chrome''s JavaScript runtime for easily building + fast, scalable network applications. Node.js uses an event-driven, non-blocking + I/O model that makes it lightweight and efficient, perfect for data-intensive + real-time applications that run across distributed devices. + license: + module: + - MIT + xmd: + mbs: + scmurl: https://src.fedoraproject.org/modules/nodejs.git?#2d349c5055939081aefa37d71cd77051d235cb79 + commit: 2d349c5055939081aefa37d71cd77051d235cb79 + buildrequires: + platform: + ref: virtual + stream: f28 + filtered_rpms: [] + version: 4 + rpms: + nodejs: + ref: 374ae23edf3676653fec706a5c81c5cdf019ce11 + requires: + platform: + ref: virtual + stream: f28 + filtered_rpms: [] + version: 4 + dependencies: + - buildrequires: + platform: [f28] + requires: + platform: [f28] + references: + community: http://nodejs.org + documentation: http://nodejs.org/en/docs + tracker: https://github.com/nodejs/node/issues + profiles: + default: + rpms: + - nodejs + - npm + development: + rpms: + - nodejs + - nodejs-devel + - npm + minimal: + rpms: + - nodejs + api: + rpms: + - nodejs + - nodejs-devel + - npm + components: + rpms: + nodejs: + rationale: Javascript runtime and npm package manager. + repository: git://pkgs.fedoraproject.org/rpms/nodejs + cache: http://pkgs.fedoraproject.org/repo/pkgs/nodejs + ref: 6 + buildorder: 10 + artifacts: + rpms: + - nodejs-1:6.13.1-1.module_1575+55808bea.x86_64 + - nodejs-devel-1:6.13.1-1.module_1575+55808bea.x86_64 + - nodejs-docs-1:6.13.1-1.module_1575+55808bea.noarch + - npm-1:3.10.10-1.6.13.1.1.module_1575+55808bea.x86_64 +... +--- +document: modulemd +version: 2 +data: + name: nodejs + stream: 8 + version: 20180308143646 + context: c2c572ec + summary: Javascript runtime + description: >- + Node.js is a platform built on Chrome''s JavaScript runtime for easily building + fast, scalable network applications. Node.js uses an event-driven, non-blocking + I/O model that makes it lightweight and efficient, perfect for data-intensive + real-time applications that run across distributed devices. + license: + module: + - MIT + xmd: + mbs: + scmurl: https://src.fedoraproject.org/modules/nodejs.git?#4dc5da13fa51c5a5cc9f02a81d71416bc6ce787e + commit: 4dc5da13fa51c5a5cc9f02a81d71416bc6ce787e + buildrequires: + platform: + ref: virtual + stream: f28 + filtered_rpms: [] + version: 4 + rpms: + nodejs: + ref: 64f8f82763943f764d25225c2d95ae065490b10a + requires: + platform: + ref: virtual + stream: f28 + filtered_rpms: [] + version: 4 + mbs_options: + blocked_pacakges: + - blocked1 + - blocked2 + dependencies: + - buildrequires: + platform: [f28] + requires: + platform: [f28] + references: + community: http://nodejs.org + documentation: http://nodejs.org/en/docs + tracker: https://github.com/nodejs/node/issues + profiles: + default: + rpms: + - nodejs + - npm + development: + rpms: + - nodejs + - nodejs-devel + - npm + minimal: + rpms: + - nodejs + api: + rpms: + - nodejs + - nodejs-devel + - npm + components: + rpms: + nodejs: + rationale: Javascript runtime and npm package manager. + repository: git://pkgs.fedoraproject.org/rpms/nodejs + cache: http://pkgs.fedoraproject.org/repo/pkgs/nodejs + ref: 8 + buildorder: 10 + artifacts: + rpms: + - nodejs-1:8.10.0-3.module_1572+d7ec111e.x86_64 + - nodejs-devel-1:8.10.0-3.module_1572+d7ec111e.x86_64 + - nodejs-docs-1:8.10.0-3.module_1572+d7ec111e.noarch + - npm-1:5.6.0-1.8.10.0.3.module_1572+d7ec111e.x86_64 +... +--- +document: modulemd +version: 2 +data: + name: nodejs + stream: 9 + version: 20180308142225 + context: c2c572ec + summary: Javascript runtime + description: >- + Node.js is a platform built on Chrome''s JavaScript runtime for easily building + fast, scalable network applications. Node.js uses an event-driven, non-blocking + I/O model that makes it lightweight and efficient, perfect for data-intensive + real-time applications that run across distributed devices. + license: + module: + - MIT + xmd: + mbs: + scmurl: https://src.fedoraproject.org/modules/nodejs.git?#3f3665745cb84576f1faa66646cb8c37913ec461 + commit: 3f3665745cb84576f1faa66646cb8c37913ec461 + buildrequires: + platform: + ref: virtual + stream: f28 + filtered_rpms: [] + version: 4 + rpms: + nodejs: + ref: 65648a2672dc03641b9eaa4d25a8f19d94fd90c3 + requires: + platform: + ref: virtual + stream: f28 + filtered_rpms: [] + version: 4 + dependencies: + - buildrequires: + platform: [f28] + requires: + platform: [f28] + references: + community: http://nodejs.org + documentation: http://nodejs.org/en/docs + tracker: https://github.com/nodejs/node/issues + profiles: + default: + rpms: + - nodejs + - npm + development: + rpms: + - nodejs + - nodejs-devel + - npm + minimal: + rpms: + - nodejs + api: + rpms: + - nodejs + - nodejs-devel + - npm + components: + rpms: + nodejs: + rationale: Javascript runtime and npm package manager. + repository: git://pkgs.fedoraproject.org/rpms/nodejs + cache: http://pkgs.fedoraproject.org/repo/pkgs/nodejs + ref: 9 + buildorder: 10 + artifacts: + rpms: + - nodejs-1:9.8.0-1.module_1571+4f4bc63d.x86_64 + - nodejs-devel-1:9.8.0-1.module_1571+4f4bc63d.x86_64 + - nodejs-docs-1:9.8.0-1.module_1571+4f4bc63d.noarch + - npm-1:5.6.0-1.9.8.0.1.module_1571+4f4bc63d.x86_64 +... +--- +document: modulemd +version: 2 +data: + name: reviewboard + stream: 2.5 + version: 20180206144254 + context: e0c83381 + summary: A web-based code review tool + description: >- + Review Board is a powerful web-based code review tool that offers developers an + easy way to handle code reviews. It scales well from small projects to large companies + and offers a variety of tools to take much of the stress and time out of the code + review process. + license: + module: + - MIT + xmd: + mbs: + scmurl: https://src.fedoraproject.org/modules/reviewboard.git?#1738e1ce6352c0d4da31ba137cab0b5dc5f30166 + commit: 1738e1ce6352c0d4da31ba137cab0b5dc5f30166 + buildrequires: + platform: + ref: virtual + stream: f28 + filtered_rpms: [] + version: 3 + django: + ref: 14fb96b250feec2e2c883e06255de2c36faa7313 + stream: 1.6 + filtered_rpms: [] + version: 20180117164842 + rpms: + python-django-multiselectfield: + ref: 149bf58875fb7b55efe29e1735baf96d44eb99a9 + ReviewBoard: + ref: 5d28213f6a797e5ce28ad05ab23f80fe67353da8 + python-django-evolution: + ref: 512424e1fc4b99f6f74c01a4130a4d9402b56b4e + python-django-pipeline: + ref: f019137be96cf86f49a81001fef47a0c7ab6aa35 + python-markdown: + ref: 0af9dd03b4822c04be2742b39b5a4d48ef2d2222 + python-django-haystack: + ref: 20fe71a6fc50a83b24578fbaf86e94a4ca584d31 + python-djblets: + ref: d5634779089456ff3d0ac7b78eec81e13ff4c733 + requires: + platform: + ref: virtual + stream: f28 + filtered_rpms: [] + version: 3 + django: + ref: 14fb96b250feec2e2c883e06255de2c36faa7313 + stream: 1.6 + filtered_rpms: [] + version: 20180117164842 + dependencies: + - buildrequires: + django: [1.6] + platform: [f28] + requires: + django: [1.6] + platform: [f28] + references: + community: https://www.reviewboard.org + documentation: https://www.reviewboard.org/docs + tracker: https://hellosplat.com/s/beanbag/tickets/ + profiles: + default: + rpms: + - ReviewBoard + server: + rpms: + - ReviewBoard + api: + rpms: + - ReviewBoard + - python2-djblets + components: + rpms: + ReviewBoard: + rationale: The Review Board code review tool + repository: git://pkgs.fedoraproject.org/rpms/ReviewBoard + cache: http://pkgs.fedoraproject.org/repo/pkgs/ReviewBoard + ref: 2.5 + buildorder: 20 + python-django-evolution: + rationale: A database modification library used and maintained by the Review + Board upstream + repository: git://pkgs.fedoraproject.org/rpms/python-django-evolution + cache: http://pkgs.fedoraproject.org/repo/pkgs/python-django-evolution + ref: 0.7 + python-django-haystack: + rationale: An older version of the Haystack search library for Django, needed + for compatibility. + repository: git://pkgs.fedoraproject.org/rpms/python-django-haystack + cache: http://pkgs.fedoraproject.org/repo/pkgs/python-django-haystack + ref: 2.4 + python-django-multiselectfield: + rationale: An older version of a mult-select form field needed by Review Board. + repository: git://pkgs.fedoraproject.org/rpms/python-django-multiselectfield + cache: http://pkgs.fedoraproject.org/repo/pkgs/python-django-multiselectfield + ref: 0.1 + python-django-pipeline: + rationale: An older version of this asset-packaging library for Django that + is compatible with Review Board. + repository: git://pkgs.fedoraproject.org/rpms/python-django-pipeline + cache: http://pkgs.fedoraproject.org/repo/pkgs/python-django-pipeline + ref: 1.3 + python-djblets: + rationale: Review Board tool library + repository: git://pkgs.fedoraproject.org/rpms/python-djblets + cache: http://pkgs.fedoraproject.org/repo/pkgs/python-djblets + ref: 0.9 + buildorder: 10 + python-markdown: + rationale: An older version of this Markdown implementation that is compatible + with Review Board. + repository: git://pkgs.fedoraproject.org/rpms/python-markdown + cache: http://pkgs.fedoraproject.org/repo/pkgs/python-markdown + ref: 2.4 + artifacts: + rpms: + - ReviewBoard-0:2.5.17-17.module_d032b812.noarch + - python-django-haystack-docs-0:2.4.1-12.module_d032b812.noarch + - python2-django-evolution-1:0.7.7-12.module_d032b812.noarch + - python2-django-haystack-0:2.4.1-12.module_d032b812.noarch + - python2-django-multiselectfield-0:0.1.3-10.module_d032b812.noarch + - python2-django-pipeline-0:1.3.27-11.module_d032b812.noarch + - python2-djblets-0:0.9.9-13.module_d032b812.noarch + - python2-markdown-0:2.4.1-11.module_d032b812.noarch + - python3-markdown-0:2.4.1-11.module_d032b812.noarch +... diff --git a/modulemd/tests/test_data/compression/uncompressed.yaml b/modulemd/tests/test_data/compression/uncompressed.yaml new file mode 100644 index 000000000..968ab2240 --- /dev/null +++ b/modulemd/tests/test_data/compression/uncompressed.yaml @@ -0,0 +1,480 @@ +--- +document: modulemd-translations +version: 1 +data: + module: nodejs + stream: 8 + modified: 1 +... +--- +document: modulemd-defaults +version: 1 +data: + module: nodejs + profiles: + 6: [default] + 8: [default] + 9: [default] + intents: + server: + stream: 8 + profiles: + 6: [server] + 8: [server] +... +--- +document: modulemd-defaults +version: 1 +data: + module: reviewboard + stream: 2.5 + profiles: + 2.5: [default] +... +--- +document: modulemd-defaults +version: 1 +data: + module: django + profiles: + 1.6: [default] +... +--- +document: modulemd +version: 2 +data: + name: django + stream: 1.6 + version: 20180307130104 + context: c2c572ec + summary: A high-level Python Web framework + description: >- + Django is a high-level Python Web framework that encourages rapid development + and a clean, pragmatic design. It focuses on automating as much as possible and + adhering to the DRY (Don't Repeat Yourself) principle. + license: + module: + - MIT + xmd: + mbs: + scmurl: https://src.fedoraproject.org/modules/django.git?#90c50f8ad1cb5ca41d62632699c375dce6353adf + commit: 90c50f8ad1cb5ca41d62632699c375dce6353adf + buildrequires: + platform: + ref: virtual + stream: f28 + filtered_rpms: [] + version: 4 + rpms: + python-django: + ref: 1c3a01558a435b56f8ef4f8fc0e5c1cd35f006a5 + requires: + platform: + ref: virtual + stream: f28 + filtered_rpms: [] + version: 4 + dependencies: + - buildrequires: + platform: [f28] + requires: + platform: [f28] + references: + community: https://www.djangoproject.com + documentation: https://docs.djangoproject.com + tracker: https://code.djangoproject.com/query + profiles: + default: + rpms: + - python2-django + python2_development: + rpms: + - python2-django + api: + rpms: + - python2-django + components: + rpms: + python-django: + rationale: The Django python web framework + repository: git://pkgs.fedoraproject.org/rpms/python-django + cache: http://pkgs.fedoraproject.org/repo/pkgs/python-django + ref: 1.6 + artifacts: + rpms: + - python-django-bash-completion-0:1.6.11.7-1.module_1560+089ce146.noarch + - python2-django-0:1.6.11.7-1.module_1560+089ce146.noarch +... +--- +document: modulemd +version: 2 +data: + name: nodejs + stream: 6 + version: 20180308155546 + context: c2c572ec + summary: Javascript runtime + description: >- + Node.js is a platform built on Chrome''s JavaScript runtime for easily building + fast, scalable network applications. Node.js uses an event-driven, non-blocking + I/O model that makes it lightweight and efficient, perfect for data-intensive + real-time applications that run across distributed devices. + license: + module: + - MIT + xmd: + mbs: + scmurl: https://src.fedoraproject.org/modules/nodejs.git?#2d349c5055939081aefa37d71cd77051d235cb79 + commit: 2d349c5055939081aefa37d71cd77051d235cb79 + buildrequires: + platform: + ref: virtual + stream: f28 + filtered_rpms: [] + version: 4 + rpms: + nodejs: + ref: 374ae23edf3676653fec706a5c81c5cdf019ce11 + requires: + platform: + ref: virtual + stream: f28 + filtered_rpms: [] + version: 4 + dependencies: + - buildrequires: + platform: [f28] + requires: + platform: [f28] + references: + community: http://nodejs.org + documentation: http://nodejs.org/en/docs + tracker: https://github.com/nodejs/node/issues + profiles: + default: + rpms: + - nodejs + - npm + development: + rpms: + - nodejs + - nodejs-devel + - npm + minimal: + rpms: + - nodejs + api: + rpms: + - nodejs + - nodejs-devel + - npm + components: + rpms: + nodejs: + rationale: Javascript runtime and npm package manager. + repository: git://pkgs.fedoraproject.org/rpms/nodejs + cache: http://pkgs.fedoraproject.org/repo/pkgs/nodejs + ref: 6 + buildorder: 10 + artifacts: + rpms: + - nodejs-1:6.13.1-1.module_1575+55808bea.x86_64 + - nodejs-devel-1:6.13.1-1.module_1575+55808bea.x86_64 + - nodejs-docs-1:6.13.1-1.module_1575+55808bea.noarch + - npm-1:3.10.10-1.6.13.1.1.module_1575+55808bea.x86_64 +... +--- +document: modulemd +version: 2 +data: + name: nodejs + stream: 8 + version: 20180308143646 + context: c2c572ec + summary: Javascript runtime + description: >- + Node.js is a platform built on Chrome''s JavaScript runtime for easily building + fast, scalable network applications. Node.js uses an event-driven, non-blocking + I/O model that makes it lightweight and efficient, perfect for data-intensive + real-time applications that run across distributed devices. + license: + module: + - MIT + xmd: + mbs: + scmurl: https://src.fedoraproject.org/modules/nodejs.git?#4dc5da13fa51c5a5cc9f02a81d71416bc6ce787e + commit: 4dc5da13fa51c5a5cc9f02a81d71416bc6ce787e + buildrequires: + platform: + ref: virtual + stream: f28 + filtered_rpms: [] + version: 4 + rpms: + nodejs: + ref: 64f8f82763943f764d25225c2d95ae065490b10a + requires: + platform: + ref: virtual + stream: f28 + filtered_rpms: [] + version: 4 + mbs_options: + blocked_pacakges: + - blocked1 + - blocked2 + dependencies: + - buildrequires: + platform: [f28] + requires: + platform: [f28] + references: + community: http://nodejs.org + documentation: http://nodejs.org/en/docs + tracker: https://github.com/nodejs/node/issues + profiles: + default: + rpms: + - nodejs + - npm + development: + rpms: + - nodejs + - nodejs-devel + - npm + minimal: + rpms: + - nodejs + api: + rpms: + - nodejs + - nodejs-devel + - npm + components: + rpms: + nodejs: + rationale: Javascript runtime and npm package manager. + repository: git://pkgs.fedoraproject.org/rpms/nodejs + cache: http://pkgs.fedoraproject.org/repo/pkgs/nodejs + ref: 8 + buildorder: 10 + artifacts: + rpms: + - nodejs-1:8.10.0-3.module_1572+d7ec111e.x86_64 + - nodejs-devel-1:8.10.0-3.module_1572+d7ec111e.x86_64 + - nodejs-docs-1:8.10.0-3.module_1572+d7ec111e.noarch + - npm-1:5.6.0-1.8.10.0.3.module_1572+d7ec111e.x86_64 +... +--- +document: modulemd +version: 2 +data: + name: nodejs + stream: 9 + version: 20180308142225 + context: c2c572ec + summary: Javascript runtime + description: >- + Node.js is a platform built on Chrome''s JavaScript runtime for easily building + fast, scalable network applications. Node.js uses an event-driven, non-blocking + I/O model that makes it lightweight and efficient, perfect for data-intensive + real-time applications that run across distributed devices. + license: + module: + - MIT + xmd: + mbs: + scmurl: https://src.fedoraproject.org/modules/nodejs.git?#3f3665745cb84576f1faa66646cb8c37913ec461 + commit: 3f3665745cb84576f1faa66646cb8c37913ec461 + buildrequires: + platform: + ref: virtual + stream: f28 + filtered_rpms: [] + version: 4 + rpms: + nodejs: + ref: 65648a2672dc03641b9eaa4d25a8f19d94fd90c3 + requires: + platform: + ref: virtual + stream: f28 + filtered_rpms: [] + version: 4 + dependencies: + - buildrequires: + platform: [f28] + requires: + platform: [f28] + references: + community: http://nodejs.org + documentation: http://nodejs.org/en/docs + tracker: https://github.com/nodejs/node/issues + profiles: + default: + rpms: + - nodejs + - npm + development: + rpms: + - nodejs + - nodejs-devel + - npm + minimal: + rpms: + - nodejs + api: + rpms: + - nodejs + - nodejs-devel + - npm + components: + rpms: + nodejs: + rationale: Javascript runtime and npm package manager. + repository: git://pkgs.fedoraproject.org/rpms/nodejs + cache: http://pkgs.fedoraproject.org/repo/pkgs/nodejs + ref: 9 + buildorder: 10 + artifacts: + rpms: + - nodejs-1:9.8.0-1.module_1571+4f4bc63d.x86_64 + - nodejs-devel-1:9.8.0-1.module_1571+4f4bc63d.x86_64 + - nodejs-docs-1:9.8.0-1.module_1571+4f4bc63d.noarch + - npm-1:5.6.0-1.9.8.0.1.module_1571+4f4bc63d.x86_64 +... +--- +document: modulemd +version: 2 +data: + name: reviewboard + stream: 2.5 + version: 20180206144254 + context: e0c83381 + summary: A web-based code review tool + description: >- + Review Board is a powerful web-based code review tool that offers developers an + easy way to handle code reviews. It scales well from small projects to large companies + and offers a variety of tools to take much of the stress and time out of the code + review process. + license: + module: + - MIT + xmd: + mbs: + scmurl: https://src.fedoraproject.org/modules/reviewboard.git?#1738e1ce6352c0d4da31ba137cab0b5dc5f30166 + commit: 1738e1ce6352c0d4da31ba137cab0b5dc5f30166 + buildrequires: + platform: + ref: virtual + stream: f28 + filtered_rpms: [] + version: 3 + django: + ref: 14fb96b250feec2e2c883e06255de2c36faa7313 + stream: 1.6 + filtered_rpms: [] + version: 20180117164842 + rpms: + python-django-multiselectfield: + ref: 149bf58875fb7b55efe29e1735baf96d44eb99a9 + ReviewBoard: + ref: 5d28213f6a797e5ce28ad05ab23f80fe67353da8 + python-django-evolution: + ref: 512424e1fc4b99f6f74c01a4130a4d9402b56b4e + python-django-pipeline: + ref: f019137be96cf86f49a81001fef47a0c7ab6aa35 + python-markdown: + ref: 0af9dd03b4822c04be2742b39b5a4d48ef2d2222 + python-django-haystack: + ref: 20fe71a6fc50a83b24578fbaf86e94a4ca584d31 + python-djblets: + ref: d5634779089456ff3d0ac7b78eec81e13ff4c733 + requires: + platform: + ref: virtual + stream: f28 + filtered_rpms: [] + version: 3 + django: + ref: 14fb96b250feec2e2c883e06255de2c36faa7313 + stream: 1.6 + filtered_rpms: [] + version: 20180117164842 + dependencies: + - buildrequires: + django: [1.6] + platform: [f28] + requires: + django: [1.6] + platform: [f28] + references: + community: https://www.reviewboard.org + documentation: https://www.reviewboard.org/docs + tracker: https://hellosplat.com/s/beanbag/tickets/ + profiles: + default: + rpms: + - ReviewBoard + server: + rpms: + - ReviewBoard + api: + rpms: + - ReviewBoard + - python2-djblets + components: + rpms: + ReviewBoard: + rationale: The Review Board code review tool + repository: git://pkgs.fedoraproject.org/rpms/ReviewBoard + cache: http://pkgs.fedoraproject.org/repo/pkgs/ReviewBoard + ref: 2.5 + buildorder: 20 + python-django-evolution: + rationale: A database modification library used and maintained by the Review + Board upstream + repository: git://pkgs.fedoraproject.org/rpms/python-django-evolution + cache: http://pkgs.fedoraproject.org/repo/pkgs/python-django-evolution + ref: 0.7 + python-django-haystack: + rationale: An older version of the Haystack search library for Django, needed + for compatibility. + repository: git://pkgs.fedoraproject.org/rpms/python-django-haystack + cache: http://pkgs.fedoraproject.org/repo/pkgs/python-django-haystack + ref: 2.4 + python-django-multiselectfield: + rationale: An older version of a mult-select form field needed by Review Board. + repository: git://pkgs.fedoraproject.org/rpms/python-django-multiselectfield + cache: http://pkgs.fedoraproject.org/repo/pkgs/python-django-multiselectfield + ref: 0.1 + python-django-pipeline: + rationale: An older version of this asset-packaging library for Django that + is compatible with Review Board. + repository: git://pkgs.fedoraproject.org/rpms/python-django-pipeline + cache: http://pkgs.fedoraproject.org/repo/pkgs/python-django-pipeline + ref: 1.3 + python-djblets: + rationale: Review Board tool library + repository: git://pkgs.fedoraproject.org/rpms/python-djblets + cache: http://pkgs.fedoraproject.org/repo/pkgs/python-djblets + ref: 0.9 + buildorder: 10 + python-markdown: + rationale: An older version of this Markdown implementation that is compatible + with Review Board. + repository: git://pkgs.fedoraproject.org/rpms/python-markdown + cache: http://pkgs.fedoraproject.org/repo/pkgs/python-markdown + ref: 2.4 + artifacts: + rpms: + - ReviewBoard-0:2.5.17-17.module_d032b812.noarch + - python-django-haystack-docs-0:2.4.1-12.module_d032b812.noarch + - python2-django-evolution-1:0.7.7-12.module_d032b812.noarch + - python2-django-haystack-0:2.4.1-12.module_d032b812.noarch + - python2-django-multiselectfield-0:0.1.3-10.module_d032b812.noarch + - python2-django-pipeline-0:1.3.27-11.module_d032b812.noarch + - python2-djblets-0:0.9.9-13.module_d032b812.noarch + - python2-markdown-0:2.4.1-11.module_d032b812.noarch + - python3-markdown-0:2.4.1-11.module_d032b812.noarch +... diff --git a/modulemd/tests/test_data/compression/xzipped b/modulemd/tests/test_data/compression/xzipped new file mode 100644 index 0000000000000000000000000000000000000000..f5594a0f18d11a2591f6af495db156f2e9e61a11 GIT binary patch literal 2564 zcmV+f3j6i_H+ooF000E$*0e?f03iVu0001VFXf})G>{3xT>uv6{*4FGX4?JNJ-MJW zdZ0jJKEAiQI;*yv#)cD-8txVCllo5~#_@(8<47416%&6;z@Lt1N;TSXsHdEDm;edy z_qk$RH8I1L-XFg%gEYQ20eY@ub@ezsGQ^*JICL|`KB5lSA6bEUm^;5ok zp<{29yac{T6 ztM7pRl&6pk6%h}q!aJOt&#DiI)@DCaj(b4gfGFc?YFCA8oJwpdb$kj;`ds(ShVMGq zlG;tMzaR`wCtGNPw%u}RjGC3aA(^)Z{Os2&`UT!xDXDuxft^R5wG=n?ga&57xx^a6 zKr?aubve%&p3P@Z)U02h%}Om35VqJYe;(?t;=C4qHVNko(jppz2N;c#(A0X3WoTEz z3DsL{;Ch&S34|M5tr_F%LtA5o@6Ldq7dBD}rx8JR9G*j~pBbgmKcneGd}?J4zAi@= zVFwT@JbyxFXu0|hmUqD2lLhLOXklF&w~P0K1mF5L+U}LLXCVgHn8mv77qC{tIvJ~3 zZaOa;ditfP@G&(lfH|5G+ml}OlGexmbZP2DA7>6M(<}st047l^;J!uqZIaf%Els>Q z;+X9M#TC~AbDQW_o3(Xtk|+8(o5uqDyEPH-s~;mg@%^&REqjp#!-r!V(UTtN+!7@_QpgZe!5v8bP@N&P>+#Dz|mS zEaF0^F%#=xe2y_j?(FCCujZ^*IDs<~1l!D6&Ce~bUzIc0hy96{8eMke%iQU2obh{P zET&XIlMe+0T-5T?$^`}ai;T&#f=O-CtV-ZMF=E&o_L*`#j_^AF7=|8%pD{ppf+j*em|1jiSHQLS6#3 zW;J~AnpN|#QgSyplsxsGG9E+t2$A&d-~fD>#R6NZ&hZP>u7+rY=c|)mxW|xUEyoAY zH)CtADZ5VGOx~c@ z-FOsv^wNm5!%-j^+0!k|Riac26Av7pQ!q{@Gwg`|g|QTlOt&p`7Mc?z_0WD+Kz5 znU|Ty#H2VFsl{!ERbC#XcCyD?&kKaMSc$ngb((u+tw^19c{Iw)b1vd3 zL+OOry7Eu!3{wWbUzeyH@U960O0>v5p?E!^C#+PZkdOO$hD=JXPpF7+AwhEZ3`?c+3%nn)X!L{+xs7m+%OY3*ArKCEOa%H>qoi)BL~X<3 z9>L0h@9qT=f>ifVH6(W3uFdyNnu6!KpP_!v3t{#N9L+*;=*0{H>X10Y835;Va3LI! zJsqc$AGoAla>s>nrysEZ(SM(h1UJ}J#pqNyX3+!xiSSG}U%OYT!iFr{_tiO7QbpsN zE*eOX5>e1d@x>IuTUs+^wPMqza-22 zq)&xqW5M2EKAZ6YP6L#?k(Qti?U~=>xCw8D2e$xMjSa6x?rI zj8}zYJn*;Xi^v?!Vmrrv>5MIp5`I!oeGSIk1}$~vb#L@Xa;*to*Vy%JVj99=tTO25 z=#C20&Bt^inx^Y3Ix(3BbfuhqAKda+cfn=8FO6KyI5X#pL6^p|6nq5f?cg+t*MDdR z`#O}K7{PEj@6mfUhAvP9u13)SRUuTJ{4URUiZBXSHvOcm zq$GrqR;623!xm^ea%oqFq`Zu|Rl9NnNE}ty@ja_MWtY%BvIO()wIm9q!YxI2;_fmW zAl6n1(zJ>?GZp?3fU}bt2pe1EZ2$Tg21y@ek+WKxaEXb$j z2cE}nR#LdP<=qheBlESSVbN^09`#>v7i=0qh+H&e8q0I{!0000ntpkfM5Pi!4 a0p1glX#fDeGTV-^#Ao{g000001X)_?$M{76 literal 0 HcmV?d00001 diff --git a/modulemd/tests/test_data/compression/xzipped.yaml.xz b/modulemd/tests/test_data/compression/xzipped.yaml.xz new file mode 100644 index 0000000000000000000000000000000000000000..f5594a0f18d11a2591f6af495db156f2e9e61a11 GIT binary patch literal 2564 zcmV+f3j6i_H+ooF000E$*0e?f03iVu0001VFXf})G>{3xT>uv6{*4FGX4?JNJ-MJW zdZ0jJKEAiQI;*yv#)cD-8txVCllo5~#_@(8<47416%&6;z@Lt1N;TSXsHdEDm;edy z_qk$RH8I1L-XFg%gEYQ20eY@ub@ezsGQ^*JICL|`KB5lSA6bEUm^;5ok zp<{29yac{T6 ztM7pRl&6pk6%h}q!aJOt&#DiI)@DCaj(b4gfGFc?YFCA8oJwpdb$kj;`ds(ShVMGq zlG;tMzaR`wCtGNPw%u}RjGC3aA(^)Z{Os2&`UT!xDXDuxft^R5wG=n?ga&57xx^a6 zKr?aubve%&p3P@Z)U02h%}Om35VqJYe;(?t;=C4qHVNko(jppz2N;c#(A0X3WoTEz z3DsL{;Ch&S34|M5tr_F%LtA5o@6Ldq7dBD}rx8JR9G*j~pBbgmKcneGd}?J4zAi@= zVFwT@JbyxFXu0|hmUqD2lLhLOXklF&w~P0K1mF5L+U}LLXCVgHn8mv77qC{tIvJ~3 zZaOa;ditfP@G&(lfH|5G+ml}OlGexmbZP2DA7>6M(<}st047l^;J!uqZIaf%Els>Q z;+X9M#TC~AbDQW_o3(Xtk|+8(o5uqDyEPH-s~;mg@%^&REqjp#!-r!V(UTtN+!7@_QpgZe!5v8bP@N&P>+#Dz|mS zEaF0^F%#=xe2y_j?(FCCujZ^*IDs<~1l!D6&Ce~bUzIc0hy96{8eMke%iQU2obh{P zET&XIlMe+0T-5T?$^`}ai;T&#f=O-CtV-ZMF=E&o_L*`#j_^AF7=|8%pD{ppf+j*em|1jiSHQLS6#3 zW;J~AnpN|#QgSyplsxsGG9E+t2$A&d-~fD>#R6NZ&hZP>u7+rY=c|)mxW|xUEyoAY zH)CtADZ5VGOx~c@ z-FOsv^wNm5!%-j^+0!k|Riac26Av7pQ!q{@Gwg`|g|QTlOt&p`7Mc?z_0WD+Kz5 znU|Ty#H2VFsl{!ERbC#XcCyD?&kKaMSc$ngb((u+tw^19c{Iw)b1vd3 zL+OOry7Eu!3{wWbUzeyH@U960O0>v5p?E!^C#+PZkdOO$hD=JXPpF7+AwhEZ3`?c+3%nn)X!L{+xs7m+%OY3*ArKCEOa%H>qoi)BL~X<3 z9>L0h@9qT=f>ifVH6(W3uFdyNnu6!KpP_!v3t{#N9L+*;=*0{H>X10Y835;Va3LI! zJsqc$AGoAla>s>nrysEZ(SM(h1UJ}J#pqNyX3+!xiSSG}U%OYT!iFr{_tiO7QbpsN zE*eOX5>e1d@x>IuTUs+^wPMqza-22 zq)&xqW5M2EKAZ6YP6L#?k(Qti?U~=>xCw8D2e$xMjSa6x?rI zj8}zYJn*;Xi^v?!Vmrrv>5MIp5`I!oeGSIk1}$~vb#L@Xa;*to*Vy%JVj99=tTO25 z=#C20&Bt^inx^Y3Ix(3BbfuhqAKda+cfn=8FO6KyI5X#pL6^p|6nq5f?cg+t*MDdR z`#O}K7{PEj@6mfUhAvP9u13)SRUuTJ{4URUiZBXSHvOcm zq$GrqR;623!xm^ea%oqFq`Zu|Rl9NnNE}ty@ja_MWtY%BvIO()wIm9q!YxI2;_fmW zAl6n1(zJ>?GZp?3fU}bt2pe1EZ2$Tg21y@ek+WKxaEXb$j z2cE}nR#LdP<=qheBlESSVbN^09`#>v7i=0qh+H&e8q0I{!0000ntpkfM5Pi!4 a0p1glX#fDeGTV-^#Ao{g000001X)_?$M{76 literal 0 HcmV?d00001