]> git.lyx.org Git - features.git/blob - src/VCBackend.h
Comments
[features.git] / src / VCBackend.h
1 // -*- C++ -*-
2 /**
3  * \file VCBackend.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Lars Gullik Bjønnes
8  * \author Pavel Sanda
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #ifndef VC_BACKEND_H
14 #define VC_BACKEND_H
15
16 #include "support/FileName.h"
17
18 #include <string>
19 #include <vector>
20
21 #include "LyXVC.h"
22
23
24 namespace lyx {
25
26 class Buffer;
27
28 /// A simple version control system interface
29 class VCS {
30 public:
31         /// the status of the managed file
32         enum VCStatus {
33                 UNLOCKED,
34                 LOCKED,
35                 NOLOCKING,
36         };
37
38         VCS(Buffer * b) : vcstatus_(NOLOCKING), owner_(b) {}
39         virtual ~VCS() {}
40
41         /// the name of the vc backend
42         virtual std::string vcname() const = 0;
43         /// register a file for version control
44         virtual void registrer(std::string const & msg) = 0;
45         /// can this operation be processed in the current VCS?
46         virtual bool renameEnabled() = 0;
47         /// rename a file. Return non-empty log on success, empty log on failure.
48         virtual std::string rename(support::FileName const &, std::string const &) = 0;
49         /// can this operation be processed in the current VCS?
50         virtual bool copyEnabled() = 0;
51         /// copy a file. Return non-empty log on success, empty log on failure.
52         virtual std::string copy(support::FileName const &, std::string const &) = 0;
53         /// check in the current revision.
54         /// \p log is non-empty on success and may be empty on failure.
55         virtual LyXVC::CommandResult
56         checkIn(std::string const & msg, std::string & log) = 0;
57         /// can this operation be processed in the current VCS?
58         virtual bool checkInEnabled() = 0;
59         /// should a log message provided for next checkin?
60         virtual bool isCheckInWithConfirmation() = 0;
61         /// check out for editing, returns log
62         virtual std::string checkOut() = 0;
63         /// can this operation be processed in the current VCS?
64         virtual bool checkOutEnabled() = 0;
65         /// synchronize with repository, returns log
66         virtual std::string repoUpdate() = 0;
67         /// can this operation be processed in the current VCS?
68         virtual bool repoUpdateEnabled() = 0;
69         /// toggle locking property of the file
70         virtual std::string lockingToggle() = 0;
71         /// can this operation be processed in the current VCS?
72         virtual bool lockingToggleEnabled() = 0;
73         /// revert current edits
74         virtual bool revert() = 0;
75         /// should a confirmation before revert requested?
76         virtual bool isRevertWithConfirmation() = 0;
77         /**
78          * Merge the current with the previous version
79          * in a reverse patch kind of way, so that the
80          * result is to revert the last changes.
81          */
82         virtual void undoLast() = 0;
83         /// can this operation be processed in the current VCS?
84         virtual bool undoLastEnabled() = 0;
85         /**
86          * getLog - read the revision log into the given file
87          * @param fname file name to read into
88          */
89         virtual void getLog(support::FileName const &) = 0;
90         /// return the current version description
91         virtual std::string const versionString() const = 0;
92         /// return the owning buffer
93         Buffer * owner() const { return owner_; }
94         /// return the lock status of this file
95         VCStatus status() const { return vcstatus_; }
96         /// do we need special handling for read-only toggling?
97         /// (also used for check-out operation)
98         virtual bool toggleReadOnlyEnabled() = 0;
99         /// Return revision info specified by the argument.
100         virtual std::string revisionInfo(LyXVC::RevisionInfo const info) = 0;
101         /// can this operation be processed in the current VCS?
102         virtual bool prepareFileRevision(std::string const & rev, std::string & f) = 0;
103         /// can this operation be processed in the current VCS?
104         virtual bool prepareFileRevisionEnabled() = 0;
105
106         /// Check the directory given in start and all parent directories
107         /// for the existence of some other file
108         /// \param start : where we start looking (we will strip the filename if given
109         ///                     and just use the directory
110         /// \param file : the directory or file for which to look
111         ///                     Note that this can be e.g. ".git/index", so we will look for the .git
112         ///                     directory and also for an index file in it.
113         /// Returns a FileName object for the found file or else an empty FileName
114         static support::FileName checkParentDirs(support::FileName const & start, std::string const & file);
115
116 protected:
117         /// parse information from the version file
118         virtual void scanMaster() = 0;
119
120         /// Prepare a version identifier suitable for RCS and CVS.
121         /// If needed converts last or relative number to the absolute revision.
122         bool makeRCSRevision(std::string const &version, std::string &revis) const;
123
124         /// GUI container for doVCCommandCall
125         int doVCCommand(std::string const & cmd, support::FileName const & path, bool reportError = true);
126         /**
127          * doVCCommandCall - call out to the version control utility
128          * @param cmd the command to execute
129          * @param path the path from which to execute
130          * @return exit status
131          */
132         static int doVCCommandCall(std::string const & cmd, support::FileName const & path);
133
134         /**
135          * The master VC file. For RCS this is *,v or RCS/ *,v. master should
136          * have full path.
137          */
138         support::FileName master_;
139
140         /// The status of the VC controlled file.
141         VCStatus vcstatus_;
142
143         /// The buffer using this VC
144         Buffer * const owner_;
145 };
146
147
148 ///
149 class RCS : public VCS {
150 public:
151
152         explicit
153         RCS(support::FileName const & m, Buffer * b);
154
155         /// Determine whether the file is under RCS control
156         /// \return the file containing the meta-data (FILE,v) if so, else empty
157         static support::FileName const findFile(support::FileName const & file);
158
159         /// get file from repo, the caller must ensure that it does not exist locally
160         static bool retrieve(support::FileName const & file);
161
162         std::string vcname() const override { return "RCS"; };
163
164         void registrer(std::string const & msg) override;
165
166         bool renameEnabled() override;
167
168         std::string rename(support::FileName const &, std::string const &) override;
169
170         bool copyEnabled() override;
171
172         std::string copy(support::FileName const &, std::string const &) override;
173
174         LyXVC::CommandResult
175         checkIn(std::string const & msg, std::string & log) override;
176
177         bool checkInEnabled() override;
178
179         bool isCheckInWithConfirmation() override;
180
181         std::string checkOut() override;
182
183         bool checkOutEnabled() override;
184
185         std::string repoUpdate() override;
186
187         bool repoUpdateEnabled() override;
188
189         std::string lockingToggle() override;
190
191         bool lockingToggleEnabled() override;
192
193         bool revert() override;
194
195         bool isRevertWithConfirmation() override;
196
197         void undoLast() override;
198
199         bool undoLastEnabled() override;
200
201         void getLog(support::FileName const &) override;
202
203         std::string const versionString() const override {
204                 return "RCS: " + version_;
205         }
206
207         bool toggleReadOnlyEnabled() override;
208
209         std::string revisionInfo(LyXVC::RevisionInfo const info) override;
210
211         bool prepareFileRevision(std::string const & rev, std::string & f) override;
212
213         bool prepareFileRevisionEnabled() override;
214
215 protected:
216         void scanMaster() override;
217 private:
218         bool getRevisionInfo();
219         /**
220          * The version of the VC file. I am not sure if this can be a
221          * string or if it must be a float/int.
222          */
223         std::string version_;
224         /// The user currently keeping the lock on the VC file (or "Unlocked").
225         std::string locker_;
226         /// Cache for revision info.
227         std::string rev_date_cache_;
228         ///
229         std::string rev_time_cache_;
230         ///
231         std::string rev_author_cache_;
232 };
233
234
235 ///
236 class CVS : public VCS {
237 public:
238         ///
239         explicit
240         CVS(support::FileName const & m, Buffer * b);
241
242         /// Determine whether the file is under CVS control
243         /// \return the file containing the meta-data (CVS/entries) if so, else empty
244         static support::FileName const findFile(support::FileName const & file);
245
246         /// get file from repo, the caller must ensure that it does not exist locally
247         static bool retrieve(support::FileName const & file);
248
249         std::string vcname() const override { return "CVS"; };
250
251         void registrer(std::string const & msg) override;
252
253         bool renameEnabled() override;
254
255         std::string rename(support::FileName const &, std::string const &) override;
256
257         bool copyEnabled() override;
258
259         std::string copy(support::FileName const &, std::string const &) override;
260
261         LyXVC::CommandResult
262         checkIn(std::string const & msg, std::string & log) override;
263
264         bool checkInEnabled() override;
265
266         bool isCheckInWithConfirmation() override;
267
268         std::string checkOut() override;
269
270         bool checkOutEnabled() override;
271
272         std::string repoUpdate() override;
273
274         bool repoUpdateEnabled() override;
275
276         std::string lockingToggle() override;
277
278         bool lockingToggleEnabled() override;
279
280         bool isRevertWithConfirmation() override;
281
282         bool revert() override;
283
284         void undoLast() override;
285
286         bool undoLastEnabled() override;
287
288         void getLog(support::FileName const &) override;
289
290         /// Check for messages in cvs output.
291         /// Returns conflict line.
292         std::string scanLogFile(support::FileName const & f, std::string & status);
293
294         std::string const versionString() const override {
295                 return "CVS: " + version_;
296         }
297
298         bool toggleReadOnlyEnabled() override;
299
300         std::string revisionInfo(LyXVC::RevisionInfo const info) override;
301
302         bool prepareFileRevision(std::string const & rev, std::string & f) override;
303
304         bool prepareFileRevisionEnabled() override;
305
306 protected:
307         void scanMaster() override;
308         /// the mode of operation for some VC commands
309         enum OperationMode {
310                 Directory = 0,
311                 File = 1
312         };
313         /// possible status values of file
314         enum CvsStatus {
315                 UpToDate = 0,
316                 LocallyModified = 1,
317                 LocallyAdded = 2,
318                 NeedsMerge = 3,
319                 NeedsCheckout = 4,
320                 NoCvsFile = 5,
321                 StatusError = 6
322         };
323
324 private:
325         // revision number from scanMaster
326         std::string version_;
327
328         /**
329          * doVCCommandWithOutput
330          * - call out to the version control utility
331          * - it is able to collect output in a file
332          * @param cmd the command to execute
333          * @param path the path from which to execute
334          * @param output the path where to store output
335          * @param reportError display of low level error message dialog
336          * @return exit status
337          */
338         int doVCCommandWithOutput(std::string const & cmd,
339                         support::FileName const & path,
340                         support::FileName const & output,
341                         bool reportError = true);
342         static int doVCCommandCallWithOutput(std::string const & cmd,
343                         support::FileName const & path,
344                         support::FileName const & output);
345
346         /// return the quoted pathname if Directory or filename if File
347         std::string const getTarget(OperationMode opmode) const;
348         /// collect the diff of file or directory against repository
349         /// result is placed in temporary file
350         void getDiff(OperationMode opmode, support::FileName const & tmpf);
351         /// make the file ready for editing:
352         /// save a copy in CVS/Base and change file permissions to rw if needed
353         int edit();
354         /// revert the edit operation
355         int unedit();
356         /// retrieve repository changes into working copy
357         int update(OperationMode opmode, support::FileName const & tmpf);
358         /// check readonly state for file
359         /// assume true when file is writable
360         bool isLocked() const;
361         /// query and parse the cvs status of file
362         CvsStatus getStatus();
363         /// convert enum to string
364         docstring toString(CvsStatus status) const;
365
366         /// cache the info values of current file revision
367         /// author, date and time of commit
368         std::string rev_author_cache_;
369         std::string rev_date_cache_;
370         std::string rev_time_cache_;
371         /// fills the cache values, returns true if successfull.
372         void getRevisionInfo();
373         bool have_rev_info_;
374 };
375
376
377 ///
378 class SVN : public VCS {
379 public:
380         ///
381         explicit
382         SVN(support::FileName const & m, Buffer * b);
383
384         /// Determine whether the file is under SVN control
385         /// \return the file itself if so, else empty
386         static support::FileName const findFile(support::FileName const & file);
387
388         /// get file from repo, the caller must ensure that it does not exist locally
389         static bool retrieve(support::FileName const & file);
390
391         std::string vcname() const override { return "SVN"; };
392
393         void registrer(std::string const & msg) override;
394
395         bool renameEnabled() override;
396
397         std::string rename(support::FileName const &, std::string const &) override;
398
399         bool copyEnabled() override;
400
401         std::string copy(support::FileName const &, std::string const &) override;
402
403         LyXVC::CommandResult
404         checkIn(std::string const & msg, std::string & log) override;
405
406         bool checkInEnabled() override;
407
408         bool isCheckInWithConfirmation() override;
409
410         std::string checkOut() override;
411
412         bool checkOutEnabled() override;
413
414         std::string repoUpdate() override;
415
416         bool repoUpdateEnabled() override;
417
418         std::string lockingToggle() override;
419
420         bool lockingToggleEnabled() override;
421
422         bool revert() override;
423
424         bool isRevertWithConfirmation() override;
425
426         void undoLast() override;
427
428         bool undoLastEnabled() override;
429
430         void getLog(support::FileName const &) override;
431
432         std::string const versionString() const override {
433                 return "SVN: " + rev_file_cache_;
434         }
435
436         bool toggleReadOnlyEnabled() override;
437
438         std::string revisionInfo(LyXVC::RevisionInfo const info) override;
439
440         bool prepareFileRevision(std::string const & rev, std::string & f) override;
441
442         bool prepareFileRevisionEnabled() override;
443
444 protected:
445         void scanMaster() override;
446         /// Check for messages in svn output. Returns error.
447         std::string scanLogFile(support::FileName const & f, std::string & status);
448         /// checks locking policy and setup locked_mode_
449         bool checkLockMode();
450         /// is the loaded file locked?
451         bool isLocked() const;
452         /// acquire/release write lock for the current file
453         bool fileLock(bool lock, support::FileName const & tmpf, std::string & status);
454         /// Check in files \p f with log \p msg
455         LyXVC::CommandResult checkIn(std::vector<support::FileName> const & f,
456                                      std::string const & msg, std::string & log);
457
458 private:
459         /// is the loaded file under locking policy?
460         bool locked_mode_;
461         /**
462          * Real code for obtaining file revision info. Fills all file-related caches
463          * and returns true if successfull.
464          * "?" is stored in rev_file_cache_ as a signal if request for obtaining info
465          * was already unsuccessful.
466          */
467         bool getFileRevisionInfo();
468         /// cache for file revision number, "?" if already unsuccessful, isNumber==true
469         std::string rev_file_cache_;
470         /// cache for author of last commit
471         std::string rev_author_cache_;
472         /// cache for date of last commit
473         std::string rev_date_cache_;
474         /// cache for time of last commit
475         std::string rev_time_cache_;
476         /// fills rev_tree_cache_, returns true if successfull.
477         bool getTreeRevisionInfo();
478         /// cache for tree revision number, "?" if already unsuccessful
479         std::string rev_tree_cache_;
480 };
481
482
483 /**
484  * Very basic git support:
485  * Remote repos are completely ignored, only the local tree is considered.
486  * How push and pull could be integrated with the LyX VCS interface needs
487  * to be discussed.
488  */
489 class GIT : public VCS {
490 public:
491         ///
492         explicit
493         GIT(support::FileName const & m, Buffer * b);
494
495         /// Determine whether the file is under RCS control
496         /// \return the file itself if so, else empty
497         static support::FileName const findFile(support::FileName const & file);
498
499         /// get file from repo, the caller must ensure that it does not exist locally
500         static bool retrieve(support::FileName const & file);
501
502         std::string vcname() const override { return "GIT"; };
503
504         void registrer(std::string const & msg) override;
505
506         bool renameEnabled() override;
507
508         std::string rename(support::FileName const &, std::string const &) override;
509
510         bool copyEnabled() override;
511
512         std::string copy(support::FileName const &, std::string const &) override;
513
514         LyXVC::CommandResult
515         checkIn(std::string const & msg, std::string & log) override;
516
517         bool checkInEnabled() override;
518
519         bool isCheckInWithConfirmation() override;
520
521         std::string checkOut() override;
522
523         bool checkOutEnabled() override;
524
525         std::string repoUpdate() override;
526
527         bool repoUpdateEnabled() override;
528
529         std::string lockingToggle() override;
530
531         bool lockingToggleEnabled() override;
532
533         bool revert() override;
534
535         bool isRevertWithConfirmation() override;
536
537         void undoLast() override;
538
539         bool undoLastEnabled() override;
540
541         void getLog(support::FileName const &) override;
542
543         std::string const versionString() const override {
544                 return "GIT: ?";
545         }
546
547         bool toggleReadOnlyEnabled() override;
548
549         std::string revisionInfo(LyXVC::RevisionInfo const info) override;
550
551         bool prepareFileRevision(std::string const & rev, std::string & f) override;
552
553         bool prepareFileRevisionEnabled() override;
554
555 protected:
556         void scanMaster() override;
557         /// Check for messages in svn output. Returns error.
558         std::string scanLogFile(support::FileName const & f, std::string & status);
559         /// Check in files \p f with log \p msg
560         LyXVC::CommandResult checkIn(std::vector<support::FileName> const & f,
561                                      std::string const & msg, std::string & log);
562
563 private:
564         /**
565          * Real code for obtaining file revision info. Fills all file-related caches
566          * and returns true if successfull.
567          * "?" is stored in rev_file_cache_ as a signal if request for obtaining info
568          * was already unsuccessful.
569          */
570         bool getFileRevisionInfo();
571         /// cache for file revision number, "?" if already unsuccessful, isNumber==true
572         std::string rev_file_cache_;
573         /// cache for abbreviated file revision number, "?" if already unsuccessful, isNumber==true
574         std::string rev_file_abbrev_cache_;
575         /// cache for author of last commit
576         std::string rev_author_cache_;
577         /// cache for date of last commit
578         std::string rev_date_cache_;
579         /// cache for time of last commit
580         std::string rev_time_cache_;
581         /// fills rev_tree_cache_, returns true if successfull.
582         bool getTreeRevisionInfo();
583         /// cache for tree revision number, "?" if already unsuccessful
584         std::string rev_tree_cache_;
585 };
586
587 } // namespace lyx
588
589 #endif // VCBACKEND_H