source: trunk/lib/CopyrightStats.cc @ 1362

Last change on this file since 1362 was 1362, checked in by Peter Johansson, 10 years ago

svncopyright: avoid parsing commit if alias already have copyright for that year.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.0 KB
Line 
1// $Id: CopyrightStats.cc 1362 2011-06-04 15:42:45Z peter $
2
3/*
4  Copyright (C) 2011 Peter Johansson
5
6  This file is part of svndigest, http://dev.thep.lu.se/svndigest
7
8  svndigest is free software; you can redistribute it and/or modify it
9  under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12
13  svndigest is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with svndigest. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "CopyrightStats.h"
23#include "LineTypeParser.h"
24#include "SVNblame.h"
25#include "SVNinfo.h"
26#include "SVNlog.h"
27
28#include <subversion-1/svn_types.h>
29
30#include <cassert>
31#include <iostream>
32
33namespace theplu {
34namespace svndigest {
35
36  CopyrightStats::CopyrightStats(const std::string& path, bool ignore_cache,
37                                 std::map<std::string, Alias>& author2alias,
38                                 const std::map<int, svn_revnum_t>& year2rev)
39    : author2alias_(author2alias), path_(path)
40  {
41    init(ignore_cache, year2rev);
42  }
43
44
45  void CopyrightStats::init(bool ignore_cache, 
46                            const std::map<int, svn_revnum_t>& year2rev)
47  {
48    svn_revnum_t cache_rev = 0;
49    if (!ignore_cache)
50      cache_rev = load_cache("");
51    SVNinfo info(path_);
52    if (cache_rev >= info.last_changed_rev())
53      return;
54
55    // reset stats if cache was invalid
56    if (cache_rev == 0) 
57      reset();
58
59    parse(cache_rev+1, year2rev);
60    write_cache("");
61  }
62
63
64  svn_revnum_t CopyrightStats::load_cache(const std::string& filename)
65  {
66    // FIXME
67    return 0;
68  }
69
70
71  const std::map<int, std::set<Alias> > CopyrightStats::map(void) const
72  {
73    return year2alias_;
74  }
75
76
77  void CopyrightStats::parse(svn_revnum_t first_rev,
78                             const std::map<int, svn_revnum_t>& year2rev)
79  {
80    std::map<int, svn_revnum_t>::const_iterator yearrev=year2rev.begin();
81    SVNlog log(path_);
82    typedef SVNlog::container::const_iterator log_iterator;
83    log_iterator commit = log.commits().begin();
84    while (commit->revision() < first_rev)
85      ++commit;
86    assert(commit->revision() >= first_rev);
87    log_iterator end = log.commits().end();
88    // loop over all commits
89    for ( ; commit!=end; ++commit) {
90      // assure yearrev correspond to commit
91      while (yearrev->second < commit->revision()) {
92        ++yearrev;
93        assert(yearrev!=year2rev.end());
94      }
95      assert(yearrev!=year2rev.end());
96      assert(yearrev->second >= commit->revision());
97     
98      const std::string& name = commit->author();
99      // find username in map of aliases
100      std::map<std::string, Alias>::iterator alias = 
101        author2alias_.lower_bound(name);
102     
103      // if alias not found for author
104      if (alias == author2alias_.end() || alias->first!=name) {
105        std::cerr << "svncopyright: warning: no copyright alias found for `" 
106                  << name << "'\n";
107        // insert alias to avoid multiple warnings.
108        Alias a(name, author2alias_.size());
109        // FIXME use insert with hint
110        author2alias_[name] = a;
111        alias = author2alias_.find(name);
112      }
113      assert(alias!=author2alias_.end());
114     
115      // skip if alias already has copyright for this year.
116      std::map<int, std::set<Alias> >::const_iterator year_aliases = 
117        year2alias_.find(yearrev->first);
118      if (year_aliases!=year2alias_.end() 
119          && year_aliases->second.count(alias->second))
120        continue;
121     
122      SVNblame svn_blame(path_, commit->revision());
123      LineTypeParser parser(path_);
124
125      // loop over lines
126      while (svn_blame.valid()) {
127        int lt = parser.parse(svn_blame.line());
128        if ((lt==LineTypeParser::code || lt==LineTypeParser::comment) && 
129            svn_blame.revision()==commit->revision()) {
130          year2alias_[yearrev->first].insert(alias->second);
131          break;
132        }
133        svn_blame.next_line();
134      }
135    }
136  }
137
138
139  void CopyrightStats::reset(void)
140  {
141    year2alias_.clear();
142  }
143
144
145  void CopyrightStats::write_cache(const std::string& filename)
146  {
147    // FIXME
148  }
149
150}}
Note: See TracBrowser for help on using the repository browser.