source: trunk/bin/Parameter.cc @ 1055

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

added new cmd option 'anchor-format'. refs #279

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