3 ms·
It's quite common to use scripts to generate code. My experience is that this is best kept as standalone scripts executed only when needed with the resulting g
by mytailorisrich 3y ago
It's quite common to use scripts to generate code.
My experience is that this is best kept as standalone scripts executed only when needed with the resulting generated code committed to source control (scripts are also of course under source control).
Code generated on the fly during the build process and never committed to source control is a pain, IMHO.
- planede 3y agoCommitted generated code can also be a pain. Now you invite manual changes to the generated code, which is probably a pain to maintain if you also want to maintain and reuse the generation script in parallel.
- mytailorisrich 3y agoNo, committed generated code does not invite manual changes. This should obviously be prevented and part of your standard software development process and guidelines. That's why autogenerated source files usually have a big warning in their headers, and you would kill any manual changes in code review with a telling off of the dev, anyway. Very simple to enforce and maintain. At least you have the whole compiled code base under source control, you can guarantee that you have access to the exact source files used for previous builds, and debugging is generally easier. You have the generated code subject to your normal code review process and everyone can easily inspect it. You also have a separation of concerns and source files, embedding Python scripts into your, say, C files is conplexifying everything for little, if any, benefits.
- simonw 3y agoYou can use the "cog --check" command in CI to prevent this from happening. On every commit, your tests can rerun the code generator and confirm that it makes no changes to the code. If it does, the tests fail. That way if anyone manually edits generated code (which they should not be doing) it will be caught by CI.
- tasuki 3y agoI really don't want any generated code committed to my source control! By its nature, this generated code is repetitive. People will go and manually change a thing in the generated code in ten thousand places. Then, when I have to make a change, I have to: 1. Either manually change my thing in ten thousand places (which is a pain) 2. Or use the code generation for my change and also make sure I don't break the previous peoples' manual changes. I don't think this is possible. > Code generated on the fly during the build process and never committed to source control is a pain, IMHO. Maybe a pain to debug, but much less of a pain to maintain/change!
- mytailorisrich 3y agoWhy would you allow manual changes to autogenerated code? Isn't the whole point not to manually change it? Autogenerated code is not a pain to maintain and change as long as you have a sensible process...
- tasuki 3y agoHow do you prevent people from manually changing any code which is checked in? Have a CI step run the auto-generation and fail if there's a diff?
- nedbat 3y agoCog can add a checksum to the generated output: https://cog.readthedocs.io/en/latest/running.html#checksummed-output https://cog.readthedocs.io/en/latest/running.html#checksumme...
- mytailorisrich 3y agoCI step, code review. Ideally those steps gate submission to master repo. But even just a big telling-off and revert after the fact (as said those files should have a big warning as header so there is no excuse) if those good practices are not followed as commits should at the very least be monitored manually, and they are obviously visible, anyway.
- deleted 3y ago
- demurgos 3y agoI see some replies pushing back against committing generating source code; but I generally agree with you. There's a principle to avoid committing generated code, but sometimes it makes sense. A few examples I had recently: - Parts of a website are generated by converting from Markdown to HTML using a Rust script. The Markdown side rarely changes, by committing the generated HTML, it allows designers to clone the website and work on it without having to install a Rust toolchain. - API Clients/type declarations for a given language are generated. Having them committed allows to send GitHub/GitLab links to the source when discussing code; it also allows to view a diff of the output when updating the code generator. - Flash files used for an emulator test suite are generated, but also committed; since setting up a compiler locally is pretty hard (similar to the first point) So my use cases mostly arise when I need to reduce friction for people joining. For more restricted projects, I avoid committing generated code; but I still tend to reach to code generation over simpler preprocessors occasionally. The main reason is that dumping the generated code to a file instead of doing it all in memory provides better support for IDEs and debuggers. It depends on the language of course, in my case it was Haxe where you get way better support with code gen rather than built-in macros. Of course there are some downsides such as keeping track of dependencies/refreshing appropriately and it requires more tooling; but sometimes it makes sense. Preventing people from editing generated code is a non-issue in practice: there are warnings indicating that the code was generated, where it was generated from, and how to generate it yourself if needed.