From: Yann Dirson <[email protected]>

This works like:
- yarn-v1-mkbbinc script generates a $PACKAGE.inc bitbake snippet containing
  * SRC_URI additions for all dependencies
  * YARNLOCK_CHECKSUM for consistency checking
- $PACKAGE.bb uses "require $PACKAGE.inc"

Supports only:
- *.tgz from npm registries and arbitrary sources
- *.tar.gz from arbitrary sources including github releases
---
 meta-os/classes/yarn-v1.bbclass |  15 +++
 scripts/yarn-v1-mkbbinc         | 168 ++++++++++++++++++++++++++++++++
 2 files changed, 183 insertions(+)
 create mode 100644 meta-os/classes/yarn-v1.bbclass
 create mode 100755 scripts/yarn-v1-mkbbinc


There are quite some ad-hoc things in the mkbbinc script, that make we
wonder whether it's got enough quality for inclusion.  OTOH it could
be seen as a base that's already working for the subset it's meant to
address, and it seems quite overkill to create a layer just for these
2 files.

Could be more clear in python than in bash, though, I guess.

diff --git a/meta-os/classes/yarn-v1.bbclass b/meta-os/classes/yarn-v1.bbclass
new file mode 100644
index 0000000000..296b4116b0
--- /dev/null
+++ b/meta-os/classes/yarn-v1.bbclass
@@ -0,0 +1,15 @@
+# yarn-v1 unpack support from offline mirror
+
+do_unpack_yarn_depends() {
+    # make sure we did not forget to update the .inc with new package version
+    CKSUM=$(sha256sum ${S}/yarn.lock |cut -d' ' -f 1)
+    [ "$CKSUM" = "${YARNLOCK_CHECKSUM}" ] || bbfatal "recipe does not match 
${S}/yarn.lock, please rerun yarn-v1-mkbbinc"
+
+    # go use offline mirror
+    echo 'yarn-offline-mirror "${WORKDIR}/offline-mirror"' > ${S}/.yarnrc
+    yarn --verbose --frozen-lockfile --offline --cwd ${S}
+}
+
+do_unpack_yarn_depends[depends] += "yarn-native:do_populate_sysroot"
+
+addtask do_unpack_yarn_depends after do_unpack before do_patch
diff --git a/scripts/yarn-v1-mkbbinc b/scripts/yarn-v1-mkbbinc
new file mode 100755
index 0000000000..a2a7a2d918
--- /dev/null
+++ b/scripts/yarn-v1-mkbbinc
@@ -0,0 +1,168 @@
+#!/bin/bash
+set -eE
+
+# Usage: yarn-v1-mkbbinc upstream/yarn.lock meta-foo/recipes-bar/package.inc
+#
+# Takes the list of dependencies recorded in a yarn.lock file and
+# generates a bitbake include file suitable for a simple "require
+# package.inc".  It appends all those dependencies to SRC_URI so
+# do_unpack will put them in ${WORKDIR}/offline-mirror/, and pulls
+# yarn-v1.bbclass to provide a do_unpack_yarn_depends sitting between
+# do_unpack and do_patch.
+
+# Known issues:
+
+# - this script makes assumptions about the yarn.lock syntax, for
+#   which the sole parser is part of yarn itself.  A js implementation
+#   could make use of that parser instead of doing ad-hoc text
+#   processing (though that works well enough).
+
+# - this script makes assumptions about the layout of the yarn v1
+#   "offline mirror".  A js implementation could possibly, maybe, use
+#   yarn's internal APIs to get the correct name.
+
+# - it has to include seemingly ad-hoc rules for different registry
+#   implementations.  Maybe this too could go away with a js
+#   implementation.
+
+# - yarn v2 uses an "offline cache" instead of this "offline mirror",
+#   will need a similar processing.
+
+die() {
+    echo >&2 "ERROR: $*"
+    exit 1
+}
+
+
+## command-line
+
+[ $# = 2 ] ||
+    die "usage: $(basename $0) upstream/yarn.lock 
meta-foo/recipes-bar/package.inc"
+
+YARNLOCK="$1"
+BBINC="$2"
+
+
+## core funcs
+
+# derive cache filename for a standard npm registry
+# (essentially wet-finger guesses)
+npm_cachefilename() {
+    urldir="$1"
+    remotefilename="$2"
+
+    case "$urldir" in
+        https://gitlab.com/api/v4/projects/*/packages/npm/*)
+            dir=${urldir#https://gitlab.com/api/v4/projects/*/packages/npm/}
+            ;;
+        *) # holds for registry.yarnpkg.com and registry.npmjs.org
+            dir=${urldir#*://} # strip protocol
+            dir=${dir#*/} # strip server
+            ;;
+    esac
+
+    shortpkg=$(basename $dir)
+    case "$dir" in
+        */$shortpkg) ;;
+        $shortpkg) ;;
+        *) die "wrong assumption dir='$dir' shortpkg='$shortpkg' 
urldir='$urldir' remotefilename='$remotefilename'" ;;
+    esac
+
+    pkg=$(echo $remotefilename | sed s/$shortpkg-.*/$shortpkg/) # strip 
version+suffix
+    case "$dir" in
+        */$pkg) ;;
+        $pkg) ;;
+        *) die "wrong assumption dir='$dir' shortpkg='$shortpkg' pkg='$pkg' 
urldir='$urldir' remotefilename='$remotefilename'" ;;
+    esac
+
+    # mangle filename according to depth in registry
+    dir=${dir%$pkg}
+    remotefilename=$(echo $remotefilename | tr / -)
+    case "$dir" in
+        '') echo "$remotefilename" ;;
+        */*/) die "more than one level of dirs '$dir' above package name in 
$url" ;;
+        */) echo "${dir%/}-$remotefilename" ;;
+    esac
+    #die "DBG dir='$dir' pkg='$pkg' urldir='$urldir' 
remotefilename='$remotefilename'"
+}
+
+gen_dependencies() {
+    grep '^ *resolved ".*#.*"$' "$YARNLOCK" |
+        cut -d'"' -f 2 | {
+        print_srcuri "SRC_URI_append = \" \\"
+        CKSUMS=""
+        while IFS=# read url checksum ; do
+            case "$url" in
+                *.tgz)
+                    afterdash=${url#*/-/}
+                    if [ "$afterdash" = "$url" ]; then
+                        # no /-/ in URL
+                        cachefilename=$(basename $url)
+                    else
+                        beforedash=${url%/-/*}
+                        cachefilename="$(npm_cachefilename "$beforedash" 
"$afterdash")"
+                    fi
+
+                    # Protect from invalid characters in SRC_URI's "name" 
value.
+                    # I see no guaranty that it can't lead to a name clash, but
+                    # do_fetch will bomb out if that happens.
+                    srcid=$(echo $cachefilename | tr @ .)
+
+                    print_srcuri " 
$url;downloadfilename=$cachefilename;name=$srcid;unpack=0;subdir=offline-mirror 
\\"
+                    ;;
+
+                *.tar.gz)
+                    cachefilename=$(basename $url)
+                    srcid=$(echo $cachefilename | tr @ .)
+                    print_srcuri " 
$url;downloadfilename=$cachefilename;name=$srcid;unpack=0;subdir=offline-mirror 
\\"
+                    ;;
+
+                *) die "unsupported URL '$url'" ;;
+            esac
+            print_cksums "SRC_URI[$srcid.sha1sum] = \"$checksum\""
+        done
+        print_srcuri "\""
+    }
+}
+
+
+## main processing
+
+TMPSRCURI=$(mktemp --tmpdir yarn-mkbb.XXXXXX.inc)
+TMPCKSUMS=$(mktemp --tmpdir yarn-mkbb.XXXXXX.inc)
+
+print_srcuri() {
+    echo >> "$TMPSRCURI" "$@"
+}
+print_cksums() {
+    echo >> "$TMPCKSUMS" "$@"
+}
+
+CKSUM=$(sha256sum  "$YARNLOCK" |cut -d' ' -f 1)
+
+gen_dependencies
+
+[ "$CKSUM" = $(sha256sum  "$YARNLOCK" |cut -d' ' -f 1) ] ||
+    die "$YARNLOCK changed under my feet"
+
+TMPINC=$(mktemp --tmpdir yarn-mkbb.XXXXXX.inc)
+
+cat > "$TMPINC" <<EOF
+# This file was generated by $(basename $0)
+
+inherit yarn-v1
+
+YARNLOCK_CHECKSUM = "$CKSUM"
+
+EOF
+
+cat "$TMPSRCURI" >> "$TMPINC"
+echo >> "$TMPINC"
+cat "$TMPCKSUMS" >> "$TMPINC"
+
+rm "$TMPSRCURI" "$TMPCKSUMS"
+
+
+## rename to final output name
+
+mv -i "$TMPINC" "$BBINC"
-- 
2.29.2

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#145173): 
https://lists.openembedded.org/g/openembedded-core/message/145173
Mute This Topic: https://lists.openembedded.org/mt/78656649/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to