source: trunk/bin/Parameter.cc @ 705

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

importing classes for commandline parsing from yat. This fixes #349 and #265

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.8 KB
Line 
1// $Id: Parameter.cc 705 2008-11-25 23:33:26Z 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(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(concatenate_path(pwd(), base_root));
133        chdir(save_wd.c_str());
134      }
135    }
136
137    // check config file
138    if (config_file_->present())
139      check_existence(config_file_->value());
140    if (node_exist(config_file_->value())) {
141      check_readable(config_file_->value());
142      struct stat nodestat;
143      stat(config_file_->value().c_str(), &nodestat);
144      if (!S_ISREG(nodestat.st_mode)) {
145        std::stringstream ss;
146        ss << "svndigest: `" << root_->value() << "' is not a regular file";
147        throw cmd_error(ss.str());
148      }
149    }
150  }
151
152
153  void Parameter::check_existence(std::string path) const
154  {
155    if (node_exist(path))
156      return;
157    std::stringstream ss;
158    ss << "svndigest: cannot stat `" << path << "': " << strerror(errno);
159    throw cmd_error(ss.str());
160  }
161
162 
163  void Parameter::check_readable(std::string path) const
164  {
165    if (!access_rights(path, "r"))
166      return;
167    std::stringstream ss;
168    ss << "svndigest: cannot open `" << path << "': " << strerror(errno);
169    throw cmd_error(ss.str());
170  }
171 
172
173  std::string Parameter::config_file(void) const
174  {
175    return config_file_->value();
176  }
177
178
179  bool Parameter::copyright(void) const
180  {
181    return copyright_->present();
182  }
183
184
185  bool Parameter::force(void) const
186  {
187    return force_->present();
188  }
189
190
191  bool Parameter::generate_config(void) const
192  {
193    return generate_config_->present();
194  }
195
196
197  bool Parameter::ignore_cache(void) const
198  {
199    return ignore_cache_->present();
200  }
201
202
203  void Parameter::init(void)
204  {
205    // don't use argv[0] because user may rename the binary
206    cmd_.program_name() = PACKAGE_NAME;
207    config_file_=new OptionArg<std::string>(cmd_, "config-file",
208                                "configuration file [<ROOT>/.svndigest/config]");
209    config_file_->print_arg("=FILE");
210    std::stringstream ss;
211    copyright_ = new OptionSwitch(cmd_, "copyright", 
212                                  "update copyright statement");
213
214    ss << "if sub-directory named <ROOT> exists in target directory, remove "
215       << "sub-directory before writing results";
216    force_ = new OptionSwitch(cmd_, "f,force", ss.str());
217    ss.str("");
218
219    help_ = new OptionHelp(cmd_);
220    generate_config_ = 
221      new OptionSwitch(cmd_, "g,generate-config", 
222                       "write configuration file to standard output");
223
224    ss.str("");
225    ss << "ignore cache files and analyze everything from repository";
226    ignore_cache_ = new OptionSwitch(cmd_, "ignore-cache", ss.str());
227         
228    report_ = new OptionSwitch(cmd_, "report", "create no HTML report", true);
229
230    ss.str("");
231    ss << "use revision numbers as time scale instead of dates [dates]";
232    revisions_ = new OptionSwitch(cmd_, "revisions", ss.str());
233
234    root_=
235      new OptionArg<std::string>(cmd_, "r,root", 
236                     "svn controlled directory to perform statistics on [.]");
237    root_->print_arg("=ROOT");
238    target_ = new OptionArg<std::string>(cmd_, "t,target", 
239                                         "output directory [.]");
240    target_->print_arg("=TARGET");
241   
242    verbose_ = new OptionSwitch(cmd_, "v,verbose", "explain what is being done");
243    version_ = new OptionVersion(cmd_);
244
245    ss.str("");
246    ss << "Report bugs to " << PACKAGE_BUGREPORT << ".\n";
247    help_->post_arguments() = ss.str();
248    help_->synopsis() = 
249      "Generate statistical report for a subversion repository\n";
250  }
251
252
253  bool Parameter::report(void) const
254  {
255    return report_->value();
256  }
257
258
259  bool Parameter::revisions(void) const
260  {
261    return revisions_->present();
262  }
263
264
265  std::string Parameter::root(void) const
266  {
267    return root_->value();
268  }
269
270 
271  std::string Parameter::targetdir(void) const
272  {
273    return target_->value();
274  }
275
276 
277  bool Parameter::verbose(void) const
278  {
279    return verbose_->present();
280  }
281
282
283}} // of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.