monotone

monotone Mtn Source Tree

Root/app_state.cc

1// Copyright (C) 2002 Graydon Hoare <graydon@pobox.com>
2//
3// This program is made available under the GNU GPL version 2.0 or
4// greater. See the accompanying file COPYING for details.
5//
6// This program is distributed WITHOUT ANY WARRANTY; without even the
7// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8// PURPOSE.
9
10#include <cstdlib> // for strtoul()
11#include <string>
12#include <vector>
13
14#include <boost/filesystem/convenience.hpp>
15#include <boost/filesystem/exception.hpp>
16#include <boost/filesystem/operations.hpp>
17#include <boost/filesystem/path.hpp>
18
19#include "botan/pubkey.h"
20#include "botan/rsa.h"
21
22#include "app_state.hh"
23#include "charset.hh"
24#include "database.hh"
25#include "file_io.hh"
26#include "platform.hh"
27#include "sanity.hh"
28#include "ui.hh"
29#include "work.hh"
30
31using std::exception;
32using std::map;
33using std::string;
34using std::vector;
35using std::vector;
36
37app_state::app_state()
38 : db(system_path()),
39 keys(this), work(db, lua),
40// search_root(current_root_path()),
41// diff_format(unified_diff),
42 branch_is_sticky(false),
43 project(*this)
44{
45 db.set_app(this);
46 lua.set_app(this);
47 keys.set_key_dir(opts.conf_dir / "keys");
48}
49
50app_state::~app_state()
51{
52}
53
54
55void
56app_state::allow_workspace()
57{
58 L(FL("initializing from directory %s") % fs::initial_path().string());
59 found_workspace = find_and_go_to_workspace(opts.root);
60
61 if (found_workspace)
62 {
63 if (global_sanity.filename.empty())
64 {
65 bookkeeping_path dump_path;
66 work.get_local_dump_path(dump_path);
67 L(FL("setting dump path to %s") % dump_path);
68 // The 'true' means that, e.g., if we're running checkout,
69 // then it's okay for dumps to go into our starting working
70 // dir's _MTN rather than the new workspace dir's _MTN.
71 global_sanity.filename = system_path(dump_path, false).as_external();
72 }
73 }
74 load_rcfiles();
75}
76
77void
78app_state::process_options()
79{
80 system_path database_option;
81 branch_name branch_option;
82 rsa_keypair_id key_option;
83 system_path keydir_option;
84
85 if (!found_workspace)
86 return;
87
88 work.check_ws_format();
89 work.get_ws_options(database_option, branch_option,
90 key_option, keydir_option);
91
92 // Workspace options are not to override the command line.
93 if (db.get_filename().as_internal().empty() && !database_option.as_internal().empty())
94 db.set_filename(database_option);
95
96 if (keys.get_key_dir().as_internal().empty() && !keydir_option.as_internal().empty())
97 set_key_dir(keydir_option);
98
99 if (opts.branchname().empty() && !branch_option().empty())
100 {
101 opts.branchname = branch_option;
102 branch_is_sticky = true;
103 }
104
105 L(FL("branch name is '%s'") % opts.branchname);
106
107 if (!opts.key_given)
108 opts.signing_key = key_option;
109}
110
111void
112app_state::write_options()
113{
114 system_path database_option;
115 branch_name branch_option;
116 rsa_keypair_id key_option;
117 system_path keydir_option;
118
119 database_option = db.get_filename();
120 keydir_option = keys.get_key_dir();
121
122 if (branch_is_sticky)
123 branch_option = opts.branchname;
124
125 if (opts.key_given)
126 key_option = opts.signing_key;
127
128 work.set_ws_options(database_option, branch_option,
129 key_option, keydir_option);
130}
131
132void
133app_state::require_workspace(string const & explanation)
134{
135 N(found_workspace,
136 F("workspace required but not found%s%s")
137 % (explanation.empty() ? "" : "\n") % explanation);
138 write_options();
139}
140
141void
142app_state::create_workspace(system_path const & new_dir)
143{
144 N(!new_dir.empty(), F("invalid directory ''"));
145
146 L(FL("creating workspace in %s") % new_dir);
147
148 mkdir_p(new_dir);
149 go_to_workspace(new_dir);
150 mark_std_paths_used();
151
152 N(!directory_exists(bookkeeping_root),
153 F("monotone bookkeeping directory '%s' already exists in '%s'")
154 % bookkeeping_root % new_dir);
155
156 L(FL("creating bookkeeping directory '%s' for workspace in '%s'")
157 % bookkeeping_root % new_dir);
158
159 mkdir_p(bookkeeping_root);
160
161 make_branch_sticky();
162
163 write_options();
164
165 work.write_ws_format();
166 work.blank_user_log();
167
168 if (lua.hook_use_inodeprints())
169 work.enable_inodeprints();
170
171 found_workspace = true;
172 if (global_sanity.filename.empty())
173 {
174 bookkeeping_path dump_path;
175 work.get_local_dump_path(dump_path);
176 L(FL("setting dump path to %s") % dump_path);
177 // The 'true' means that, e.g., if we're running checkout,
178 // then it's okay for dumps to go into our starting working
179 // dir's _MTN rather than the new workspace dir's _MTN.
180 global_sanity.filename = system_path(dump_path, false).as_external();
181 }
182
183 load_rcfiles();
184}
185
186void
187app_state::set_database(system_path const & filename)
188{
189 if (!filename.empty())
190 {
191 db.set_filename(filename);
192
193 if (found_workspace)
194 {
195 system_path database_option(filename);
196 branch_name branch_option;
197 rsa_keypair_id key_option;
198 system_path keydir_option;
199
200 work.set_ws_options(database_option, branch_option,
201 key_option, keydir_option);
202 }
203 }
204}
205
206void
207app_state::set_key_dir(system_path const & filename)
208{
209 if (!filename.empty())
210 {
211 keys.set_key_dir(filename);
212 }
213}
214
215void
216app_state::make_branch_sticky()
217{
218 branch_is_sticky = true;
219 if (found_workspace)
220 {
221 // Already have a workspace, can (must) write options directly,
222 // because no-one else will do so. If we don't have a workspace
223 // yet, then require_workspace (for instance) will call
224 // write_options when it finds one.
225 write_options();
226 }
227}
228
229project_t &
230app_state::get_project()
231{
232 return project;
233}
234
235void
236app_state::set_root(system_path const & path)
237{
238 require_path_is_directory
239 (path,
240 F("search root '%s' does not exist") % path,
241 F("search root '%s' is not a directory") % path);
242 opts.root = path;
243 L(FL("set search root to %s") % opts.root);
244}
245
246// rc files are loaded after we've changed to the workspace so that
247// _MTN/monotonerc can be loaded between ~/.monotone/monotonerc and other
248// rcfiles.
249
250void
251app_state::load_rcfiles()
252{
253 // Built-in rc settings are defaults.
254
255 if (!opts.nostd)
256 lua.add_std_hooks();
257
258 // ~/.monotone/monotonerc overrides that, and
259 // _MTN/monotonerc overrides *that*.
260
261 if (!opts.norc)
262 {
263 system_path default_rcfile;
264 bookkeeping_path workspace_rcfile;
265 lua.default_rcfilename(default_rcfile);
266 lua.workspace_rcfilename(workspace_rcfile);
267 lua.load_rcfile(default_rcfile, false);
268 lua.load_rcfile(workspace_rcfile, false);
269 }
270
271 // Command-line rcfiles override even that.
272
273 for (vector<utf8>::const_iterator i = opts.extra_rcfiles.begin();
274 i != opts.extra_rcfiles.end(); ++i)
275 {
276 lua.load_rcfile(*i);
277 }
278}
279
280// Local Variables:
281// mode: C++
282// fill-column: 76
283// c-file-style: "gnu"
284// indent-tabs-mode: nil
285// End:
286// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:

Archive Download this file

Branches

Tags

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