source: trunk/bin/Parameter.cc @ 752

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

refs #338 - turning on cache again, but not only for files being up to date. Incomplete caches is ignored and the file is completely re-parsed from svn repo.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.1 KB
RevLine 
[37]1// $Id: Parameter.cc 752 2009-01-14 12:48:18Z peter $
2
[84]3/*
[727]4  Copyright (C) 2006, 2007, 2008 Jari Häkkinen, Peter Johansson
[84]5
[687]6  This file is part of svndigest, http://dev.thep.lu.se/svndigest
[84]7
[149]8  svndigest is free software; you can redistribute it and/or modify it
[84]9  under the terms of the GNU General Public License as published by
[693]10  the Free Software Foundation; either version 3 of the License, or
[84]11  (at your option) any later version.
12
[149]13  svndigest is distributed in the hope that it will be useful, but
[84]14  WITHOUT ANY WARRANTY; without even the implied warranty of
[149]15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
[84]16  General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
[693]19  along with svndigest. If not, see <http://www.gnu.org/licenses/>.
[84]20*/
21
[37]22#include "Parameter.h"
[234]23
24#include "ColumnStream.h"
[705]25#include "OptionArg.h"
26#include "OptionHelp.h"
27#include "OptionSwitch.h"
28#include "OptionVersion.h"
[116]29#include "utility.h"
[83]30#include <config.h> // this header file is created by configure
[37]31
[705]32#include <cassert>
33#include <cerrno>
[540]34#include <cstddef>
[727]35#include <cstring>
[226]36#include <fstream>
[37]37#include <iostream>
[226]38#include <sstream>
[49]39#include <stdexcept>
[37]40#include <string>
[104]41#include <sys/stat.h>
[37]42
43namespace theplu {
[149]44namespace svndigest {
[37]45
[518]46  Parameter::Parameter( int argc, char *argv[])
[705]47    : cmd_(
48     "Mandatory arguments to long options are mandatory for short options too.") 
[37]49  {
[705]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    }
[475]58
[705]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())
[709]67      config_file_->value(concatenate_path(root_->value(),".svndigest/config"));
[705]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());
[37]104      }
[705]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());
[475]119        }
[705]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());
[52]125        }
[705]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());
[626]131        }
[715]132        target_->value(pwd());
[705]133        chdir(save_wd.c_str());
[52]134      }
[705]135    }
136
137    // check config file
[708]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
[705]144      check_existence(config_file_->value());
[708]145    if (config_exists) {
146      // throws if file is not readable
[705]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;
[710]151        ss << "svndigest: `" << config_file_->value() 
152           << "' is not a regular file";
[705]153        throw cmd_error(ss.str());
[423]154      }
[705]155    }
[626]156  }
[37]157
[705]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());
[37]166  }
167
[705]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 
[37]178
[705]179  std::string Parameter::config_file(void) const
[37]180  {
[705]181    return config_file_->value();
182  }
[151]183
184
[705]185  bool Parameter::copyright(void) const
186  {
187    return copyright_->present();
188  }
[579]189
[116]190
[705]191  bool Parameter::force(void) const
192  {
193    return force_->present();
194  }
[579]195
[151]196
[705]197  bool Parameter::generate_config(void) const
198  {
199    return generate_config_->present();
200  }
[116]201
[229]202
[705]203  bool Parameter::ignore_cache(void) const
204  {
205    return ignore_cache_->present();
[240]206  }
[229]207
[240]208
[705]209  void Parameter::init(void)
[240]210  {
[705]211    // don't use argv[0] because user may rename the binary
212    cmd_.program_name() = PACKAGE_NAME;
213    config_file_=new OptionArg<std::string>(cmd_, "config-file",
214                                "configuration file [<ROOT>/.svndigest/config]");
215    config_file_->print_arg("=FILE");
216    std::stringstream ss;
217    copyright_ = new OptionSwitch(cmd_, "copyright", 
218                                  "update copyright statement");
219
220    ss << "if sub-directory named <ROOT> exists in target directory, remove "
221       << "sub-directory before writing results";
222    force_ = new OptionSwitch(cmd_, "f,force", ss.str());
223    ss.str("");
224
225    help_ = new OptionHelp(cmd_);
226    generate_config_ = 
227      new OptionSwitch(cmd_, "g,generate-config", 
228                       "write configuration file to standard output");
229
230    ss.str("");
231    ss << "ignore cache files and analyze everything from repository";
232    ignore_cache_ = new OptionSwitch(cmd_, "ignore-cache", ss.str());
233         
234    report_ = new OptionSwitch(cmd_, "report", "create no HTML report", true);
235
236    ss.str("");
237    ss << "use revision numbers as time scale instead of dates [dates]";
238    revisions_ = new OptionSwitch(cmd_, "revisions", ss.str());
239
240    root_=
241      new OptionArg<std::string>(cmd_, "r,root", 
242                     "svn controlled directory to perform statistics on [.]");
243    root_->print_arg("=ROOT");
244    target_ = new OptionArg<std::string>(cmd_, "t,target", 
245                                         "output directory [.]");
246    target_->print_arg("=TARGET");
[240]247   
[705]248    verbose_ = new OptionSwitch(cmd_, "v,verbose", "explain what is being done");
[724]249    version_ = new OptionVersion(cmd_, "version", 
250                                 "print version information and exit", verbose_);
[705]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";
[37]257  }
258
259
[705]260  bool Parameter::report(void) const
[73]261  {
[705]262    return report_->value();
263  }
[234]264
265
[705]266  bool Parameter::revisions(void) const
267  {
268    return revisions_->present();
269  }
[234]270
[280]271
[705]272  std::string Parameter::root(void) const
273  {
274    return root_->value();
[37]275  }
276
[705]277 
278  std::string Parameter::targetdir(void) const
[626]279  {
[705]280    return target_->value();
[626]281  }
282
[705]283 
284  bool Parameter::verbose(void) const
[37]285  {
[705]286    return verbose_->present();
[37]287  }
288
[705]289
[442]290}} // of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.