diff --git a/.ci/steps.sh b/.ci/steps.sh deleted file mode 100644 index 50b0c9d..0000000 --- a/.ci/steps.sh +++ /dev/null @@ -1,54 +0,0 @@ -#! /bin/sh - -set -o xtrace - -function new_section { - set +o xtrace - echo "" - echo "" - echo "========" - echo $1 - set -o xtrace -} - -REGISTRY_URL=http://localhost:4873 - -if ! command -v verdaccio &> /dev/null -then - new_section "Installing verdaccio" - yarn global add verdaccio -fi - -VERDACCIO_PID=$(netstat -ano | grep 4873 | awk '{ print $5 }' | head -n1) -if [[ ! "$VERDACCIO_PID" =~ '^[1-9][0-9]+$' ]] -then - new_section "Setting up verdaccio" - verdaccio -c ./.ci/verdaccio-config.yaml & - sleep 1 - VERDACCIO_PID=$(netstat -ano | grep 4873 | awk '{ print $5 }' | head -n1) # $! doesn't work on Windows -fi - -new_section "Packaging for NPM" -node scripts/package.js -new_section "Publishing to local NPM" -cd _esy-package/readline-8.1 -npm publish --registry $REGISTRY_URL -# npm still looks for auth token See https://github.com/verdaccio/verdaccio/issues/212#issuecomment-308578500 - -cd ../../esy-test/ -export ESY__PREFIX=$HOME/_esy_test/prefix -rm -rf $ESY__PREFIX -mkdir -p $ESY__PREFIX -esy i --npm-registry $REGISTRY_URL -esy b -rm -rf esy.lock -cd ../ - -case $(uname) in - CYGWIN*|MINGW*) - taskkill.exe -pid "$VERDACCIO_PID" -F - ;; - *) - kill "$VERDACCIO_PID" -esac -rm -rf .ci/verdaccio-storage diff --git a/.ci/verdaccio-config.yaml b/.ci/verdaccio-config.yaml deleted file mode 100644 index 4cebb69..0000000 --- a/.ci/verdaccio-config.yaml +++ /dev/null @@ -1,87 +0,0 @@ -# -# This is the default config file. It allows all users to do anything, -# so don't use it on production systems. -# -# Look here for more config file examples: -# https://github.com/verdaccio/verdaccio/tree/master/conf -# - -# path to a directory with all packages -storage: ./verdaccio-storage -# path to a directory with plugins to include -plugins: ./plugins - -web: - title: Verdaccio - # comment out to disable gravatar support - # gravatar: false - # by default packages are ordercer ascendant (asc|desc) - # sort_packages: asc - # convert your UI to the dark side - # darkMode: true - -# translate your registry, api i18n not available yet -# i18n: -# list of the available translations https://github.com/verdaccio/ui/tree/master/i18n/translations -# web: en-US - -# auth: -# htpasswd: -# file: ./htpasswd - # Maximum amount of users allowed to register, defaults to "+inf". - # You can set this to -1 to disable registration. - # max_users: 1000 - -# a list of other known repositories we can talk to -uplinks: - npmjs: - url: https://registry.npmjs.org/ - -packages: - '@*/*': - # scoped packages - access: $all - publish: $all - unpublish: $all - proxy: npmjs - - '**': - # allow all users (including non-authenticated users) to read and - # publish all packages - # - # you can specify usernames/groupnames (depending on your auth plugin) - # and three keywords: "$all", "$anonymous", "$authenticated" - access: $all - - # allow all known users to publish/publish packages - # (anyone can register by default, remember?) - publish: $all - unpublish: $all - - # if package is not available locally, proxy requests to 'npmjs' registry - proxy: npmjs - -# You can specify HTTP/1.1 server keep alive timeout in seconds for incoming connections. -# A value of 0 makes the http server behave similarly to Node.js versions prior to 8.0.0, which did not have a keep-alive timeout. -# WORKAROUND: Through given configuration you can workaround following issue https://github.com/verdaccio/verdaccio/issues/301. Set to 0 in case 60 is not enough. -server: - keepAliveTimeout: 60 - -middlewares: - audit: - enabled: true - -# log settings -logs: - - { type: stdout, format: pretty, level: http } - #- {type: file, path: verdaccio.log, level: info} -#experiments: -# # support for npm token command -# token: false -# # support for the new v1 search endpoint, functional by incomplete read more on ticket 1732 -# search: false - -# This affect the web and api (not developed yet) -#i18n: -#web: en-US -max_body_size: 1000mb diff --git a/.ci/yarnrc b/.ci/yarnrc deleted file mode 100644 index 92d9d63..0000000 --- a/.ci/yarnrc +++ /dev/null @@ -1,8 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -email foo@bar.com -username foo -_password qweqwe -password qweqwe \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..4f7aa34 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +*.sh text=auto eol=lf + diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 6ecb0ac..d48037d 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -1,37 +1,38 @@ -name: Build and test the esy package - -on: - - push - -jobs: - build: - strategy: - fail-fast: false - matrix: - os: - - macos-latest - - ubuntu-latest - # - windows-latest - - runs-on: ${{ matrix.os }} - - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Use Node.js 14.x - uses: actions/setup-node@v1 - with: - node-version: 14.x - - - name: Install esy - run: npm install -g @esy-nightly/esy verdaccio - - - name: Run end-to-end tests on the package - run: bash ./.ci/steps.sh - shell: bash - - - uses: actions/upload-artifact@v2 - with: - name: release - path: package.tar.gz +name: Build and test the esy package + +on: + - push + +jobs: + build: + strategy: + fail-fast: false + matrix: + os: + - macos-13 + - macos-latest + - ubuntu-latest + - windows-latest + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Use Node.js + uses: actions/setup-node@v3 + + - name: Install esy, verdaccio and esy-package + run: npm install -g esy verdaccio esy-package@latest # to be reverted to dev + + - name: Run end-to-end tests on the package + run: DEBUG=bale*,verdaccio* esy-package + shell: bash + env: + SHELL: "bash.exe" # HACK!! For some weird reason, $SHELL in Github actions' Windows' bash shell doesn't set this environment variable. We rely on it to figure if path normalisation is necessary on Gitbash Windows + + - uses: actions/upload-artifact@v3 + with: + name: release + path: package.tar.gz diff --git a/.npmrc b/.npmrc deleted file mode 100644 index 79a5aba..0000000 --- a/.npmrc +++ /dev/null @@ -1 +0,0 @@ -//localhost:4873/:_authToken="+vVrDzq8gudTDDEoQOS+PQ==" \ No newline at end of file diff --git a/esy-test/package.json b/esy-test/package.json index 2742e07..7387f4e 100644 --- a/esy-test/package.json +++ b/esy-test/package.json @@ -1,12 +1,12 @@ { "esy": { - "build": "pkg-config --libs gmp" + "buildsInSource": true, + "build": [ + "#{os == 'windows' ? 'x86_64-w64-mingw32-':''}gcc test.c -I#{esy-gmp.install / 'include'} -L#{esy-gmp.lib} -lgmp -o test", + "./test" + ] }, "dependencies": { - "yarn-pkg-config": "*", - "esy-gmp": "6.2.1000" - }, - "resolutions": { - "yarn-pkg-config": "esy-ocaml/yarn-pkg-config#9293b15f9f0e3dcac6f86ebb1e09a2fa766289ba" + "esy-gmp": "6.3.0" } } diff --git a/esy-test/test.c b/esy-test/test.c new file mode 100644 index 0000000..0b3688a --- /dev/null +++ b/esy-test/test.c @@ -0,0 +1,12 @@ +#include +#include + +int main() { + mpz_t i, j, k; + mpz_init_set_str (i, "1a", 16); + mpz_init (j); + mpz_init (k); + mpz_sqrtrem (j, k, i); + if (mpz_get_si (j) != 5 || mpz_get_si (k) != 1) abort(); + return 0; +} diff --git a/esy.json b/esy.json index 77d627e..9430fec 100644 --- a/esy.json +++ b/esy.json @@ -1,16 +1,36 @@ { "name": "esy-gmp", - "version": "6.2.1000", + "version": "6.3.0", "description": "GMP packaged for esy", - "source": "https://gmplib.org/download/gmp/gmp-6.2.1.tar.xz#sha256:fd4829912cddd12f84181c3451cc752be224643e87fac497b69edddadc49b4f2", + "source": "https://ftp.gnu.org/gnu/gmp/gmp-6.3.0.tar.xz#sha256:a3c2b80201b89e68616f4ad30bc66aee4927c3ce50e33929ca819d5c43538898", "override": { "buildEnv": {}, - "build": ["sh ./esy-configure.sh", "make"], + "build": ["bash ./esy-configure.sh", "make -j8"], "install": "make install", "buildsInSource": true, "exportedEnv": { + "LDFLAGS": { + "scope": "global", + "val": "-L#{self.lib} -lgmp" + }, + "CPPFLAGS": { + "scope": "global", + "val": "-I#{self.install / 'include'}" + }, + "LD_LIBRARY_PATH": { + "scope": "global", + "val": "#{self.lib}:$LD_LIBRARY_PATH" + }, + "LIBRARY_PATH": { + "scope": "global", + "val": "#{self.lib}:$LIBRARY_PATH" + }, + "CPATH": { + "scope": "global", + "val": "#{self.install / 'include'}:$CPATH" + }, "PKG_CONFIG_PATH": { - "val": "#{self.lib / 'pkgconfig'}", + "val": "#{self.lib / 'pkgconfig' : $PKG_CONFIG_PATH}", "scope": "global" } }, diff --git a/files/esy-configure.sh b/files/esy-configure.sh index c25c893..2af5732 100644 --- a/files/esy-configure.sh +++ b/files/esy-configure.sh @@ -1,17 +1,7 @@ -#! /bin/sh +#! /bin/bash CONFIGURE_FLAGS=("--prefix=$cur__install" "--enable-cxx" "--with-pic") -UNAME_M=$(uname -m) - -ARCH="${UNAME_M%%*( )}" -OS=$(uname -s) - -if [ "$OS" == "Darwin" ] -then - CONFIGURE_FLAGS+=("--build=${ARCH}-apple-darwin$(uname -r)") -fi - case "$(uname -s)" in CYGWIN*|MINGW32*|MSYS*) CONFIGURE_FLAGS+=("--host x86_64-w64-mingw32") @@ -22,4 +12,6 @@ case "$(uname -s)" in esac CONFIGURE_ARGS=$(printf '%s ' "${CONFIGURE_FLAGS[@]}") +export PATH="/usr/x86_64-w64-mingw32/sys-root/mingw/bin:$PATH" # because mingw g++ fails the ./configure tests around certain flags +find ./ -exec touch -t 200905010101 {} + # because, other makeinfo is being looked up, which we'd like to avoid installing ./configure $CONFIGURE_ARGS diff --git a/scripts/package.js b/scripts/package.js deleted file mode 100644 index f3945cf..0000000 --- a/scripts/package.js +++ /dev/null @@ -1,240 +0,0 @@ -/* - * For transparency reasons, this is a script and not a native executable - */ - -const fs = require("fs"); -const path = require("path"); -const os = require("os"); -const crypto = require("crypto"); -const url = require("url"); -const cp = require("child_process"); - -function mkdirpSync(pathStr) { - if (fs.existsSync(pathStr)) { - return; - } else { - mkdirpSync(path.dirname(pathStr)); - fs.mkdirSync(pathStr); - } -} - -function copy(src, dest) { - let srcStat = fs.statSync(src); - if (srcStat.isDirectory()) { - if (!fs.existsSync(dest)) { - mkdirpSync(dest); - } - let srcEntries = fs.readdirSync(src); - for (srcEntry of srcEntries) { - copy(path.join(src, srcEntry), path.join(dest, srcEntry)); - } - } else { - fs.writeFileSync(dest, fs.readFileSync(src)); - } -} - -function fetch(urlStr, urlObj, pathStr, callback) { - let httpm; - switch (urlObj.protocol) { - case "http:": - httpm = require("http"); - break; - case "https:": - httpm = require("https"); - break; - default: - throw `Unrecognised protocol in provided url: ${urlStr}`; - } - httpm.get(urlObj, function (response) { - if (response.statusCode == 302) { - let urlStr = response.headers.location; - fetch(urlStr, url.parse(urlStr), pathStr, callback); - } else { - response.pipe(fs.createWriteStream(pathStr)).on("finish", function () { - callback(pathStr); - }); - } - }); -} - -function uncompress(pathStr, pkgPath) { - pathStr = normalisePath(pathStr); - switch (path.extname(pathStr)) { - case ".tgz": - case ".gz": - tar(pathStr, pkgPath, true); - break; - case ".xz": - tar(pathStr, pkgPath); - break; - case ".zip": - unzip(pathStr, pkgPath); - break; - } -} - -function computeChecksum(filePath, algo) { - return new Promise((resolve, reject) => { - let stream = fs.createReadStream(filePath).pipe(crypto.createHash(algo)); - let buf = ""; - stream.on("data", (chunk) => { - buf += chunk.toString("hex"); - }); - stream.on("end", () => { - resolve(buf); - }); - }); -} - -function normalisePath(path) { - let platform; - try { - platform = cp.execSync("uname").toString().trim(); - } catch (e) { - console.log(e); - platform = "Windows"; - } - - if (/cygwin/i.test(platform) || /mingw/i.test(platform)) { - path = cp.execSync(`cygpath -u ${path}`).toString().trim(); - } - - return path; -} - -function download(urlStrWithChecksum, pkgPath) { - return new Promise(function (resolve, reject) { - let [urlStr, checksum] = urlStrWithChecksum.split("#"); - if (!urlStr) { - reject(`No url in ${urlStr}`); - } else if (!checksum) { - reject(`No checksum in ${urlStr}`); - } - - let urlObj = url.parse(urlStr); - let filename = path.basename(urlObj.path); - let tmpDownloadedPath = path.join(os.tmpdir(), "esy-package-" + filename); - - let protoParts = urlObj.protocol.split("+"); - - if (protoParts.length > 2) { - reject("Unrecognised protocol " + urlObj.protocol); - } else if (protoParts.length === 2) { - let [a, b] = protoParts; - if (a === "git") { - let gitUrl = url.format({ ...urlObj, protocol: b }); - - if (fs.existsSync(tmpDownloadedPath)) { - reject("TODO: run rm -rf"); - } else { - let destDir = path.join(pkgPath, "git-source"); // TODO: not network resilient. Any interruptions will corrupt the path - cp.execSync(`git clone ${gitUrl} ${destDir}`); - let commitHash = checksum; - cp.execSync(`git -C ${destDir} checkout ${commitHash}`); - resolve(destDir); - } - } else { - reject("Unrecognised protocol " + urlObj.protocol); - } - } else { - let [algo, hashStr] = checksum.split(":"); - if (!hashStr) { - hashStr = algo; - algo = "sha1"; - } - - if (fs.existsSync(tmpDownloadedPath)) { - computeChecksum(tmpDownloadedPath, algo).then((checksum) => { - if (hashStr == checksum) { - uncompress(tmpDownloadedPath, pkgPath); - resolve(tmpDownloadedPath); - } else { - fetch(urlStr, urlObj, tmpDownloadedPath, () => - computeChecksum(tmpDownloadedPath, algo).then((checksum) => { - if (hashStr == checksum) { - uncompress(tmpDownloadedPath, pkgPath); - resolve(tmpDownloadedPath); - } else { - reject(`Checksum error: expected ${hashStr} got ${checksum}`); - } - }) - ); - } - }); - } else { - fetch(urlStr, urlObj, tmpDownloadedPath, () => - computeChecksum(tmpDownloadedPath, algo).then((checksum) => { - if (hashStr == checksum) { - uncompress(tmpDownloadedPath, pkgPath); - resolve(tmpDownloadedPath); - } else { - reject(`Checksum error: expected ${hashStr} got ${checksum}`); - } - }) - ); - } - } - }); -} - -let cwd = process.argv[2] || process.cwd(); -let manifest = require(path.join(cwd, "esy.json")); - -let { - source, - name, - version, - description, - override: { build, install, buildsInSource, dependencies }, -} = manifest; - -function tar(filePath, destDir, gzip) { - cp.execSync(`tar -x${gzip ? "z" : ""}f ${filePath} -C ${destDir}`, { - stdio: "inherit", - }); -} - -function unzip(filePath, destDir) { - cp.execSync(`unzip -o ${filePath} -d ${destDir}`); -} - -let esyPackageDir = path.join(cwd, "_esy-package"); -mkdirpSync(esyPackageDir); -let pkgPath = esyPackageDir; -download(source, pkgPath) - .then(() => { - let entries = fs.readdirSync(pkgPath); - if (entries.length > 1) { - // Extracted tarball is not wrapped by a single root directory. The entire `pkgPath` must be considered as package root - return pkgPath; - } else { - return path.join(pkgPath, entries[0]); - } - }) - .then((pkgPath) => { - function filterComments(o = {}) { - return Object.keys(o) - .filter((k) => !k.startsWith("//")) - .reduce((acc, k) => { - acc[k] = o[k]; - return acc; - }, {}); - } - let buildEnv = filterComments(manifest.override.buildEnv); - let exportedEnv = filterComments(manifest.override.exportedEnv); - let esy = { buildsInSource, build, install, buildEnv, exportedEnv }; - let patchFilesPath = path.join(cwd, "files"); - if (fs.existsSync(patchFilesPath)) { - copy(patchFilesPath, pkgPath); - } - fs.writeFileSync( - path.join(pkgPath, "package.json"), - JSON.stringify({ name, version, description, esy, dependencies }, null, 2) - ); - fs.writeFileSync( - path.join(pkgPath, ".npmignore"), - ` -_esy -` - ); - });