source: trunk/bin/Parameter.cc @ 1015

Last change on this file since 1015 was 1015, checked in by Peter Johansson, 14 years ago

closes #438. adding an option --format

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