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

Write synchronous .yo-rc.json #740

Closed
f-liva opened this issue Mar 24, 2022 · 2 comments
Closed

Write synchronous .yo-rc.json #740

f-liva opened this issue Mar 24, 2022 · 2 comments

Comments

@f-liva
Copy link

f-liva commented Mar 24, 2022

My install method contains many spawn commands that may break during their execution.
Interruption of even one of them, due to an error or a major cause, will result in having to restart the generator by re-executing all previously executed spawn commands.
To avoid this, I thought of using this.config.set and this.config.get to save the state of correct execution of each spawn command and to recover this state in a subsequent execution of the generator, which at that point will know which spawn command to relaunch and which not because they have already been executed.

The problem, is that Yeoman generates the .yo-rc.json file only at the end of everything, making the approach I had thought useless. Running this.config.set or this.config.save over and over again does not result in a write (at that precise moment) to the configuration file, and therefore if the generator stops due to a spawn command error, nothing will be written to the .yo-rc.json file.

How can I solve this issue and force Yeoman to update the .yo-rc.json file when I say so and when I need it, without waiting for the completion of the generator execution?

See code example here. See comments on spawn commands

module.exports = class extends Generator {

    async prompting () {
        this.answers = await this.prompt([
            ...
        ])
    }

    writing () {
        ...
    }

    install () {
        if (!this.config.get('foo-executed')) {
            this.spawnCommandSync('foo-command')

            this.config.set('foo-executed', true) // This will not be saved to .yo-rc.json because...
        }

        // I need at this point the .yo-rc.json file has already been saved and contains foo-executed: true

        if (!this.config.get('bar-executed')) {
            this.spawnCommandSync('bar-command') // ... this will cause an error and stop the execution of the generator!

            this.config.set('bar-executed', true)
        }
    }

    end () {
        this.log('Have a nice day')
    }
}
@JoshuaKGoldberg
Copy link

🤔 I don't think this is what the .yo-rc file is meant for. As I understand it, that config file is meant to store persistent configurations across runs, not temporary data within a run.

I think what you probably want is a separate system for configs. I don't know that there's one most popular system. Quick searching found ...

But I'm not confident I've interpreted everything correctly. Tagging @UlisesGascon in: WDYT?

@mshima
Copy link
Member

mshima commented Apr 10, 2025

.yo-rc.json file keeps the state of the generation process like an transaction.
To be consistent with in disc files it will be written to disc together with the rest of files.
But we don't provide rollback of written files in case of errors in the middle of commit process.

If there is interest in synchronous .yo-rc.json commit you can use mem-fs events (non verified poc):

this.env.sharedFs.on('change', filePath => {
  if (filePath.endsWith('.yo-rc.json') {
    writeSync(filePath, this.env.sharedFs.get(filePath).contents);
  }
});

@mshima mshima closed this as completed Apr 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants