source: trunk/bin/Parameter.cc @ 834

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

workaround for autoconf 2.63 and older

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