Final User interface tweaks to basic commit code (shows dialogs while it does stuff)
[gitlive] / Scm / Repo.js
1 var XObject = imports.XObject.XObject;
2
3 var GLib  = imports.gi.GLib;
4 var File = imports.File.File;
5 // mix of SCM and Repo class from mtrack.
6
7 //var SCM = imports.SCM.SCM;
8
9 _abstract = function() {
10     throw "abstract function not implemented";
11 }
12
13 Repo = XObject.define(
14     function(cfg) {
15         // cal parent?
16         if (typeof(cfg) != 'object') {
17             return;
18         } 
19         XObject.extend(cfg);
20          
21     },
22     Object,
23     {
24             
25         id : null,
26          scmtype : null,
27         repopath : null,
28         browserurl : null,
29         browsertype : null,
30         description : null,
31         parent : '',
32         clonedfrom : null,
33         serverurl : null,
34
35     
36         links_to_add : false,
37         links_to_remove : false,
38         links : false,
39         
40         
41         repopath : '',
42         
43        
44         /** Returns an array keyed by possible branch names.
45         * The data associated with the branches is implementation
46         * defined.
47         * If the SCM does not have a concept of first-class branch
48         * objects, this function returns null */
49         getBranches : _abstract,
50         
51         /** Returns an array keyed by possible tag names.
52         * The data associated with the tags is implementation
53         * defined.
54         * If the SCM does not have a concept of first-class tag
55         * objects, this function returns null */
56         getTags : _abstract,
57         
58         /** Enumerates the files/dirs that are present in the specified
59         * location of the repository that match the specified revision,
60         * branch or tag information.  If no revision, branch or tag is
61         * specified, then the appropriate default is assumed.
62         *
63         * The second and third parameters are optional; the second
64         * parameter is one of 'rev', 'branch', or 'tag', and if specifed
65         * the third parameter must be the corresponding revision, branch
66         * or tag identifier.
67         *
68         * The return value is an array of MTrackSCMFile objects present
69         * at that location/revision of the repository.
70         */
71         readdir : _abstract,
72         
73         /** Queries information on a specific file in the repository.
74         *
75         * Parameters are as for readdir() above.
76         *
77         * This function returns a single MTrackSCMFile for the location
78         * in question.
79         */
80         file : _abstract,
81         
82         /** Queries history for a particular location in the repo.
83         *
84         * Parameters are as for readdir() above, except that path can be
85         * left unspecified to query the history for the entire repo.
86         *
87         * The limit parameter limits the number of entries returned; it it is
88         * a number, it specifies the number of events, otherwise it is assumed
89         * to be a date in the past; only events since that date will be returned.
90         *
91         * Returns an array of MTrackSCMEvent objects.
92         */
93         history : _abstract,
94         
95         /** Obtain the diff text representing a change to a file.
96         *
97         * You may optionally provide one or two revisions as context.
98         *
99         * If no revisions are passed in, then the change associated
100         * with the location will be assumed.
101         *
102         * If one revision is passed, then the change associated with
103         * that event will be assumed.
104         *
105         * If two revisions are passed, then the difference between
106         * the two events will be assumed.
107         */
108         diff : _abstract,
109         
110         /** Determine the next and previous revisions for a given
111         * changeset.
112         *
113         * Returns an array: the 0th element is an array of prior revisions,
114         * and the 1st element is an array of successor revisions.
115         *
116         * There will usually be one prior and one successor revision for a
117         * given change, but some SCMs will return multiples in the case of
118         * merges.
119         */
120         getRelatedChanges : _abstract,
121         
122         /** Returns a working copy object for the repo
123         *
124         * The intended purpose is to support wiki page modifications, and
125         * as such, is not meant to be an especially efficient means to do so.
126         */
127         getWorkingCopy : _abstract,
128         
129         /** Returns meta information about the SCM type; this is used in the
130         * UI and tooling to let the user know their options.
131         *
132         * Returns an array with the following keys:
133         * 'name' => 'Mercurial', // human displayable name
134         * 'tools' => array('hg'), // list of tools to find during setup
135         */
136         getSCMMetaData : _abstract,
137         
138         /** Returns the default 'root' location in the repository.
139         * For SCMs that have a concept of branches, this is the empty string.
140         * For SCMs like SVN, this is the trunk dir */
141         getDefaultRoot : function() {
142              return '';
143         },
144
145         
146           
147         
148         /* takes an MTrackSCM as a parameter because in some bootstrapping
149          * cases, we're actually MTrack_Repo and not the end-class.
150          * MTrack_Repo calls the end-class method and passes itself in for
151          * context */
152         reconcileRepoSettings  : _abstract,
153         
154         
155         
156         
157         getBrowseRootName   : _abstract, 
158         /***
159          *
160          * resolve Revision
161          *
162          * @param {string} rev - a fixed revision - always returns this if it is not false;
163          * @param {string} object [rev|branch|tag]- object type
164          * @param {ident} object id (eg. rev nun, branch name, tag name)
165          *
166          *
167          */
168         resolveRevision :function(rev, object, ident)
169         {
170             if (rev !== false) {
171                 return rev;
172             }
173             
174             if (object === false) {
175                 return false;
176             }
177             
178             switch (object) {
179                 case 'rev':
180                     rev = ident;
181                     break;
182                 
183                 case 'branch':
184                     
185                     // technically we should check it exists..
186                     rev = ident;
187                     break;
188                     //var branches = this.getBranches();
189                     // branches is now an array - not a map.
190                      
191                     //rev = typeof(branches[ident]) == 'undefined' ? false : branches[ident];
192                     //break;
193                 
194                 case 'tag':
195                     tags = this.getTags();
196                     rev = typeof(tags[ident]) == 'undefined' ? false : tags[ident];
197                     break;
198             }
199             if (rev === false) {
200                 throw   "don't know which revision to use (rev,object,ident) got" + object;
201             }
202             return rev;
203         }
204         
205     
206      /*
207     
208     function reconcileRepoSettings()
209     {
210         $c = self::Factory(array('scmtype'=>$this->scmtype));
211         $s->reconcileRepoSettings($this);
212     }
213     
214     function getServerURL()
215     {
216         if ($this->serverurl) {
217             return $this->serverurl;
218         }
219         
220         return null;
221     }
222
223     function getCheckoutCommand() {
224         $url = $this->getServerURL();
225         if (strlen($url)) {
226           return $this->scmtype . ' clone ' . $this->getServerURL();
227         }
228         return null;
229     }
230
231     function canFork() {
232         return false;
233     }
234
235     function getWorkingCopy() {
236          throw new Exception("cannot getWorkingCopy from a generic repo object");
237     }
238     /*
239     function deleteRepo(MTrackChangeset $CS) {
240         MTrackDB::q('delete from repos where repoid = ?', $this->repoid);
241         mtrack_rmdir($this->repopath);
242     }
243      
244   
245
246 // these are needed just to implement the abstract interface..
247     function getBranches() {}
248     function getTags() {}
249     function readdir($path, $object = null, $ident = null) {}
250     function file($path, $object = null, $ident = null) {}
251     function history($path, $limit = null, $object = null, $ident = null){}
252     function diff($path, $from = null, $to = null) {}
253     function getRelatedChanges($revision) {}
254     function getSCMMetaData() { return null; }
255     /**
256      *  converts a commit log message (cached locally into a working object..)
257      *  see Browse.php
258      */
259     /*
260     function commitLogToEvent($str) {
261         throw new Exception("no implementation for commitLogToEvent");
262     }
263     */
264 });
265
266
267 /*
268  
269     static $scms = array();
270     static function factory($ar)
271     {
272         //print_r($ar);
273         $type = ucfirst($ar['scmtype']);
274         $fn = 'MTrack/SCM/'.$type .'/Repo.php';
275         $cls = 'MTrack_SCM_'.$type .'_Repo';
276         require_once $fn;
277         
278         $ret = new $cls($ar);
279         
280         return $ret;
281         
282     }
283     
284  
285     static function getAvailableSCMs()
286     {
287         $ret = array();
288         $ar = scandir(dirname(__FILE__).'/SCM');
289         
290         foreach($ar as $a) {
291             if (empty($a) || $a[0] == '.') {
292                 continue;
293             }
294             $fn = dirname(__FILE__).'/SCM/'.$a.'/Repo.php';
295             if (!file_exists($fn)) {
296                 continue;
297             } 
298             $ret[$a] = MTrack_Repo::factory(array('scmtype'=> $a));
299             
300         }
301         return $ret;
302     }  
303 */
304
305 Repo._list  = false;
306 Repo.list = function()
307 {
308     
309     if (Repo._list !== false) {
310         return Repo._list;
311     }
312     Repo._list  = [];
313     var dir = GLib.get_home_dir() + '/gitlive';
314     var ar = File.list(dir );
315     print(JSON.stringify(ar));
316     ar.forEach(function(f) {
317         if (File.exists(dir + '/' + f +'/.git')) {
318             Repo._list.push(new imports.Scm.Git.Repo.Repo({repopath : dir  +'/' + f }))
319             
320         }
321         
322     });
323     
324     return Repo._list;
325       
326 }
327