• BillClintonIsTheMan (unregistered) in reply to Bananas
    Bananas:
    Does nobody place any value on being able to reproduce an older version of the executable from source control?

    Yes, as I read it this is more of a "blame" scenario.

    This dev team probably has little or no control over package distribution/delivery, and this is how they identify who sent what to where and when.

  • Tom (unregistered)

    TRWTF is not using reflection.

  • trtrwtf (unregistered) in reply to Chris L
    Chris L:
    As a not-a-programmer, I enjoy the discussions around the borderline WTFs more than anything on this site.

    WTF?????

  • qbolec (unregistered) in reply to PseudoBovine
    PseudoBovine:
    Kasper:
    Why does so many people want the version information to be in a separate file?

    Overzealous application of "good design principles".

    One practice that is normally a good thing is the separation of code and data. For example, if you ran across a program that had to be recompiled every time the host IP address changed, you'd rightly consider that a WTF. If there's information that can vary, it's almost always a good idea to factor that out into a configuration file, database or similar.

    That's the thought process. "The versioning information changes constantly. 'Best practices' would be to generalize it out into some sort of data storage system." - Again, usually this would be the right thing to do, but as you mention, the tight coupling between the version information and the actual code is a highly desired feature.

    In short, blindly following "best practices" isn't always for the best.

    but, but, build version changes precisely every time I compile a program, which keeps the build-to-change ratio at 1:1 level, so there is no benefit in separating the two. It's not like with the hardcoded host IP example where the ratio was more like 1:X :))

  • (cs)

    I guess everyone missed the part where it says the code does not compile until this file has been generated, and also the copy-pasting of the GenerateTagFile.java in all projects.

  • qbolec (unregistered) in reply to vic
    vic:
    I guess everyone missed the part where it says the code does not compile until this file has been generated, and also the copy-pasting of the GenerateTagFile.java in all projects.
    Actually I was more puzzled by the part where it says that the file was missing, but was also in the repo at the same time. So... was it missing, auto-generated, copy&pasted, or simply checked out?
  • jay (unregistered)

    Are there better ways to do it? Sure. But my standards for deciding if code is screwed up are:

    1. Does it work? This looks like it should. Pass.

    2. Is it reasonably understandable by other programmers? Looks like. Pass.

    3. Is it easy to maintain? Yes. Pass.

    4. Is it efficient? Not the best, but shouldn't be awful. Pass, maybe with some minor reservations.

    5. Is it robust, i.e. unlikely to fail? Might be some grounds for criticism here. Depending on how the build scripts are written, maybe a failed build would end up being mislabeled, and that could interfere with problem resolution. Maybe.

  • Kiwi (unregistered) in reply to Bananas
    Bananas:
    Does nobody place any value on being able to reproduce an older version of the executable from source control?
    Well the lead developer a few jobs ago refused to allow build dates/times in binaries for an embedded system so the historical rebuilds matched exactly. Unfortunately I'd felt that the additional info was better!
  • (cs) in reply to jay
    jay:
    Are there better ways to do it? Sure. But my standards for deciding if code is screwed up are:
    1. Does it work? This looks like it should. Pass.

    2. Is it reasonably understandable by other programmers? Looks like. Pass.

    3. Is it easy to maintain? Yes. Pass.

    4. Is it efficient? Not the best, but shouldn't be awful. Pass, maybe with some minor reservations.

    5. Is it robust, i.e. unlikely to fail? Might be some grounds for criticism here. Depending on how the build scripts are written, maybe a failed build would end up being mislabeled, and that could interfere with problem resolution. Maybe.

    2. Is it reasonably understandable by other programmers? Not really. I mean, who expects that sort of thing? See also #5.

    3. Is it easy to maintain? No! Fail! The "code generator" file and the associated build steps need to be copied to every project that uses that mechanism.

    Overall I rate this as mild or head-scratcher on the WTF scale.

  • -- (unregistered) in reply to Chris L
    Chris L:
    I enjoy the discussions around the borderline WTFs more than anything on this site. It seems to me that this type of article exposes philosophical WTFery rather than objectively bad code.

    Yeah I also like the ones that are questionably wtf-worthy. Mostly because I like reading the best practice discussion. I come to this site to possibly get a laugh and possibly learn something.

    CAPTCHA: ideo - a male idea

  • Kasper (unregistered) in reply to Kiwi
    Kiwi:
    Well the lead developer a few jobs ago refused to allow build dates/times in binaries for an embedded system so the historical rebuilds matched exactly. Unfortunately I'd felt that the additional info was better!
    I believe both points of view are valid. That does mean there are two conflicting goals and one need to relax one of the two goals just a little bit in order to resolve that conflict.

    The compromise I'd recommend is to have the automatic build system include relevant information including date in the targets that are build. However there then need to be a way to manually override the strings when you want to do a historic build and have an exact match. By default builds made outside of the automatic build system should be clearly labelled in a way that can distinguish development builds from release builds.

    Reproducible builds are good for certain validation of builds. For example you can have two different people look at the source being build and have both confirm that those executables are really build from that source.

  • Andrew (unregistered) in reply to qbolec

    I was thinking the same thing and that perhaps TRWTF was that the code wouldn't compile in this instance because it required the file that it would generate, if it successfully compiled. The workaround was a copy paste from elsewhere.

  • (cs)

    That's nothing. Wait until you meet GenerateGenerateTagFile.java

  • Evan (unregistered) in reply to Kasper
    Kasper:
    Why does so many people want the version information to be in a separate file? If the version information doesn't get included in the executable being build, I don't see what value it adds?

    If you distribute the version number and executable as separate files, it is just too easy to replace the executable but keep the version number the same.

    That was my reaction too. (Things like the Manifest file that would get built to the same JAR don't count as separate.)

    I can't claim to be an expert, but advice like version information lives in a non-executable file. If you want code modules that read that file for ease of use sounds like exactly the wrong thing to do to me.

  • Jared Kells (unregistered) in reply to Evan

    Doesn't seem like much of a WTF to me.

    For the naysayers what is the "correct" way to achieve this? I am genuinely curious.

    In .NET land I update AssemblyInfo.cs and the wix installer xml files on the build server using NANT before compilation.

    It's virtually the same thing.

  • Norman Diamond (unregistered) in reply to Callin
    Callin:
    That's nothing. Wait until you meet GenerateGenerateTagFile.java
    To build yacc, first code the grammar for yacc in yacc, and pass it through yacc. That produces a C program, which you pass through a C compiler that compiles C compilers to C programs that compile C, but first you need to compile the C program that compiles yacc to C, and then compile the resulting C to produce a program that compiles yacc.

    I don't think I can parse that.

  • (cs) in reply to Remy Porter
    Remy Porter:
    Because there should be a direct mapping of the code source control and the code in the build. By adding a code-generation step to the build process, you break that connection.
    Than you'd have to program in machine code. Because compilation and code-generation are the same thing. Remember, when compiling C, the preprocessor first generates preprocessed C, than the compiler writes out Assembly, still human-readable and human-writable language and than the assembler simply recodes that in the binary form. And early C++ and ObjC compilers compiled to C, so just inserting another step into that chain. And many other compilers just do the same; they generate another language normally used for programming and chain to it's respective compiler.
    Remy Porter:
    Even Microsoft's tools generate code pre-compilation so that you actually check the generated code into source control...
    Generated files should not be checked in version control. It does not matter whether they are "code". Assembly is also "code" and you don't consider checking that in.
  • (cs) in reply to Remy Porter
    Remy Porter:
    Because generating code is always superior to generating a human-readable data-file that can be parsed by stock code?
    Code is not human readable? Or not parsed by stock code (the compiler)?
  • (cs) in reply to jamesn
    jamesn:
    jay:
    Are there better ways to do it? Sure. But my standards for deciding if code is screwed up are:
    1. Does it work? This looks like it should. Pass.

    2. Is it reasonably understandable by other programmers? Looks like. Pass.

    3. Is it easy to maintain? Yes. Pass.

    4. Is it efficient? Not the best, but shouldn't be awful. Pass, maybe with some minor reservations.

    5. Is it robust, i.e. unlikely to fail? Might be some grounds for criticism here. Depending on how the build scripts are written, maybe a failed build would end up being mislabeled, and that could interfere with problem resolution. Maybe.

    2. Is it reasonably understandable by other programmers? Not really. I mean, who expects that sort of thing? See also #5.

    3. Is it easy to maintain? No! Fail! The "code generator" file and the associated build steps need to be copied to every project that uses that mechanism.

    Overall I rate this as mild or head-scratcher on the WTF scale.

    2. Is it reasonably understandable by other programmers? Not really. I mean, who expects that sort of thing? The fact that it is unexpected is not automatically an obstacle to understanding.

    3. Is it easy to maintain? Yes, but you must take some steps to ensure it is reliably easy to maintain. You have to first realise that the tag file generator is part of the build system, not part of the body of source code, and should be deployed and launched as such. The rest more or less follows from there.

    Oh, and remember Steve The Cynic's rule:

    90%[1] of what we do as programmers is communicating with other people.

    [1] It might not be exactly 90%, but the fraction is nevertheless close to 100%.

    We do this through email, talking, the source code, and even documentation. In the context of this discussion, STCrule means that we should have documents that describe all this. But that's another battle to fight.

  • Roland (unregistered)

    Our build process here generates a timstamp file that has the date, time and level information in the filename. The file is automatically included in the META-INF directory of every JAR, WAR or EAR file that is generated. That way, I can use 'jar' or 'zip' to get the version information from the command line, without first extracting a MANIFEST.MF and then looking at its content. Of course that is not the best solution if you want a '"-version" switch that prints the information, because then you'd want to know the filename in advance. For that, I'd probably prefer the MANIFEST.MF solution.

    (captcha: dolor - oh these pains...)

  • Gibbon1 (unregistered) in reply to Kiwi
    Kiwi:
    Bananas:
    Does nobody place any value on being able to reproduce an older version of the executable from source control?
    Well the lead developer a few jobs ago refused to allow build dates/times in binaries for an embedded system so the historical rebuilds matched exactly. Unfortunately I'd felt that the additional info was better!

    I wrote a utility that will read in a hex file and it's matching .elf file, then update the hexfile with list of symbols and strings, then write it out into a ./images directory. The modified hexfiles get checked in with the code. That allows you to add compile dates, revision numbers, and checksums without modifying source files and recompiling. One key thing is it does not reformat the hexfile, so you can use diff, to verify changes.

  • Svensson (unregistered) in reply to jamesn
    jamesn:
    2. Is it reasonably understandable by other programmers? Not really. I mean, who expects that sort of thing? See also #5.

    I don't know what your problem is, but I understood it easily. The biggest barrier to my understanding was that I was constantly looking for the WTF, but I never found it.

    3. Is it easy to maintain? No! Fail! The "code generator" file and the associated build steps need to be copied to every project that uses that mechanism.

    This is intentional. The code generator and associated steps are part of the project so that they do not result in an additional external dependency. You would explicitly customize it for each project as the project demands.

    Remember, the point of code re-use is to reduce work. Sometimes copying and making local mods really is better than using a library.

  • Evan (unregistered) in reply to Bulb
    Bulb:
    Generated files should not be checked in version control. It does not matter whether they are "code". Assembly is also "code" and you don't consider checking that in.
    99% of the time I agree with you, but I think there are very occasional exceptions if for some reason you think that the generation is "too hard." For instance, I've checked in files that are generated by an obscure third-party tool that probably no one would have if not for the project. Checking in the generated files makes it so you don't even need it for that project if you don't want it.

    I agree it's not an ideal solution, but I think the benefits of making the repository much more of a "one-stop-shop" for what you need to build makes it worth it. As with every rule (probably including this one :-)) there are no completely hard and fast rules.

  • Your Name (unregistered)

    "Brian’s brain break" broke my brain.

  • (cs)

    I'm confused: Why is a two-stage process even needed? Why does the build process not just build the TagFile class, instead of building a TagFileBuilder class which is then run to build the TagFile class? After all, to build the former, the build process had to have all the information needed to build the latter, the way it's building it.

    My brain hurt.

    I'm reminded of those nested Russian dolls. Does he need a builder to build the builder of the builder of the tag file? Hmmmm....

  • Lacho (unregistered)

    Y'know, I actually think that's pretty cool.

  • AN AMAZING CODER (unregistered) in reply to Alex
    Alex:
    This is a WTF people.. Using a .properties file included in the build would make a lot more sense.

    Code generation shouldn't be a part of your build unless it really is the only option.

    Properties files can be easily changed by humans.

    I'm guessing the point of this somewhat hacky build process is to have trustable build information available to the program at run time. Perhaps for some reporting and debugging purpose.

    I highly doubt your operating system's build information is stored in text somewhere.

    Either way, it's an eyebrow raiser at best, not a wtf.

  • AN AMAZING CODER (unregistered) in reply to Remy Porter
    Remy Porter:
    Because there should be a direct mapping of the code source control and the code in the build. By adding a code-generation step to the build process, you break that connection.

    Even Microsoft's tools generate code pre-compilation so that you actually check the generated code into source control. Now, in this case, someone was going back and checking these TagFile.java files back into source control, which is also pretty terrible, since they're going to be replaced every build, unless the process checks it back in automatically, and then you have this metadata file in source control that doesn't actually mean anything and argh.

    I oversee the build process in my company, and I would never want to see something like this.

    I agree that checking build-generated files into source code is a bad idea. But that's not what this article expresses. It expresses that generating code at build time is a bad idea without any context around the reason why.

    If a requirement was runtime availability of the build-time information that could not be easily modified by a malicious end-user, how would you accomplish it?

    You're going to say "you can use a hex editor on compiled classes anyway" or something like that, but that's outside of my definition of "easily".

  • Sultan (unregistered)

    Good job trying to reinvent XML.

  • Anon (unregistered) in reply to Steve The Cynic

    The javac compiler lacks a preprocessor, sure, but one could easily be added to the build scripts or other parts of the system if needed. For example, the following code works with CVS:

    private String revision = "$Revision: $";

    When CVS handles the file, it automatically fills that with the correct revision (and updates it again later). A similar system would be very easy to create and use with for example Ant scripts.

  • W. (unregistered) in reply to PseudoBovine
    PseudoBovine:
    For example, if you ran across a program that had to be recompiled every time the host IP address changed, you'd rightly consider that a WTF.

    cough oracle enterprise manager cough

  • Rich (unregistered)

    This kind of thing is practically encouraged in the .NET stack, although usually at design time rather than build time: T4 Templates.

  • instigator (unregistered) in reply to Remy Porter

    Oh boy, another file to keep up with during install.

Leave a comment on “One Version”

Log In or post as a guest

Replying to comment #:

« Return to Article