source: trunk/bin/Parameter.cc @ 829

Last change on this file since 829 was 829, checked in by Peter Johansson, 12 years ago

adding svndigest url to help output

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.8 KB
RevLine 
[37]1// $Id: Parameter.cc 829 2009-10-27 02:36:08Z 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
[705]24#include "OptionVersion.h"
[795]25#include "../lib/utility.h" // to avoid inclusion of yat file
26
27#include "yat/ColumnStream.h"
28#include "yat/Exception.h"
29#include "yat/OptionArg.h"
30#include "yat/OptionHelp.h"
31#include "yat/OptionSwitch.h"
32
[83]33#include <config.h> // this header file is created by configure
[37]34
[705]35#include <cassert>
36#include <cerrno>
[540]37#include <cstddef>
[727]38#include <cstring>
[226]39#include <fstream>
[37]40#include <iostream>
[226]41#include <sstream>
[49]42#include <stdexcept>
[37]43#include <string>
[104]44#include <sys/stat.h>
[37]45
46namespace theplu {
[149]47namespace svndigest {
[37]48
[518]49  Parameter::Parameter( int argc, char *argv[])
[820]50    : cmd_( std::string("Mandatory arguments to long options ") + 
51            std::string("are mandatory for short options too.")), 
52      config_file_(cmd_, "config-file", 
53                   "configuration file [<ROOT>/.svndigest/config]"),
54      copyright_(cmd_, "copyright", "update copyright statement"),
55      force_(cmd_, "f,force", 
56             std::string("if sub-directory named <ROOT> exists in target dire")+
57             std::string("ctory, remove sub-directory before writing results")),
58      generate_config_(cmd_, "g,generate-config", 
59                       "write configuration to standard output"),
60      help_(cmd_),
61      ignore_cache_(cmd_, "ignore-cache", 
62                    std::string("ignore cache files and analyze ") +
63                    std::string("everything from repository")),
64      report_(cmd_, "report", "create no HTML report", true),
65      revisions_(cmd_, "revisions", 
66                 "use revision number as time scale instead of dates [dates]"),
67      root_(cmd_, "r,root", 
68            "svn controlled directory to perform statistics on [.]"),
69      target_(cmd_, "t,target", "output directory [.]"),
70      verbose_(cmd_, "v,verbose", "explain what is being done"),
71      version_(cmd_, "version", "print version information and exit", &verbose_)
[37]72  {
[705]73    init();
74    try {
75      cmd_.parse(argc, argv);
76    }
[795]77    catch (yat::utility::cmd_error& e) {
[705]78      std::cerr << e.what() << std::endl;
79      exit (-1);
80    }
[475]81
[705]82    // set default values
[820]83    if (!root_.present())
84      root_.value(".");
[705]85
[820]86    if (!target_.present())
87      target_.value(".");
[705]88
[820]89    if (!config_file_.present())
90      config_file_.value(concatenate_path(root_.value(),".svndigest/config"));
[705]91
92    // analyse arguments
93    analyse();
94  }
95
96
97  Parameter::~Parameter(void)
98  {
99  }
100
101
102  void Parameter::analyse(void)
103  {
104    std::string save_wd = pwd();
105
106    // check root but not if -g option given
107    if (!generate_config()) {
[820]108      check_existence(root_.value());
109      check_readable(root_.value());
110      if (chdir(root_.value().c_str())) {
[705]111        std::stringstream ss;
[820]112        ss << "svndigest: cannot read `" << root_.value() << "': " 
[705]113           << strerror(errno);
[795]114        throw yat::utility::cmd_error(ss.str());
[37]115      }
[820]116      root_.value(pwd());
[705]117      chdir(save_wd.c_str());
118
119      // check target (only if we write report)
120      if (report()) {
[820]121        check_existence(target_.value());
122        check_readable(target_.value());
123        std::string base_root = file_name(root_.value());
124        std::string path = concatenate_path(target_.value(),base_root); 
125        if (access_rights(target_.value().c_str(), "w")) {
[705]126          std::stringstream ss;
127          ss << "svndigest: cannot create directory `" << path
128             << "': " << strerror(errno);
[795]129          throw yat::utility::cmd_error(ss.str());
[475]130        }
[705]131        if (node_exist(path) && !force()) {
132          std::stringstream ss;
133          ss << "svndigest: cannot create directory `" << path << "' "
134             << strerror(EEXIST);
[795]135          throw yat::utility::cmd_error(ss.str());
[52]136        }
[820]137        if (chdir(target_.value().c_str())) {
[705]138          std::stringstream ss;
[820]139          ss << "svndigest: cannot read `" << target_.value() << "': " 
[705]140             << strerror(errno);
[795]141          throw yat::utility::cmd_error(ss.str());
[626]142        }
[820]143        target_.value(pwd());
[705]144        chdir(save_wd.c_str());
[52]145      }
[705]146    }
147
148    // check config file
[708]149    struct stat nodestat;
150    // true also if there is a broken symlink named...
[820]151    bool config_exists = !lstat(config_file_.value().c_str(), &nodestat);
[708]152    // the latter case in order to catch broken symlink
[820]153    if (config_file_.present() || config_exists)
[708]154      // throws if file does not exists
[820]155      check_existence(config_file_.value());
[708]156    if (config_exists) {
157      // throws if file is not readable
[820]158      check_readable(config_file_.value());
159      stat(config_file_.value().c_str(), &nodestat);
[705]160      if (!S_ISREG(nodestat.st_mode)) {
161        std::stringstream ss;
[820]162        ss << "svndigest: `" << config_file_.value() 
[710]163           << "' is not a regular file";
[795]164        throw yat::utility::cmd_error(ss.str());
[423]165      }
[705]166    }
[626]167  }
[37]168
[705]169
170  void Parameter::check_existence(std::string path) const
171  {
172    if (node_exist(path))
173      return;
174    std::stringstream ss;
175    ss << "svndigest: cannot stat `" << path << "': " << strerror(errno);
[795]176    throw yat::utility::cmd_error(ss.str());
[37]177  }
178
[705]179 
180  void Parameter::check_readable(std::string path) const
181  {
182    if (!access_rights(path, "r"))
183      return;
184    std::stringstream ss;
185    ss << "svndigest: cannot open `" << path << "': " << strerror(errno);
[795]186    throw yat::utility::cmd_error(ss.str());
[705]187  }
188 
[37]189
[705]190  std::string Parameter::config_file(void) const
[37]191  {
[820]192    return config_file_.value();
[705]193  }
[151]194
195
[705]196  bool Parameter::copyright(void) const
197  {
[820]198    return copyright_.present();
[705]199  }
[579]200
[116]201
[705]202  bool Parameter::force(void) const
203  {
[820]204    return force_.present();
[705]205  }
[579]206
[151]207
[705]208  bool Parameter::generate_config(void) const
209  {
[820]210    return generate_config_.present();
[705]211  }
[116]212
[229]213
[705]214  bool Parameter::ignore_cache(void) const
215  {
[820]216    return ignore_cache_.present();
[240]217  }
[229]218
[240]219
[705]220  void Parameter::init(void)
[240]221  {
[705]222    // don't use argv[0] because user may rename the binary
223    cmd_.program_name() = PACKAGE_NAME;
[820]224    config_file_.print_arg("=FILE");
225    root_.print_arg("=ROOT");
226    target_.print_arg("=TARGET");
[705]227    std::stringstream ss;
[829]228    ss << "Report bugs to " << PACKAGE_BUGREPORT << ".\n"
229       << PACKAGE << " home page: <" << PACKAGE_URL << ">.\n";
[820]230    help_.post_arguments() = ss.str();
231    help_.synopsis() = 
[705]232      "Generate statistical report for a subversion repository\n";
[37]233  }
234
235
[705]236  bool Parameter::report(void) const
[73]237  {
[820]238    return report_.value();
[705]239  }
[234]240
241
[705]242  bool Parameter::revisions(void) const
243  {
[820]244    return revisions_.present();
[705]245  }
[234]246
[280]247
[705]248  std::string Parameter::root(void) const
249  {
[820]250    return root_.value();
[37]251  }
252
[705]253 
254  std::string Parameter::targetdir(void) const
[626]255  {
[820]256    return target_.value();
[626]257  }
258
[705]259 
260  bool Parameter::verbose(void) const
[37]261  {
[820]262    return verbose_.present();
[37]263  }
264
[705]265
[442]266}} // of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.