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 branch_name = options[branch_option];
64 internalize_rsa_keypair_id(options[key_option], signing_key);
65
66 if (!current.empty())
67 {
68 relative_directory = file_path(current.native_directory_string());
69 L(F("relative directory is '%s'\n") % relative_directory());
70 }
71
72 if (global_sanity.filename == "")
73 {
74 local_path dump_path;
75 get_local_dump_path(dump_path);
76 L(F("setting dump path to %s\n") % dump_path);
77 global_sanity.filename = dump_path();
78 }
79 }
80 load_rcfiles();
81}
82
83void
84app_state::require_working_copy()
85{
86 N(found_working_copy, F("working copy directory required but not found"));
87 write_options();
88}
89
90void
91app_state::create_working_copy(std::string const & dir)
92{
93 N(dir.size(), F("invalid directory ''"));
94
95 // cd back to where we started from
96 N(chdir(fs::initial_path().native_directory_string().c_str()) != -1,
97 F("cannot change to initial directory %s\n")
98 % fs::initial_path().native_directory_string());
99
100 string target = absolutify(dir);
101 L(F("create working copy in %s\n") % target);
102
103 {
104 fs::path new_dir = mkpath(target);
105 try
106 {
107 fs::create_directories(new_dir);
108 }
109 catch (fs::filesystem_error & err)
110 {
111 N(false,
112 F("could not create directory: %s: %s\n")
113 % err.path1().native_directory_string()
114 % strerror(err.native_error()));
115 }
116 N(chdir(new_dir.native_directory_string().c_str()) != -1,
117 F("cannot change to new directory %s\n")
118 % new_dir.native_directory_string());
119
120 relative_directory = file_path();
121 }
122
123 local_path mt(book_keeping_dir);
124
125 N(!directory_exists(mt),
126 F("monotone book-keeping directory '%s' already exists in '%s'\n")
127 % book_keeping_dir % target);
128
129 L(F("creating book-keeping directory '%s' for working copy in '%s'\n")
130 % book_keeping_dir % target);
131
132 mkdir_p(mt);
133
134 write_options();
135
136 blank_user_log();
137
138 load_rcfiles();
139}
140
141file_path
142app_state::prefix(utf8 const & path)
143{
144 fs::path p1 = mkpath(relative_directory()) / mkpath(path());
145 file_path p2(p1.normalize().string());
146 L(F("'%s' prefixed to '%s'\n") % path() % p2());
147 return p2;
148}
149
150void
151app_state::set_restriction(path_set const & valid_paths, vector<utf8> const & paths)
152{
153 // this can't be a file-global static, because file_path's initializer
154 // depends on another global static being defined.
155 static file_path dot(".");
156 for (vector<utf8>::const_iterator i = paths.begin(); i != paths.end(); ++i)
157 {
158 file_path p = prefix(*i);
159
160 if (lua.hook_ignore_file(p))
161 {
162 L(F("'%s' ignored by restricted path set\n") % p());
163 continue;
164 }
165
166 N(p == dot || valid_paths.find(p) != valid_paths.end(),
167 F("unknown path '%s'\n") % p());
168
169 L(F("'%s' added to restricted path set\n") % p());
170 restrictions.insert(p);
171 }
172}
173
174bool
175app_state::restriction_includes(file_path const & path)
176{
177 // this can't be a file-global static, because file_path's initializer
178 // depends on another global static being defined.
179 static file_path dot(".");
180 if (restrictions.empty())
181 {
182 L(F("empty restricted path set; '%s' included\n") % path());
183 return true;
184 }
185
186 // a path that normalizes to "." means that the restriction has been
187 // essentially cleared (all files are included). rather than be
188 // careful about what goes in to the restricted path set we just
189 // check for this special case here.
190
191 if (restrictions.find(dot) != restrictions.end())
192 {
193 L(F("restricted path set cleared; '%s' included\n") % path());
194 return true;
195 }
196
197 fs::path test = mkpath(path());
198
199 while (!test.empty())
200 {
201 L(F("checking restricted path set for '%s'\n") % test.string());
202
203 file_path p(test.string());
204 path_set::const_iterator i = restrictions.find(p);
205
206 if (i != restrictions.end())
207 {
208 L(F("path '%s' found in restricted path set; '%s' included\n")
209 % test.string() % path());
210 return true;
211 }
212 else
213 {
214 L(F("path '%s' not found in restricted path set; '%s' excluded\n")
215 % test.string() % path());
216 }
217 test = test.branch_path();
218 }
219
220 return false;
221}
222
223void
224app_state::set_database(utf8 const & filename)
225{
226 string dbname = absolutify(filename());
227 if (dbname != "") db.set_filename(mkpath(dbname));
228
229 options[database_option] = utf8(dbname);
230}
231
232void
233app_state::set_branch(utf8 const & branch)
234{
235 branch_name = branch();
236
237 options[branch_option] = branch;
238}
239
240void
241app_state::set_signing_key(utf8 const & key)
242{
243 internalize_rsa_keypair_id(key, signing_key);
244
245 options[key_option] = key;
246}
247
248void
249app_state::set_root(utf8 const & path)
250{
251 search_root = absolutify(path());
252 fs::path root = mkpath(search_root());
253 N(fs::exists(root),
254 F("search root '%s' does not exist\n") % search_root);
255 N(fs::is_directory(root),
256 F("search root '%s' is not a directory\n") % search_root);
257 L(F("set search root to %s\n") % search_root);
258}
259
260void
261app_state::set_message(utf8 const & m)
262{
263 message = m;
264}
265
266void
267app_state::set_depth(long d)
268{
269 N(d > 0,
270 F("negative or zero depth not allowed\n"));
271 depth = d;
272}
273
274void
275app_state::add_revision(utf8 const & selector)
276{
277 revision_selectors.push_back(selector);
278}
279
280void
281app_state::set_stdhooks(bool b)
282{
283 stdhooks = b;
284}
285
286void
287app_state::set_rcfiles(bool b)
288{
289 rcfiles = b;
290}
291
292void
293app_state::add_rcfile(utf8 const & filename)
294{
295 extra_rcfiles.push_back(filename);
296}
297
298// rc files are loaded after we've changed to the working copy
299// directory so that MT/monotonerc can be loaded between .monotonerc
300// and other rcfiles
301
302void
303app_state::load_rcfiles()
304{
305 // built-in rc settings are defaults
306
307 if (stdhooks)
308 lua.add_std_hooks();
309
310 // ~/.monotonerc overrides that, and
311 // MT/monotonerc overrides *that*
312
313 if (rcfiles)
314 {
315 fs::path default_rcfile;
316 fs::path working_copy_rcfile;
317 lua.default_rcfilename(default_rcfile);
318 lua.working_copy_rcfilename(working_copy_rcfile);
319 lua.load_rcfile(default_rcfile, false);
320 lua.load_rcfile(working_copy_rcfile, false);
321 }
322
323 // command-line rcfiles override even that
324
325 for (vector<utf8>::const_iterator i = extra_rcfiles.begin();
326 i != extra_rcfiles.end(); ++i)
327 {
328 lua.load_rcfile(mkpath((*i)()), true);
329 }
330}
331
332void
333app_state::read_options()
334{
335 local_path o_path;
336 get_options_path(o_path);
337
338 if (file_exists(o_path))
339 {
340 data dat;
341 read_data(o_path, dat);
342 read_options_map(dat, options);
343 }
344}
345
346void
347app_state::write_options()
348{
349 local_path o_path;
350 get_options_path(o_path);
351
352 data dat;
353 write_options_map(dat, options);
354 write_data(o_path, dat);
355}

Archive Download this file

Branches

Tags

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