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