source: trunk/bin/Parameter.cc @ 888

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

updating copyrights

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