Changeset 1551


Ignore:
Timestamp:
Nov 3, 2012, 6:03:36 AM (11 years ago)
Author:
Peter Johansson
Message:

closes #518. svncopyright now works on characters rather than lines. That implies old cache files are obsolete and will be ignored from this revision.

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/NEWS

    r1523 r1551  
    44
    55Version 0.11 (released NOT YET)
     6  - svncopyright now works on characters rather than lines (ticket #518)
    67
    78  A complete list of closed tickets can be found here [[br]]
  • trunk/doc/readme.txt

    r1373 r1551  
    33Copyright (C) 2005 Jari Häkkinen
    44Copyright (C) 2006, 2007, 2008 Jari Häkkinen, Peter Johansson
    5 Copyright (C) 2009, 2010, 2011 Peter Johansson
     5Copyright (C) 2009, 2010, 2011, 2012 Peter Johansson
    66
    77This file is part of svndigest, http://dev.thep.lu.se/svndigest
     
    202202svncopyright updates the copyright statement in subversion controlled
    203203files. The program detects the copyright statement and replaces it
    204 with a copyright statement calculated from repository statistics. 
     204with a copyright statement calculated from repository statistics.
    205205
    206206The copyright statement is detected as the first line containing the
     
    211211statement block is replaced with a new copyright statement generated
    212212from analyzing `svn blame output`. An author is considered to have
    213 copyright of the file if (s)he has added a line of code or comment
     213copyright of the file if (s)he has added a non-whitespace character
    214214(excluding copyright statements). For an example of the format of the
    215215generated copyright statement, please have a look at the top of this
    216 file. 
     216file.
    217217
    218218By default the `svn user name` of the author is printed in the
  • trunk/lib/CopyrightStats.cc

    r1515 r1551  
    2525#include "Configuration.h"
    2626#include "LineTypeParser.h"
    27 #include "SVNblame.h"
     27#include "SkipWhiteSpaceIterator.h"
    2828#include "SVNinfo.h"
    2929#include "SVNlog.h"
     30#include "SVNcat.h"
    3031#include "utility.h"
    3132
     
    9293    std::string line;
    9394    getline(is, line);
    94     if (line!="SVNCOPYRIGHT CACHE VERSION 1")
     95    if (line!="SVNCOPYRIGHT CACHE VERSION 2")
    9596      return 0;
    9697    getline(is, line);
     
    149150    assert(commit->revision() >= first_rev);
    150151    log_iterator end = log.commits().end();
     152
    151153    // loop over all commits
    152154    for ( ; commit!=end; ++commit) {
     
    170172        continue;
    171173
    172       SVNblame svn_blame(path_, commit->revision());
    173       LineTypeParser parser(path_);
    174 
    175       // loop over lines
    176       while (svn_blame.valid()) {
    177         int lt = parser.parse(svn_blame.line());
    178         if ((lt==LineTypeParser::code || lt==LineTypeParser::comment) &&
    179             svn_blame.revision()==commit->revision()) {
    180           year2user_[yearrev->first].insert(name);
    181           break;
    182         }
    183         svn_blame.next_line();
    184       }
    185     }
    186   }
     174      SVNcat previous(path_, commit->revision()-1);
     175      std::string previous_content;
     176      remove_copyright_lines(previous.str(), previous_content);
     177
     178      SVNcat current(path_, commit->revision());
     179      std::string current_content;
     180      remove_copyright_lines(current.str(), current_content);
     181
     182      // if any character added between previous and current add
     183      // author to set of authors
     184      if (!subseq(current_content, previous_content)) {
     185        year2user_[yearrev->first].insert(name);
     186      }
     187    }
     188  }
     189
     190
     191  void CopyrightStats::remove_copyright_lines(const std::string& src,
     192                                              std::string& result) const
     193  {
     194    LineTypeParser ltp(path_);
     195    std::istringstream is(src);
     196    std::string line;
     197    while (getline(is, line)) {
     198      if (ltp.parse(line) != LineTypeParser::copyright) {
     199        result += line;
     200        result += '\n';
     201      }
     202    }
     203  }
    187204
    188205
     
    190207  {
    191208    year2user_.clear();
     209  }
     210
     211
     212  bool
     213  CopyrightStats::subseq(const std::string& sub, const std::string& seq) const
     214  {
     215    SkipWhiteSpaceIterator iter1(sub.begin(), sub.end());
     216    SkipWhiteSpaceIterator end1(sub.end(), sub.end());
     217    SkipWhiteSpaceIterator iter2(seq.begin(), seq.end());
     218    SkipWhiteSpaceIterator end2(seq.end(), seq.end());
     219
     220    for ( ; iter1!=end1; ++iter1) {
     221      iter2 = std::find(iter2, end2, *iter1);
     222      if (iter2 == end2) {
     223        return false;
     224      }
     225    }
     226    return true;
    192227  }
    193228
     
    199234    assert(os.good());
    200235
    201     os << "SVNCOPYRIGHT CACHE VERSION 1\n";
     236    os << "SVNCOPYRIGHT CACHE VERSION 2\n";
    202237    os << config_ << "\n";
    203238    os << year2user_.size() << "\n";
  • trunk/lib/CopyrightStats.h

    r1453 r1551  
    6060
    6161    void parse(svn_revnum_t rev, const std::map<int, svn_revnum_t>& year2rev);
     62    void remove_copyright_lines(const std::string& src,
     63                                std::string& result) const;
    6264    void reset(void);
     65
     66    /**
     67       sub is subsequence of seq if sub can be created from seq by
     68       removing element in seq.
     69
     70       \return true if \a sub is subsequence of \a seq
     71     */
     72    bool subseq(const std::string& sub, const std::string& seq) const;
     73
    6374    void write_cache(void);
    6475
  • trunk/test/copyright.cc

    r1515 r1551  
    6666    suite.add(false);
    6767  }
    68   suite.out() << "File contains 1 copyright line.\n"; 
     68  suite.out() << "File contains 1 copyright line.\n";
    6969
    70   // warn about missing Copyright statement only in verbose mode
    71   if (suite.verbose()){
    72     std::stringstream ss;
    73     ss << "[copyright]\n"
    74        << "missing-copyright-warning=yes\n"
    75        << "[copyright-alias]\n"
    76        << "jari = jh\n"
    77        << "peter = pj\n";
    78     Configuration& config = Configuration::instance();
    79     config.load(ss);
    80   }
     70  std::stringstream ss;
     71  ss << "[copyright]\n"
     72     << "missing-copyright-warning=yes\n"
     73     << "[copyright-alias]\n"
     74     << "jari = jh\n"
     75     << "peter = pj\n";
     76  Configuration& config = Configuration::instance();
     77  config.load(ss);
    8178
    8279  suite.out() << "Create SVN instance" << std::endl;
     
    9087  suite.out() << "Create File object" << std::endl;
    9188  File file(0,filename,"");
    92  
    93   update_copyright(file, suite.verbose(), false);
     89
     90  update_copyright(file, true, true);
    9491
    9592  is.open(filename.c_str());
     
    10097  std::vector<std::string> copyright_correct;
    10198  copyright_correct.push_back("Copyright (C) 2006 jh");
    102   copyright_correct.push_back("Copyright (C) 2007, 2008 pj");
     99  copyright_correct.push_back("Copyright (C) 2008 pj");
    103100  if (copyrights.size()!=copyright_correct.size()) {
    104101    suite.add(false);
  • trunk/test/copyright_cache_test.sh

    r1532 r1551  
    4343test -s stderr && exit_fail
    4444test -r $cache_file || exit_fail
     45cat $cache_file
    4546# check that we cache user name not alias
    4647grep peter $cache_file || exit_fail
  • trunk/test/ignore_revs_test.sh

    r1525 r1551  
    3131cat >> config << _EOF
    3232[svn-props]
    33 README = svncopyright:ignore=$ignore
     33Node.h = svncopyright:ignore=$ignore
    3434_EOF
    3535cat config
     
    3838}
    3939
     40# log for AUTHORS
     41# r4  jari  2006
     42# r21 jari  2006
     43# r22 jari  2006
     44# r23 jari  2006
     45# r41 peter 2007
     46# r42 peter 2007 only updated copyright
     47# r44 peter 2007 only copyright
     48# r47 peter 2007 only copyright
     49# r67 peter 2009 only copyright
     50
    4051# no ignore
    4152SVNCOPYRIGHT_run 0 -v --ignore-cache --root toy_project
    42 $GREP "2006 Jari" toy_project/README || exit_fail
    43 $GREP "2007, 2008 Peter" toy_project/README || exit_fail
     53$GREP "2006 Jari" toy_project/lib/Node.h || exit_fail
     54$GREP "2007 Peter" toy_project/lib/Node.h || exit_fail
    4455
    45 run_svncopyright_with_ignore 42
    46 $GREP "2006 Jari" toy_project/README || exit_fail
    47 $GREP "Copyright (C) 2008 Peter" toy_project/README || exit_fail
     56run_svncopyright_with_ignore 21
     57$GREP "2006 Jari" toy_project/lib/Node.h || exit_fail
     58$GREP "2007 Peter" toy_project/lib/Node.h || exit_fail
    4859
    49 run_svncopyright_with_ignore "-42"
    50 $GREP "2006 Jari" toy_project/README && exit_fail
    51 $GREP "Copyright (C) 2008 Peter" toy_project/README || exit_fail
     60run_svncopyright_with_ignore "-30"
     61$GREP "2006 Jari" toy_project/lib/Node.h && exit_fail
     62$GREP "2007 Peter" toy_project/lib/Node.h || exit_fail
    5263
    53 run_svncopyright_with_ignore "41"
    54 $GREP "2006 Jari" toy_project/README || exit_fail
    55 $GREP "Copyright (C) 2007, 2008 Peter" toy_project/README || exit_fail
     64run_svncopyright_with_ignore "1"
     65$GREP "2006 Jari" toy_project/lib/Node.h || exit_fail
    5666
    57 run_svncopyright_with_ignore "1-34"
    58 $GREP "2006 Jari" toy_project/README || exit_fail
    59 $GREP "Copyright (C) 2007, 2008 Peter" toy_project/README || exit_fail
     67run_svncopyright_with_ignore "1-22"
     68$GREP "2006 Jari" toy_project/lib/Node.h || exit_fail
    6069
    61 run_svncopyright_with_ignore "1-35"
    62 $GREP "2006 Jari" toy_project/README && exit_fail
    63 $GREP "Copyright (C) 2007, 2008 Peter" toy_project/README || exit_fail
     70run_svncopyright_with_ignore "1-23"
     71$GREP "2006 Jari" toy_project/lib/Node.h && exit_fail
    6472
    65 run_svncopyright_with_ignore "42-"
    66 $GREP "2006 Jari" toy_project/README || exit_fail
    67 $GREP "Copyright (C) 2007, 2008 Peter" toy_project/README && exit_fail
    68 
    69 run_svncopyright_with_ignore "0-999"
    70 $GREP "Copyright (C)" toy_project/README || exit_fail
     73run_svncopyright_with_ignore "41-"
     74$GREP "2006 Jari" toy_project/lib/Node.h || exit_fail
     75$GREP "2007 Peter" toy_project/lib/Node.h && exit_fail
    7176
    7277# test that nonsense argument fails with grace
     
    7479cat > config << _EOF
    7580[svn-props]
    76 README = svncopyright:ignore=nonsense
     81Node.h = svncopyright:ignore=nonsense
    7782_EOF
    7883cat config
     
    8994peter = Peter
    9095[svn-props]
    91 README = svncopyright:ignore=0-35
     96Node.h = svncopyright:ignore=41
    9297toy_project = svncopyright:ignore=42
    9398_EOF
     
    95100# do not use --ignore-cache so we also test that cache is ignored automatically
    96101SVNCOPYRIGHT_run 0 -v --root toy_project --config-file=config
    97 $GREP "Copyright (C) 2006" toy_project/README && exit_fail
    98 $GREP "Copyright (C) 2008" toy_project/README || exit_fail
     102$GREP "Copyright (C) 2006" toy_project/lib/Node.h || exit_fail
     103$GREP "Copyright (C) 2007" toy_project/lib/Node.h && exit_fail
    99104
    100105exit_success
Note: See TracChangeset for help on using the changeset viewer.