monotone

monotone Mtn Source Tree

Root/manifest.cc

1// copyright (C) 2002, 2003 graydon hoare <graydon@pobox.com>
2// all rights reserved.
3// licensed to the public under the terms of the GNU GPL (>= 2)
4// see the file COPYING for details
5
6#include <string>
7#include <iterator>
8#include <sstream>
9#include <iostream>
10#include <algorithm>
11#include <iterator>
12
13#include <boost/regex.hpp>
14
15#include <boost/filesystem/path.hpp>
16#include <boost/filesystem/operations.hpp>
17#include <boost/filesystem/convenience.hpp>
18
19#include "app_state.hh"
20#include "file_io.hh"
21#include "manifest.hh"
22#include "transforms.hh"
23#include "sanity.hh"
24
25// this file defines the class of manifest_map objects, and various comparison
26// and i/o functions on them. a manifest specifies exactly which versions
27// of each file reside at which path location in a given tree.
28
29using namespace boost;
30using namespace std;
31
32string const manifest_file_name("manifest");
33
34// building manifest_maps
35
36class
37manifest_map_builder : public tree_walker
38{
39 app_state & app;
40 manifest_map & man;
41public:
42 manifest_map_builder(app_state & a, manifest_map & m);
43 virtual void visit_file(file_path const & path);
44};
45
46manifest_map_builder::manifest_map_builder(app_state & a, manifest_map & m)
47 : app(a), man(m)
48{
49}
50
51void
52manifest_map_builder::visit_file(file_path const & path)
53{
54 if (app.lua.hook_ignore_file(path))
55 return;
56 hexenc<id> ident;
57 L(F("scanning file %s\n") % path);
58 calculate_ident(path, ident, app.lua);
59 man.insert(manifest_entry(path, file_id(ident)));
60}
61
62/** these seem to be unused
63
64void
65build_manifest_map(file_path const & path,
66 app_state & app,
67 manifest_map & man)
68{
69 man.clear();
70 manifest_map_builder build(app,man);
71 walk_tree(path, build);
72}
73
74void
75build_manifest_map(app_state & app,
76 manifest_map & man)
77{
78 man.clear();
79 manifest_map_builder build(app,man);
80 walk_tree(build);
81}
82
83**/
84
85
86
87void
88build_manifest_map(path_set const & paths,
89 manifest_map & man,
90 app_state & app)
91{
92 man.clear();
93 for (path_set::const_iterator i = paths.begin(); i != paths.end(); ++i)
94 {
95 N(fs::exists(mkpath((*i)())),
96F("file disappeared but exists in manifest: %s") % (*i)());
97 hexenc<id> ident;
98 calculate_ident(*i, ident, app.lua);
99 man.insert(manifest_entry(*i, file_id(ident)));
100 }
101}
102
103
104void
105build_restricted_manifest_map(path_set const & paths,
106 manifest_map const & m_old,
107 manifest_map & m_new,
108 app_state & app)
109{
110 m_new.clear();
111 for (path_set::const_iterator i = paths.begin(); i != paths.end(); ++i)
112 {
113 if (app.restriction_includes(*i))
114 {
115 // compute the current sha1 id for included files
116 N(fs::exists(mkpath((*i)())),
117 F("file disappeared but exists in new manifest: %s") % (*i)());
118 hexenc<id> ident;
119 calculate_ident(*i, ident, app.lua);
120 m_new.insert(manifest_entry(*i, file_id(ident)));
121 }
122 else
123 {
124 // copy the old manifest entry for excluded files
125 manifest_map::const_iterator old = m_old.find(*i);
126 N(old != m_old.end(),
127 F("file restricted but does not exist in old manifest: %s") % *i);
128 m_new.insert(*old);
129 }
130 }
131}
132
133// reading manifest_maps
134
135struct
136add_to_manifest_map
137{
138 manifest_map & man;
139 explicit add_to_manifest_map(manifest_map & m) : man(m) {}
140 bool operator()(match_results<std::string::const_iterator> const & res)
141 {
142 std::string ident(res[1].first, res[1].second);
143 std::string path(res[2].first, res[2].second);
144 file_path pth(path);
145 man.insert(manifest_entry(pth, hexenc<id>(ident)));
146 return true;
147 }
148};
149
150void
151read_manifest_map(data const & dat,
152 manifest_map & man)
153{
154 regex expr("^([[:xdigit:]]{40}) ([^[:space:]].*)$");
155 regex_grep(add_to_manifest_map(man), dat(), expr, match_not_dot_newline);
156}
157
158void
159read_manifest_map(manifest_data const & dat,
160 manifest_map & man)
161{
162 gzip<data> decoded;
163 data decompressed;
164 decode_base64(dat.inner(), decoded);
165 decode_gzip(decoded, decompressed);
166 read_manifest_map(decompressed, man);
167}
168
169
170
171// writing manifest_maps
172
173std::ostream &
174operator<<(std::ostream & out, manifest_entry const & e)
175{
176 return (out << manifest_entry_id(e) << " " << manifest_entry_path(e) << "\n");
177}
178
179
180void
181write_manifest_map(manifest_map const & man,
182 manifest_data & dat)
183{
184 ostringstream sstr;
185 copy(man.begin(),
186 man.end(),
187 ostream_iterator<manifest_entry>(sstr));
188
189 data raw;
190 gzip<data> compressed;
191 base64< gzip<data> > encoded;
192
193 raw = sstr.str();
194 encode_gzip(raw, compressed);
195 encode_base64(compressed, encoded);
196 dat = manifest_data(encoded);
197}
198
199void
200write_manifest_map(manifest_map const & man,
201 data & dat)
202{
203 ostringstream sstr;
204 for (manifest_map::const_iterator i = man.begin();
205 i != man.end(); ++i)
206 sstr << *i;
207 dat = sstr.str();
208}
209
210

Archive Download this file

Branches

Tags

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