Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

awaiting svgexport.render resolves before output file is added to filesystem #97

Open
vegerot opened this issue Apr 5, 2021 · 1 comment

Comments

@vegerot
Copy link

vegerot commented Apr 5, 2021

I am trying to make a script to auto-generate icon files and send them to the right spots. This is what I have so far

#!/usr/bin/env node

import * as svgexport from 'svgexport';

import * as fs from 'fs';

import { exec as execCP } from 'child_process';

import { promisify } from 'util';

const exec = promisify(execCP)


const TARGETS = {
    'android-chrome': [192, 512, 457],
    'apple-touch-icon': [60, 76, 120, 152, 180],
    favicon: [16, 32],
    'msapplication-icon': [144],
    mstile: [150],
}

async function main() {
    const args = process.argv.slice(2);
    const src = args[0] || 'src/assets/Logo.svg'
    const dest = args[1] || 'public/assets/img/icons'
    const tmp = '/tmp/my_images'
    await renderImages(TARGETS, src, tmp)
    await moveFiles(TARGETS, tmp, dest)
}

async function renderImages(/** @type {Record<string, number[]>} */ targets, src,
    /** @type {string} */ dest) {

    if (!fs.existsSync(dest)) {
        fs.mkdirSync(dest)
    }

    const sizes = new Set(Object.values(targets).flat());

    const tasks = [];

    for (const size of sizes) {
        tasks.push(
            svgexport.render({
                input: [src],
                output: [[`${dest}/${size}.png`, `${size}:`]],
                cwd: process.cwd(),
            })
        )
    }
    return Promise.all(tasks);
}

function moveFiles(/** @type {Record<string, number[]>} */ targets, /** @type{string} */ src, dest) {

    const tasks = [];
    for (const [name, sizes] of Object.entries(targets)) {
        for (const size of sizes) {
            // non-portable
            tasks.push(
                exec(`/bin/cp ${src}/${size}.png ${dest}/${name}-${size}x${size}.png`)
            );
        }
    }

    return Promise.all(tasks);
}



main();

However, I am having trouble diagnosing a bug in my code. Whenever I add a new size to TARGETS, the first time I run this script I get

rocess]. Use emitter.setMaxListeners() to increase limit
node:child_process:326
      ex = new Error('Command failed: ' + cmd + '\n' + stderr);
           ^

Error: Command failed: /bin/cp /tmp/my_images/457.png public/img/icons//android-chrome-457x457.png
cp: /tmp/my_images/457.png: No such file or directory

    at ChildProcess.exithandler (node:child_process:326:12)
    at ChildProcess.emit (node:events:369:20)
    at maybeClose (node:internal/child_process:1067:16)
    at Socket.<anonymous> (node:internal/child_process:453:11)
    at Socket.emit (node:events:369:20)
    at Pipe.<anonymous> (node:net:665:12) {
  killed: false,
  code: 1,
  signal: null,
  cmd: '/bin/cp /tmp/my_images/457.png public/img/icons//android-chrome-457x457.png',
  stdout: '',
  stderr: 'cp: /tmp/my_images/457.png: No such file or directory\n'
}

But normally after running my script a second time it works without a hitch. I suspect the bug comes from svgexport.render resolving BEFORE the files have been moved to their output locations. Then moveFiles runs before the file exists, and thus the error. This would also explain why often times running it a second time works.

My question: Is this a bug in this library, or is there something I can do to my code to fix it?

Thanks

@vegerot
Copy link
Author

vegerot commented Apr 5, 2021

edit: nvm, 👇 error is just because svgexport adds event listeners for SIGINT, SIGTERM, and SIGHUP for each render job.

btw while I'm here, I also have another (probably unrelated) question. Even when the script is successful, my output looks like this

❯ ./tools/createIcons.mjs src/assets/My-Logo.svg public/img/icons/
(node:2404) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 exit listeners added to [process]. Use emitter.setMaxListeners() to increase limit
(Use `node --trace-warnings ...` to show where the warning was created)
(node:2404) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 SIGINT listeners added to [process]. Use emitter.setMaxListeners() to increase limit
(node:2404) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 SIGTERM listeners added to [process]. Use emitter.setMaxListeners() to increase limit
(node:2404) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 SIGHUP listeners added to [process]. Use emitter.setMaxListeners() to increase limit

Which seems odd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant