GitRepo.vala
[gitlive] / GitRepo.vala
1
2 /**
3  * @class Scm.Git.Repo
4  *
5  * @extends Scm.Repo
6  * 
7  *
8  *
9  */
10 public class GitRepo : Object
11 {
12     
13     public Array<GitMonitorQueue> cmds;
14
15
16     public string gitdir;
17     public string git_working_dir;
18     public bool debug = false;
19
20     /**
21     * index of.. matching gitpath..
22     */
23      public static int indexOf( Array<GitRepo> repos, string gitpath) {
24         // make a fake object to compare against..
25         var test_repo = new GitRepo(gitpath);
26         
27         for(var i =0; i < repos.length; i++) {
28             if (repos.index(i).gitdir == test_repo.gitdir) {
29                 return i;
30             }
31         }
32         return -1;
33     
34     }
35     
36     public static Array<GitRepo> list_cache = null;
37     
38     public static Array<GitRepo> list()
39     {
40         
41         if (Repo._list !== false) {
42             return Repo._list;
43         }
44         Repo._list  = [];
45         var dir = GLib.get_home_dir() + '/gitlive';
46         var ar = File.list(dir );
47         print(JSON.stringify(ar));
48         ar.forEach(function(f) {
49             if (File.exists(dir + '/' + f +'/.git')) {
50                 Repo._list.push(new imports.Scm.Git.Repo.Repo(  {
51                     repopath : dir  +'/' + f,
52                     name : f
53                 }))
54             }
55         });
56         
57         return Repo._list;
58           
59 }
60     
61  
62    
63     /**
64      * constructor:
65      * 
66      * @param {Object} cfg - Configuration
67      *     (basically repopath is currently only critical one.)
68      *
69      */
70      
71     public GitRepo(string path) {
72         // cal parent?
73         this.git_working_dir = path;
74         this.gitdir = path + "/.git";
75         if (!FileUtils.test(this.gitdir , FileTest.IS_DIR)) {
76             this.gitdir = path; // naked...
77         }
78         this.cmds = new  Array<GitMonitorQueue> ();
79         //Repo.superclass.constructor.call(this,cfg);
80         
81     } 
82     /**
83      * add:
84      * add files to track.
85      *
86      * @argument {Array} files the files to add.
87      */
88     public string add ( Array<GitMonitorQueue> files ) throws Error, SpawnError
89     {
90         // should really find out if these are untracked files each..
91         // we run multiple versions to make sure that if one failes, it does not ignore the whole lot..
92         // not sure if that is how git works.. but just be certian.
93         var ret = "";
94         for (var i = 0; i < files.length;i++) {
95             var f = files.index(i).vname;
96             try {
97                 string[] cmd = { "add",    f  };
98                 this.git( cmd );
99             } catch (Error e) {
100                 ret += e.message  + "\n";
101             }        
102
103         }
104         return ret;
105     }
106     
107       /**
108      * remove:
109      * remove files to track.
110      *
111      * @argument {Array} files the files to add.
112      */
113     public string remove  ( Array<GitMonitorQueue> files ) throws Error, SpawnError
114     {
115         // this may fail if files do not exist..
116         // should really find out if these are untracked files each..
117         // we run multiple versions to make sure that if one failes, it does not ignore the whole lot..
118         // not sure if that is how git works.. but just be certian.
119         var ret = "";
120
121         for (var i = 0; i < files.length;i++) {
122             var f = files.index(i).vname;
123             try {
124                 string[] cmd = { "rm",  "-f" ,  f  };
125                 this.git( cmd );
126             } catch (Error e) {
127                 ret += e.message  + "\n";
128             }        
129         }
130
131         return ret;
132
133     }
134     
135     /**
136      * commit:
137      * perform a commit.
138      *
139      * @argument {Object} cfg commit configuration
140      * 
141      * @property {String} name (optional)
142      * @property {String} email (optional)
143      * @property {String} changed (date) (optional)
144      * @property {String} reason (optional)
145      * @property {Array} files - the files that have changed. 
146      * 
147      */
148      
149     public string commit ( string message, Array<GitMonitorQueue> files  ) throws Error, SpawnError
150     {
151         
152
153         /*
154         var env = [];
155
156         if (typeof(cfg.name) != 'undefined') {
157             args.push( {
158                 'author' : cfg.name + ' <' + cfg.email + '>'
159             });
160             env.push(
161                 "GIT_COMMITTER_NAME" + cfg.name,
162                 "GIT_COMMITTER_EMAIL" + cfg.email
163             );
164         }
165
166         if (typeof(cfg.changed) != 'undefined') {
167             env.push("GIT_AUTHOR_DATE= " + cfg.changed )
168             
169         }
170         */
171         string[] args = { "commit", "-m" };
172         args +=  (message.length > 0  ? message : "Changed" );
173         for (var i = 0; i< files.length ; i++ ) {
174             args += files.index(i).vname; // full path?
175         }
176          
177         return this.git(args);
178     }
179     
180     /**
181      * pull:
182      * Fetch and merge remote repo changes into current branch..
183      *
184      * At present we just need this to update the current working branch..
185      * -- maybe later it will have a few options and do more stuff..
186      *
187      */
188     public string pull () throws Error, SpawnError
189     {
190         // should probably hand error conditions better... 
191         string[] cmd = { "pull" };
192         return this.git( cmd );
193
194         
195         
196     }
197     /**
198      * push:
199      * Send local changes to remote repo(s)
200      *
201      * At present we just need this to push the current branch.
202      * -- maybe later it will have a few options and do more stuff..
203      *
204      */
205     public string push () throws Error, SpawnError
206     {
207         // should 
208         return this.git({ "push" });
209         
210     }
211      /**
212      * git:
213      * The meaty part.. run spawn.. with git..
214      *
215      *
216      */
217     
218     public string git(string[] args_in ) throws Error, SpawnError
219     {
220         // convert arguments.
221         
222
223         string[]  args = { "git" };
224         //args +=  "--git-dir";
225         //args +=  this.gitdir;
226         args +=  "--no-pager";
227  
228
229         //if (this.gitdir != this.repopath) {
230         //    args +=   "--work-tree";
231          //   args += this.repopath; 
232         //}
233         for (var i = 0; i < args_in.length;i++) {
234             args += args_in[i];
235         }            
236
237         //this.lastCmd = args.join(" ");
238         //if(this.debug) {
239             stdout.printf( "CWD=%s\n",  this.git_working_dir ); 
240             print(  string.joinv (" ", args)); 
241         //}
242
243         string[]   env = {};
244         string  home = "HOME=" + Environment.get_home_dir() ;
245         env +=  home ;
246         // do not need to set gitpath..
247         //if (File.exists(this.repo + '/.git/config')) {
248             //env.push("GITPATH=" + this.repo );
249         //}
250         
251
252
253         var cfg = new SpawnConfig(this.git_working_dir , args , env);
254         
255
256        // may throw error...
257         var sp = new Spawn(cfg);
258
259         stdout.printf( "GOT: %s\n" , sp.output);
260         // parse output for some commands ?
261         return sp.output;
262     }
263
264 }