8

I am trying to create a pre-commit hook for git that edits the comments at the top of each of my .h and .m files. I would like to change the header comments added by x-code to include the app version and license information. This would be helpful when changing to a new version.

This is the text that is automatically inserted when I create a file in x-code:

//
//  myFile.h
//  myApp 
//
//  Created by Developer on 11/13/12.
//  Copyright (c) 2012 myCompany LLC. All rights reserved.
//

I would like the hook to change it to this:

/*

myFile.h
myApp
Version: 1.0

myApp is free software: you can redistribute it and/or modify it under the terms 
of the GNU General Public License as published by the Free Software Foundation,
either version 2 of the License, or (at your option) any later version.

myApp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
PURPOSE.  See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with myApp.
If not, see <http://www.gnu.org/licenses/>

Copyright 2012 myCompany. All rights reserved.


This notice may not be removed from this file.

*/

I was thinking that I would have a text file with the header text I want to change. Or detect when the app version number changes. When this file is updated with a new version number and git I do a git commit, then it will update all the other files with the new version and change any new files to have the correct header text. This seems like it might be useful.

jscs
  • 63,694
  • 13
  • 151
  • 195
Bryan Aneux
  • 328
  • 2
  • 9
  • 5
    Why does it need to be part of the `git commit` instead of being done as part of the build or some other script? – trojanfoe Jan 19 '13 at 22:25
  • Well, I suppose it would be better if was done with a build script, because then it could just use the app version from the app settings. I'm not tied to a git hook. I was thinking a hook might be better so it doesn't run every time I build, only when I commit to a production branch. I was just having difficutly with the script. – Bryan Aneux Jan 19 '13 at 22:45
  • The thing is, the version changes very infrequently, and when it does it needs to be consciously set by the developer (i.e. bugfix element increase, minor version increase or major version increase). So you probably want to create a script and run `set_version.sh X.Y.Z` as part of development. – trojanfoe Jan 19 '13 at 22:50
  • Related question; possible solution. http://stackoverflow.com/a/14107410/1301972 – Todd A. Jacobs Jan 20 '13 at 18:14

4 Answers4

2

Use smudge/clean filters (full chapter, linked "Keyword Expansion" most carefully)?

Lazy Badger
  • 94,711
  • 9
  • 78
  • 110
0

I've done similar before using the equivalent of a perl inplace-edit '-i' but using a perl script instead of just on the command line as the data is bigger.

I've done the following which should suite your needs, given some tweaking and testing :D.

The new source header is defined in the __DATA__ section of the perl script.

There's an illustration of how you can pass the VERSION and COPY_YEAR via environment variables.

It's a while since I've done some serious perl but it works on my testcases, it creates backups although I'd suggest you back up your files first.

I hope it helps in some way.

Example usage:

$ perl add_header *.h *.m 

Script:

use strict;
my $extension = '.orig';
local $/ = undef; # slurp
my $oldargv = undef;

my $replacement = <DATA>;
$replacement =~ s/{VERSION}/$ENV{VERSION} or '1.0.alpha'/e;
$replacement =~ s/{COPY_YEAR}/$ENV{COPY_YEAR} or '2013'/e;

LINE: while (<>) {
    if ( $ARGV ne $oldargv) {
        my $backup = undef;
        if ($extension !~ /\*/) {
            $backup = $ARGV . $extension;
        }
        else {
             ($backup = $extension) =~ s/\*/$ARGV/;
        }
        rename($ARGV, $backup);
        open(ARGVOUT, ">$ARGV");
        select(ARGVOUT);
        my $oldargv = $ARGV;
    }
    s!^//.*Copy.*?//$!$replacement!sm; # THE BUSINESS END.
}
continue {
    print;
}
select(STDOUT);
__DATA__
/**
 *  My New Header...
 *  Version info {VERSION} ]}
 *  made {COPY_YEAR}
 */
sotapme
  • 4,695
  • 2
  • 19
  • 20
0

I once did something similar but taking the version number from an annotated tag, which we created when the release version was finalised. The build process would;

  • Check out the code using a specified tag
  • Generate a version number from the tag (it was of the form "foo_version_1_2" -> 1.2), and write it to a file. This was so a template could pull it in for display in the app
  • Execute the build
  • Package it up

You could just as easily run script to populate the version number wherever you like during build time. I remember looking at smudge/clean filters, but it seemed an icky approach.

The above would be less useful if you're trying to populate a file-specific number, but then I'd question the value of that anyway since you don't version individual files in git. Why are you trying to do that?

Rory Hunter
  • 3,425
  • 1
  • 14
  • 16
0

Try to use pre-commit framework: https://pre-commit.com/

There are multiple scripts developed already for such process, that works with pre-commit

For example:

Stan Gabenov
  • 987
  • 9
  • 9