|
1 # state.py - writing and reading state files in Mercurial |
|
2 # |
|
3 # Copyright 2018 Pulkit Goyal <pulkitmgoyal@gmail.com> |
|
4 # |
|
5 # This software may be used and distributed according to the terms of the |
|
6 # GNU General Public License version 2 or any later version. |
|
7 |
|
8 """ |
|
9 This file contains class to wrap the state for commands and other |
|
10 related logic. |
|
11 |
|
12 All the data related to the command state is stored as dictionary in the object. |
|
13 The class has methods using which the data can be stored to disk in a file under |
|
14 .hg/ directory. |
|
15 |
|
16 We store the data on disk in cbor, for which we use the third party cbor library |
|
17 to serialize and deserialize data. |
|
18 """ |
|
19 |
|
20 from __future__ import absolute_import |
|
21 |
|
22 from .thirdparty import cbor |
|
23 |
|
24 from . import ( |
|
25 util, |
|
26 ) |
|
27 |
|
28 class cmdstate(object): |
|
29 """a wrapper class to store the state of commands like `rebase`, `graft`, |
|
30 `histedit`, `shelve` etc. Extensions can also use this to write state files. |
|
31 |
|
32 All the data for the state is stored in the form of key-value pairs in a |
|
33 dictionary. |
|
34 |
|
35 The class object can write all the data to a file in .hg/ directory and |
|
36 can populate the object data reading that file. |
|
37 |
|
38 Uses cbor to serialize and deserialize data while writing and reading from |
|
39 disk. |
|
40 """ |
|
41 |
|
42 def __init__(self, repo, fname, opts=None): |
|
43 """ repo is the repo object |
|
44 fname is the file name in which data should be stored in .hg directory |
|
45 opts is a dictionary of data of the statefile |
|
46 """ |
|
47 self._repo = repo |
|
48 self.fname = fname |
|
49 if not opts: |
|
50 self.opts = {} |
|
51 else: |
|
52 self.opts = opts |
|
53 |
|
54 def __nonzero__(self): |
|
55 return self.exists() |
|
56 |
|
57 def __getitem__(self, key): |
|
58 return self.opts[key] |
|
59 |
|
60 def __setitem__(self, key, value): |
|
61 updates = {key: value} |
|
62 self.opts.update(updates) |
|
63 |
|
64 def load(self): |
|
65 """load the existing state file into the class object""" |
|
66 op = self._read() |
|
67 self.opts.update(op) |
|
68 |
|
69 def addopts(self, opts): |
|
70 """add more key-value pairs to the data stored by the object""" |
|
71 self.opts.update(opts) |
|
72 |
|
73 def save(self): |
|
74 """write all the state data stored to .hg/<filename> file |
|
75 |
|
76 we use third-party library cbor to serialize data to write in the file. |
|
77 """ |
|
78 with self._repo.vfs(self.fname, 'wb', atomictemp=True) as fp: |
|
79 cbor.dump(self.opts, fp) |
|
80 |
|
81 def _read(self): |
|
82 """reads the state file and returns a dictionary which contain |
|
83 data in the same format as it was before storing""" |
|
84 with self._repo.vfs(self.fname, 'rb') as fp: |
|
85 return cbor.load(fp) |
|
86 |
|
87 def delete(self): |
|
88 """drop the state file if exists""" |
|
89 util.unlinkpath(self._repo.vfs.join(self.fname), ignoremissing=True) |
|
90 |
|
91 def exists(self): |
|
92 """check whether the state file exists or not""" |
|
93 return self._repo.vfs.exists(self.fname) |