diff --git a/snapcraft.yaml b/snapcraft.yaml index 6e25c7ff..4e0e0175 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -55,13 +55,18 @@ parts: appstream-generator: source: . source-type: git - parse-info: [data/org.freedesktop.appstream.generator.metainfo.xml] + parse-info: [usr/share/metainfo/org.freedesktop.appstream.generator.metainfo.xml] override-pull: | snapcraftctl pull # set version from Git snapcraftctl set-version "$(git describe --always | sed -e 's/v//;s/-/+git/;y/-/./')" + # adjust to an absolute path to help finding the GIR file from the AppStream part + sed -i 's|AppStream-1.0.gir|$SNAPCRAFT_STAGE/usr/share/gir-1.0/AppStream-1.0.gir|g' ${SNAPCRAFT_PART_SRC}/contrib/girwrap/APILookupAppStream.txt + sed -i 's|AppStreamCompose-1.0.gir|$SNAPCRAFT_STAGE/usr/share/gir-1.0/AppStreamCompose-1.0.gir|g' ${SNAPCRAFT_PART_SRC}/contrib/girwrap/APILookupAppStreamCompose.txt + + plugin: meson build-environment: - LD_LIBRARY_PATH: $SNAPCRAFT_STAGE/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/ @@ -71,18 +76,13 @@ parts: echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list apt-get update && apt-get install --no-install-recommends -y yarn nodejs - # adjust to an absolute path to help finding the GIR file from the AppStream part - sed -i 's|AppStream-1.0.gir|$SNAPCRAFT_STAGE/usr/share/gir-1.0/AppStream-1.0.gir|g' contrib/girwrap/APILookupAppStream.txt - sed -i 's|AppStreamCompose-1.0.gir|$SNAPCRAFT_STAGE/usr/share/gir-1.0/AppStreamCompose-1.0.gir|g' contrib/girwrap/APILookupAppStreamCompose.txt - # actually build asgen - we need to run everything manually here, # because snapcraft will kill the build if run with maximum amount of ninja jobs, # and I found no way to limit the amount of permitted ninja jobs other than overriding everything - meson --prefix=/usr --buildtype=debugoptimized -Ddownload-js=true snapbuild - cd snapbuild - ninja -j1 - meson test --verbose - DESTDIR=$SNAPCRAFT_PART_INSTALL ninja install + meson --prefix=/usr --buildtype=debugoptimized -Ddownload-js=true ${SNAPCRAFT_PART_BUILD} ${SNAPCRAFT_PART_SRC} + ninja -C "${SNAPCRAFT_PART_BUILD}" -j4 + meson test -C "${SNAPCRAFT_PART_BUILD}" --verbose + DESTDIR=${SNAPCRAFT_PART_INSTALL} ninja -C "${SNAPCRAFT_PART_BUILD}" install override-prime: | set -eux snapcraftctl prime diff --git a/src/asgen/backends/debian/debpkg.d b/src/asgen/backends/debian/debpkg.d index 469511e0..ebe83966 100644 --- a/src/asgen/backends/debian/debpkg.d +++ b/src/asgen/backends/debian/debpkg.d @@ -174,21 +174,23 @@ public: { import std.regex : ctRegex; - if (dataArchive.isOpen) - return dataArchive; - - ArchiveDecompressor ad; - // extract the payload to a temporary location first - ad.open (this.getFilename); - mkdirRecurse (tmpDir); - - auto files = ad.extractFilesByRegex (ctRegex!(r"data\.*"), tmpDir); - if (files.length == 0) - throw new Exception ("Unable to find the payload tarball in Debian package: %s".format (this.getFilename)); - immutable dataArchiveFname = files[0]; - - dataArchive.open (dataArchiveFname); - return dataArchive; + synchronized(this) { + if (dataArchive.isOpen) + return dataArchive; + + ArchiveDecompressor ad; + // extract the payload to a temporary location first + ad.open (this.getFilename); + mkdirRecurse (tmpDir); + + auto files = ad.extractFilesByRegex (ctRegex!(r"data\.*"), tmpDir); + if (files.length == 0) + throw new Exception ("Unable to find the payload tarball in Debian package: %s".format (this.getFilename)); + immutable dataArchiveFname = files[0]; + + dataArchive.open (dataArchiveFname); + return dataArchive; + } } final void extractPackage (const string dest = buildPath (tmpDir, name)) @@ -196,32 +198,36 @@ public: import std.file : exists; import std.regex : ctRegex; - if (!dest.exists) - mkdirRecurse (dest); + synchronized(this) { + if (!dest.exists) + mkdirRecurse (dest); - auto pa = openPayloadArchive (); - pa.extractArchive (dest); + auto pa = openPayloadArchive (); + pa.extractArchive (dest); + } } private final auto openControlArchive () { import std.regex : ctRegex; - if (controlArchive.isOpen) - return controlArchive; + synchronized(this) { + if (controlArchive.isOpen) + return controlArchive; - ArchiveDecompressor ad; - // extract the payload to a temporary location first - ad.open (this.getFilename); - mkdirRecurse (tmpDir); + ArchiveDecompressor ad; + // extract the payload to a temporary location first + ad.open (this.getFilename); + mkdirRecurse (tmpDir); - auto files = ad.extractFilesByRegex (ctRegex!(r"control\.*"), tmpDir); - if (files.empty) - throw new Exception ("Unable to find control data in Debian package: %s".format (this.getFilename)); - immutable controlArchiveFname = files[0]; + auto files = ad.extractFilesByRegex (ctRegex!(r"control\.*"), tmpDir); + if (files.empty) + throw new Exception ("Unable to find control data in Debian package: %s".format (this.getFilename)); + immutable controlArchiveFname = files[0]; - controlArchive.open (controlArchiveFname); - return controlArchive; + controlArchive.open (controlArchiveFname); + return controlArchive; + } } override final @@ -323,22 +329,31 @@ public: override final void cleanupTemp () { - controlArchive.close (); - dataArchive.close (); - - try { - if (std.file.exists (tmpDir)) - rmdirRecurse (tmpDir); - } catch (Exception e) { - // we ignore any error - logDebug ("Unable to remove temporary directory: %s (%s)", tmpDir, e.msg); + synchronized(this) { + if (controlArchive.isOpen) + controlArchive.close (); + if (dataArchive.isOpen) + dataArchive.close (); + + try { + if (std.file.exists (tmpDir)) { + /* Whenever we delete the temporary directory, we need to + * forget about the local file too, since (if it's remote) that + * was downloaded into there. */ + logDebug ("Deleting temporary directory %s", tmpDir); + localDebFname = null; + rmdirRecurse (tmpDir); + } + } catch (Exception e) { + // we ignore any error + logDebug ("Unable to remove temporary directory: %s (%s)", tmpDir, e.msg); + } } } override final void finish () { - localDebFname = null; cleanupTemp (); } } diff --git a/src/asgen/meson.build b/src/asgen/meson.build index cde84364..42913dc6 100644 --- a/src/asgen/meson.build +++ b/src/asgen/meson.build @@ -110,4 +110,6 @@ asgen_test_exe = executable('asgen_test', d_import_dirs: [data_import_dirs], d_unittest: true ) -test('asgen_tests', asgen_test_exe) +test('asgen_tests', + asgen_test_exe, + workdir: meson.source_root()) diff --git a/src/asgen/utils.d b/src/asgen/utils.d index 615757f9..8cd2dd12 100644 --- a/src/asgen/utils.d +++ b/src/asgen/utils.d @@ -368,6 +368,10 @@ string getDataPath (string fname) if (std.file.exists (resPath)) return resPath; + resPath = buildPath ("data", fname); + if (std.file.exists (resPath)) + return resPath; + // Uh, let's just give up return buildPath ("/usr", "share", "appstream", fname); } diff --git a/src/asgen/zarchive.d b/src/asgen/zarchive.d index 6eeac96f..9381f356 100644 --- a/src/asgen/zarchive.d +++ b/src/asgen/zarchive.d @@ -19,6 +19,7 @@ module asgen.zarchive; +import core.stdc.string : strerror; import std.stdio; import std.string; import std.regex; @@ -97,8 +98,15 @@ string decompressFile (string fname) archive_read_support_filter_all (ar); ret = archive_read_open_filename (ar, toStringz (fname), DEFAULT_BLOCK_SIZE); - if (ret != ARCHIVE_OK) - throw new Exception (format ("Unable to open compressed file '%s': %s", fname, getArchiveErrorMessage (ar))); + if (ret != ARCHIVE_OK) { + auto ret_errno = archive_errno (ar); + auto ret_strerr = fromStringz (strerror(ret_errno)); + throw new Exception (format ("Unable to open compressed file '%s': %s. error: %s (%d)", + fname, + getArchiveErrorMessage (ar), + ret_strerr, + ret_errno)); + } return readArchiveData (ar, fname); } @@ -177,10 +185,15 @@ private: archive_read_support_format_all (ar); auto ret = archive_read_open_filename (ar, archive_fname.toStringz, DEFAULT_BLOCK_SIZE); - if (ret != ARCHIVE_OK) - throw new Exception (format ("Unable to open compressed file '%s': %s", - archive_fname, - getArchiveErrorMessage (ar))); + if (ret != ARCHIVE_OK) { + auto ret_errno = archive_errno (ar); + auto ret_strerr = fromStringz (strerror(ret_errno)); + throw new Exception (format ("Unable to open compressed file '%s': %s. error: %s (%d)", + archive_fname, + getArchiveErrorMessage (ar), + ret_strerr, + ret_errno)); + } return ar; }