monotone

monotone Mtn Source Tree

Root/app_state.cc

1#include <iostream>
2#include <string>
3#include <vector>
4#ifdef WIN32
5#include <io.h> /* for chdir() */
6#endif
7#include <cstdlib> // for strtoul()
8
9#include <boost/filesystem/path.hpp>
10#include <boost/filesystem/operations.hpp>
11#include <boost/filesystem/convenience.hpp>
12#include <boost/filesystem/exception.hpp>
13
14#include "app_state.hh"
15#include "database.hh"
16#include "file_io.hh"
17#include "sanity.hh"
18#include "transforms.hh"
19#include "work.hh"
20
21// copyright (C) 2002, 2003 graydon hoare <graydon@pobox.com>
22// all rights reserved.
23// licensed to the public under the terms of the GNU GPL (>= 2)
24// see the file COPYING for details
25
26using namespace std;
27
28static string const database_option("database");
29static string const branch_option("branch");
30static string const key_option("key");
31
32app_state::app_state()
33 : branch_name(""), db(""), stdhooks(true), rcfiles(true),
34 search_root("/"), depth(-1)
35{
36 db.set_app(this);
37}
38
39app_state::~app_state()
40{
41}
42
43void
44app_state::allow_working_copy()
45{
46 fs::path root = mkpath(search_root());
47 fs::path working;
48 fs::path current;
49
50 found_working_copy = find_working_copy(root, working, current);
51
52 if (found_working_copy)
53 {
54 L(F("initializing from directory %s\n") % fs::initial_path().string());
55 L(F("found working copy directory %s\n") % working.string());
56 N(chdir(working.native_directory_string().c_str()) != -1,
57 F("cannot change to directory to %s\n") % working.native_directory_string());
58
59 read_options();
60
61 string dbname = absolutify(options[database_option]());
62 if (dbname != "") db.set_filename(mkpath(dbname));
63 if (branch_name().empty())
64 branch_name = options[branch_option];
65 L(F("branch name is '%s'\n") % branch_name());
66 internalize_rsa_keypair_id(options[key_option], signing_key);
67
68 if (!current.empty())
69 {
70 relative_directory = file_path(current.native_directory_string());
71 L(F("relative directory is '%s'\n") % relative_directory());
72 }
73
74 if (global_sanity.filename == "")
75 {
76 local_path dump_path;
77 get_local_dump_path(dump_path);
78 L(F("setting dump path to %s\n") % dump_path);
79 global_sanity.filename = dump_path();
80 }
81 }
82 load_rcfiles();
83}
84
85void
86app_state::require_working_copy()
87{
88 N(found_working_copy, F("working copy directory required but not found"));
89 write_options();
90}
91
92void
93app_state::create_working_copy(std::string const & dir)
94{
95 N(dir.size(), F("invalid directory ''"));
96
97 // cd back to where we started from
98 N(chdir(fs::initial_path().native_directory_string().c_str()) != -1,
99 F("cannot change to initial directory %s\n")
100 % fs::initial_path().native_directory_string());
101
102 string target = absolutify(dir);
103 L(F("create working copy in %s\n") % target);
104
105 {
106 fs::path new_dir = mkpath(target);
107 try
108 {
109 fs::create_directories(new_dir);
110 }
111 catch (fs::filesystem_error & err)
112 {
113 N(false,
114 F("could not create directory: %s: %s\n")
115 % err.path1().native_directory_string()
116 % strerror(err.native_error()));
117 }
118 N(chdir(new_dir.native_directory_string().c_str()) != -1,
119 F("cannot change to new directory %s\n")
120 % new_dir.native_directory_string());
121
122 relative_directory = file_path();
123 }
124
125 local_path mt(book_keeping_dir);
126
127 N(!directory_exists(mt),
128 F("monotone book-keeping directory '%s' already exists in '%s'\n")
129 % book_keeping_dir % target);
130
131 L(F("creating book-keeping directory '%s' for working copy in '%s'\n")
132 % book_keeping_dir % target);
133
134 mkdir_p(mt);
135
136 make_branch_sticky();
137
138 write_options();
139
140 blank_user_log();
141
142 if (lua.hook_use_inodeprints())
143 enable_inodeprints();
144
145 load_rcfiles();
146}
147
148file_path
149app_state::prefix(utf8 const & path)
150{
151 fs::path p1 = mkpath(relative_directory()) / mkpath(path());
152 file_path p2(p1.normalize().string());
153 L(F("'%s' prefixed to '%s'\n") % path() % p2());
154 return p2;
155}
156
157void
158app_state::set_restriction(path_set const & valid_paths, vector<utf8> const & paths)
159{
160 // this can't be a file-global static, because file_path's initializer
161 // depends on another global static being defined.
162 static file_path dot(".");
163 restrictions.clear();
164 for (vector<utf8>::const_iterator i = paths.begin(); i != paths.end(); ++i)
165 {
166 file_path p = prefix(*i);
167
168 if (lua.hook_ignore_file(p))
169 {
170 L(F("'%s' ignored by restricted path set\n") % p());
171 continue;
172 }
173
174 N(p == dot || valid_paths.find(p) != valid_paths.end(),
175 F("unknown path '%s'\n") % p());
176
177 L(F("'%s' added to restricted path set\n") % p());
178 restrictions.insert(p);
179 }
180}
181
182bool
183app_state::restriction_includes(file_path const & path)
184{
185 // this can't be a file-global static, because file_path's initializer
186 // depends on another global static being defined.
187 static file_path dot(".");
188 if (restrictions.empty())
189 {
190 return true;
191 }
192
193 // a path that normalizes to "." means that the restriction has been
194 // essentially cleared (all files are included). rather than be
195 // careful about what goes in to the restricted path set we just
196 // check for this special case here.
197
198 if (restrictions.find(dot) != restrictions.end())
199 {
200 return true;
201 }
202
203 fs::path test = mkpath(path());
204
205 while (!test.empty())
206 {
207 L(F("checking restricted path set for '%s'\n") % test.string());
208
209 file_path p(test.string());
210 path_set::const_iterator i = restrictions.find(p);
211
212 if (i != restrictions.end())
213 {
214 L(F("path '%s' found in restricted path set; '%s' included\n")
215 % test.string() % path());
216 return true;
217 }
218 else
219 {
220 L(F("path '%s' not found in restricted path set; '%s' excluded\n")
221 % test.string() % path());
222 }
223 test = test.branch_path();
224 }
225
226 return false;
227}
228
229void
230app_state::set_database(utf8 const & filename)
231{
232 string dbname = absolutify(filename());
233 if (dbname != "") db.set_filename(mkpath(dbname));
234
235 options[database_option] = utf8(dbname);
236}
237
238void
239app_state::set_branch(utf8 const & branch)
240{
241 branch_name = branch();
242}
243
244void
245app_state::make_branch_sticky()
246{
247 options[branch_option] = branch_name();
248}
249
250void
251app_state::set_signing_key(utf8 const & key)
252{
253 internalize_rsa_keypair_id(key, signing_key);
254
255 options[key_option] = key;
256}
257
258void
259app_state::set_root(utf8 const & path)
260{
261 search_root = absolutify(path());
262 fs::path root = mkpath(search_root());
263 N(fs::exists(root),
264 F("search root '%s' does not exist\n") % search_root);
265 N(fs::is_directory(root),
266 F("search root '%s' is not a directory\n") % search_root);
267 L(F("set search root to %s\n") % search_root);
268}
269
270void
271app_state::set_message(utf8 const & m)
272{
273 message = m;
274}
275
276void
277app_state::set_date(utf8 const & d)
278{
279 date = d;
280}
281
282void
283app_state::set_author(utf8 const & a)
284{
285 author = a;
286}
287
288void
289app_state::set_depth(long d)
290{
291 N(d > 0,
292 F("negative or zero depth not allowed\n"));
293 depth = d;
294}
295
296void
297app_state::add_revision(utf8 const & selector)
298{
299 revision_selectors.push_back(selector);
300}
301
302void
303app_state::set_stdhooks(bool b)
304{
305 stdhooks = b;
306}
307
308void
309app_state::set_rcfiles(bool b)
310{
311 rcfiles = b;
312}
313
314void
315app_state::add_rcfile(utf8 const & filename)
316{
317 extra_rcfiles.push_back(filename);
318}
319
320// rc files are loaded after we've changed to the working copy directory so
321// that MT/monotonerc can be loaded between ~/.monotone/monotonerc and other
322// rcfiles
323
324void
325app_state::load_rcfiles()
326{
327 // built-in rc settings are defaults
328
329 if (stdhooks)
330 lua.add_std_hooks();
331
332 // ~/.monotone/monotonerc overrides that, and
333 // MT/monotonerc overrides *that*
334
335 if (rcfiles)
336 {
337 fs::path default_rcfile;
338 fs::path working_copy_rcfile;
339 lua.default_rcfilename(default_rcfile);
340 lua.working_copy_rcfilename(working_copy_rcfile);
341 lua.load_rcfile(default_rcfile, false);
342 lua.load_rcfile(working_copy_rcfile, false);
343 }
344
345 // command-line rcfiles override even that
346
347 for (vector<utf8>::const_iterator i = extra_rcfiles.begin();
348 i != extra_rcfiles.end(); ++i)
349 {
350 lua.load_rcfile(mkpath((*i)()), true);
351 }
352}
353
354void
355app_state::read_options()
356{
357 local_path o_path;
358 get_options_path(o_path);
359
360 if (file_exists(o_path))
361 {
362 data dat;
363 read_data(o_path, dat);
364 read_options_map(dat, options);
365 }
366}
367
368void
369app_state::write_options()
370{
371 local_path o_path;
372 get_options_path(o_path);
373
374 data dat;
375 write_options_map(dat, options);
376 write_data(o_path, dat);
377}

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status