source: trunk/bin/Parameter.cc @ 719

Last change on this file since 719 was 719, checked in by Peter Johansson, 13 years ago

there are still some problems with the cache so it should be ignored. The cache was enabled accidently in r705. refs #338

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.1 KB
Line 
1// $Id: Parameter.cc 719 2008-12-01 01:20:41Z peter $
2
3/*
4  Copyright (C) 2006, 2007 Jari Häkkinen, Peter Johansson
5  Copyright (C) 2008 Peter Johansson
6
7  This file is part of svndigest, http://dev.thep.lu.se/svndigest
8
9  svndigest is free software; you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 3 of the License, or
12  (at your option) any later version.
13
14  svndigest is distributed in the hope that it will be useful, but
15  WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  General Public License for more details.
18
19  You should have received a copy of the GNU General Public License
20  along with svndigest. If not, see <http://www.gnu.org/licenses/>.
21*/
22
23#include "Parameter.h"
24
25#include "ColumnStream.h"
26#include "OptionArg.h"
27#include "OptionHelp.h"
28#include "OptionSwitch.h"
29#include "OptionVersion.h"
30#include "utility.h"
31#include <config.h> // this header file is created by configure
32
33#include <cassert>
34#include <cerrno>
35#include <cstddef>
36#include <fstream>
37#include <iostream>
38#include <sstream>
39#include <stdexcept>
40#include <string>
41#include <sys/stat.h>
42
43namespace theplu {
44namespace svndigest {
45
46  Parameter::Parameter( int argc, char *argv[])
47    : cmd_(
48     "Mandatory arguments to long options are mandatory for short options too.") 
49  {
50    init();
51    try {
52      cmd_.parse(argc, argv);
53    }
54    catch (cmd_error& e) {
55      std::cerr << e.what() << std::endl;
56      exit (-1);
57    }
58
59    // set default values
60    if (!root_->present())
61      root_->value(".");
62
63    if (!target_->present())
64      target_->value(".");
65
66    if (!config_file_->present())
67      config_file_->value(concatenate_path(root_->value(),".svndigest/config"));
68
69    // analyse arguments
70    analyse();
71  }
72
73
74  Parameter::~Parameter(void)
75  {
76    delete config_file_;
77    delete copyright_;
78    delete force_;
79    delete generate_config_;
80    delete help_;
81    delete ignore_cache_;
82    delete report_;
83    delete revisions_;
84    delete root_;
85    delete target_;
86    delete verbose_;
87    delete version_;
88  }
89
90
91  void Parameter::analyse(void)
92  {
93    std::string save_wd = pwd();
94
95    // check root but not if -g option given
96    if (!generate_config()) {
97      check_existence(root_->value());
98      check_readable(root_->value());
99      if (chdir(root_->value().c_str())) {
100        std::stringstream ss;
101        ss << "svndigest: cannot read `" << root_->value() << "': " 
102           << strerror(errno);
103        throw cmd_error(ss.str());
104      }
105      root_->value(pwd());
106      chdir(save_wd.c_str());
107
108      // check target (only if we write report)
109      if (report()) {
110        check_existence(target_->value());
111        check_readable(target_->value());
112        std::string base_root = file_name(root_->value());
113        std::string path = concatenate_path(target_->value(),base_root); 
114        if (access_rights(target_->value().c_str(), "w")) {
115          std::stringstream ss;
116          ss << "svndigest: cannot create directory `" << path
117             << "': " << strerror(errno);
118          throw cmd_error(ss.str());
119        }
120        if (node_exist(path) && !force()) {
121          std::stringstream ss;
122          ss << "svndigest: cannot create directory `" << path << "' "
123             << strerror(EEXIST);
124          throw cmd_error(ss.str());
125        }
126        if (chdir(target_->value().c_str())) {
127          std::stringstream ss;
128          ss << "svndigest: cannot read `" << target_->value() << "': " 
129             << strerror(errno);
130          throw cmd_error(ss.str());
131        }
132        target_->value(pwd());
133        chdir(save_wd.c_str());
134      }
135    }
136
137    // check config file
138    struct stat nodestat;
139    // true also if there is a broken symlink named...
140    bool config_exists = !lstat(config_file_->value().c_str(), &nodestat);
141    // the latter case in order to catch broken symlink
142    if (config_file_->present() || config_exists)
143      // throws if file does not exists
144      check_existence(config_file_->value());
145    if (config_exists) {
146      // throws if file is not readable
147      check_readable(config_file_->value());
148      stat(config_file_->value().c_str(), &nodestat);
149      if (!S_ISREG(nodestat.st_mode)) {
150        std::stringstream ss;
151        ss << "svndigest: `" << config_file_->value() 
152           << "' is not a regular file";
153        throw cmd_error(ss.str());
154      }
155    }
156  }
157
158
159  void Parameter::check_existence(std::string path) const
160  {
161    if (node_exist(path))
162      return;
163    std::stringstream ss;
164    ss << "svndigest: cannot stat `" << path << "': " << strerror(errno);
165    throw cmd_error(ss.str());
166  }
167
168 
169  void Parameter::check_readable(std::string path) const
170  {
171    if (!access_rights(path, "r"))
172      return;
173    std::stringstream ss;
174    ss << "svndigest: cannot open `" << path << "': " << strerror(errno);
175    throw cmd_error(ss.str());
176  }
177 
178
179  std::string Parameter::config_file(void) const
180  {
181    return config_file_->value();
182  }
183
184
185  bool Parameter::copyright(void) const
186  {
187    return copyright_->present();
188  }
189
190
191  bool Parameter::force(void) const
192  {
193    return force_->present();
194  }
195
196
197  bool Parameter::generate_config(void) const
198  {
199    return generate_config_->present();
200  }
201
202
203  bool Parameter::ignore_cache(void) const
204  {
205    return true;
206    return ignore_cache_->present();
207  }
208
209
210  void Parameter::init(void)
211  {
212    // don't use argv[0] because user may rename the binary
213    cmd_.program_name() = PACKAGE_NAME;
214    config_file_=new OptionArg<std::string>(cmd_, "config-file",
215                                "configuration file [<ROOT>/.svndigest/config]");
216    config_file_->print_arg("=FILE");
217    std::stringstream ss;
218    copyright_ = new OptionSwitch(cmd_, "copyright", 
219                                  "update copyright statement");
220
221    ss << "if sub-directory named <ROOT> exists in target directory, remove "
222       << "sub-directory before writing results";
223    force_ = new OptionSwitch(cmd_, "f,force", ss.str());
224    ss.str("");
225
226    help_ = new OptionHelp(cmd_);
227    generate_config_ = 
228      new OptionSwitch(cmd_, "g,generate-config", 
229                       "write configuration file to standard output");
230
231    ss.str("");
232    ss << "ignore cache files and analyze everything from repository";
233    ignore_cache_ = new OptionSwitch(cmd_, "ignore-cache", ss.str());
234         
235    report_ = new OptionSwitch(cmd_, "report", "create no HTML report", true);
236
237    ss.str("");
238    ss << "use revision numbers as time scale instead of dates [dates]";
239    revisions_ = new OptionSwitch(cmd_, "revisions", ss.str());
240
241    root_=
242      new OptionArg<std::string>(cmd_, "r,root", 
243                     "svn controlled directory to perform statistics on [.]");
244    root_->print_arg("=ROOT");
245    target_ = new OptionArg<std::string>(cmd_, "t,target", 
246                                         "output directory [.]");
247    target_->print_arg("=TARGET");
248   
249    verbose_ = new OptionSwitch(cmd_, "v,verbose", "explain what is being done");
250    version_ = new OptionVersion(cmd_);
251
252    ss.str("");
253    ss << "Report bugs to " << PACKAGE_BUGREPORT << ".\n";
254    help_->post_arguments() = ss.str();
255    help_->synopsis() = 
256      "Generate statistical report for a subversion repository\n";
257  }
258
259
260  bool Parameter::report(void) const
261  {
262    return report_->value();
263  }
264
265
266  bool Parameter::revisions(void) const
267  {
268    return revisions_->present();
269  }
270
271
272  std::string Parameter::root(void) const
273  {
274    return root_->value();
275  }
276
277 
278  std::string Parameter::targetdir(void) const
279  {
280    return target_->value();
281  }
282
283 
284  bool Parameter::verbose(void) const
285  {
286    return verbose_->present();
287  }
288
289
290}} // of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.