Fix #7286 - live testing issues
[roobuilder] / src / Application.vala
1
2  
3         public class AppSettings : Object
4         {
5
6                 
7                 
8                 // what are we going to have as settings?
9                 public string roo_html_dir { get; set; }
10
11                 public AppSettings()
12                 {
13                         this.notify.connect(() => {
14                                 this.save();
15                         });
16                 }
17
18                 public static AppSettings factory()
19                 {
20                          
21                         var setting_file = BuilderApplication.configDirectory() + "/builder.settings";
22                         
23                         if (!FileUtils.test(setting_file, FileTest.EXISTS)) {
24                                  return new AppSettings();
25                         }
26                         string data; 
27                         FileUtils.get_contents(setting_file, out data);
28                         return Json.gobject_from_data (typeof (AppSettings), data) as AppSettings;
29                 }
30                 public void save()
31                 {
32                         var dirname = GLib.Environment.get_home_dir() + "/.Builder";
33                         var setting_file = dirname + "/builder.settings";
34                         string data = Json.gobject_to_data (this, null);
35                         print("saving application settings\n");
36                         FileUtils.set_contents(setting_file,   data);
37                 }
38
39                 
40         }
41         
42         
43         public static BuilderApplication application = null;
44         
45         public class BuilderApplication : Gtk.Application
46         {
47                 
48                 // options - used when builder is run as a compiler
49                 // we have to spawn ourself as a compiler as just running libvala
50                 // as a task to check syntax causes memory leakage..
51                 // 
52                 const OptionEntry[] options = {
53                 
54                         
55                         { "project", 0, 0, OptionArg.STRING, ref opt_compile_project, "Compile a project", null },
56                         { "target", 0, 0, OptionArg.STRING, ref opt_compile_target, "Target to build", null },
57                         { "skip-file", 0, 0, OptionArg.STRING, ref opt_compile_skip ,"For test compiles do not add this (usually used in conjunction with add-file ", null },
58                         { "add-file", 0, 0, OptionArg.STRING, ref opt_compile_add, "Add this file to compile list", null },
59                         { "output", 0, 0, OptionArg.STRING, ref opt_compile_output, "output binary file path", null },
60                         { "debug", 0, 0, OptionArg.NONE, ref opt_debug, "Show debug messages", null },
61                         { "pull-resources", 0, 0, OptionArg.NONE, ref opt_pull_resources, "Fetch the online resources", null },                 
62             
63             // some testing code.
64             { "list-projects", 0, 0,  OptionArg.NONE, ref opt_list_projects, "List Projects", null },
65             { "list-files", 0, 0,  OptionArg.NONE, ref  opt_list_files, "List Files (in a project", null},
66             { "bjs", 0, 0, OptionArg.STRING, ref opt_bjs_compile, "convert bjs file (use all to convert all of them and compare output)", null },
67             { "bjs-glade", 0, 0, OptionArg.NONE, ref opt_bjs_compile_glade, "output glade", null },
68             { "bjs-test-all", 0, 0, OptionArg.NONE, ref opt_bjs_test, "Test all the BJS files to see if the new parser/writer would change anything", null },            
69             { "bjs-target", 0, 0, OptionArg.STRING, ref opt_bjs_compile_target, "convert bjs file to tareet  : vala / js", null },
70             { "test", 0, 0, OptionArg.STRING, ref opt_test, "run a test use 'help' to list the available tests", null },
71             
72                         { null }
73                 };
74                 public static string opt_compile_project;
75                 public static string opt_compile_target;
76                 public static string opt_compile_skip;
77                 public static string opt_compile_add;
78                 public static string opt_compile_output;
79         public static string opt_bjs_compile;
80
81         public static string opt_bjs_compile_target;
82         public static string opt_test;        
83                 public static bool opt_debug = false;
84                 public static bool opt_list_projects = false;
85                 public static bool opt_list_files = false;
86                 public static bool opt_pull_resources = false;
87                 public static bool opt_bjs_compile_glade = false;
88         public static bool opt_bjs_test = false;                
89                 public static string _self;
90                 
91                 public enum Target {
92                     INT32,
93                     STRING,
94                     ROOTWIN
95                 }
96
97
98                 public const Gtk.TargetEntry[] targetList = {
99                     { "INTEGER",    0, Target.INT32 },
100                     { "STRING",     0, Target.STRING },
101                     { "application/json",     0, Target.STRING },                       
102                     { "text/plain", 0, Target.STRING },
103                     { "application/x-rootwindow-drop", 0, Target.ROOTWIN }
104                 };
105                 public AppSettings settings = null;
106
107         
108                 public BuilderApplication (  string[] args)
109                 {
110                         
111                         _self = FileUtils.read_link("/proc/self/exe");
112                         GLib.debug("SELF = %s", _self);
113                         
114                         Object(
115                                application_id: "org.roojs.app-builder",
116                                 flags: ApplicationFlags.FLAGS_NONE
117                         );
118                                          
119                         configDirectory();
120                         this.settings = AppSettings.factory();  
121                         var opt_context = new OptionContext ("Application Builder");
122                         
123                         try {
124                                 opt_context.set_help_enabled (true);
125                                 opt_context.add_main_entries (options, null);
126                                 opt_context.parse (ref args);
127                                  
128                                 
129                         } catch (OptionError e) {
130                                 stdout.printf ("error: %s\n", e.message);
131                                 stdout.printf ("Run '%s --help' to see a full list of available command line options.\n %s", 
132                                                          args[0], opt_context.get_help(true,null));
133                                 GLib.Process.exit(Posix.EXIT_FAILURE);
134                                  
135                         }
136                         this.initDebug();
137                         this.runTests();                        
138                         this.pullResources();
139                         
140                 Project.Project.loadAll();
141                         this.listProjects();
142                         var cur_project = this.compileProject();
143                         this.listFiles(cur_project);
144                         this.testBjs(cur_project);
145                         this.compileBjs(cur_project);
146                         this.compileVala();
147
148                 }
149
150
151                 
152                 public static BuilderApplication  singleton(  string[] args)
153                 {
154                         if (application==null) {
155                                 application = new BuilderApplication(  args);
156  
157                         
158                         }
159                         return application;
160                 }
161
162                 
163                 public static string configDirectory()
164                 {
165                         var dirname = GLib.Environment.get_home_dir() + "/.Builder";
166                 
167                         if (!FileUtils.test(dirname,FileTest.IS_DIR)) {
168                                 var dir = File.new_for_path(dirname);
169                                 dir.make_directory();    
170                         }
171                         if (!FileUtils.test(dirname + "/resources",FileTest.IS_DIR)) {
172                                 var dir = File.new_for_path(dirname + "/resources");
173                                 dir.make_directory();    
174                         }
175
176                 
177                         return dirname;
178                 }
179                 
180                 
181                 // --------------- non static...
182                 
183                 void initDebug() 
184                 {
185                 
186                         if (BuilderApplication.opt_debug  || BuilderApplication.opt_compile_project == null) {
187                                 GLib.Log.set_handler(null, 
188                                         GLib.LogLevelFlags.LEVEL_DEBUG | GLib.LogLevelFlags.LEVEL_WARNING, 
189                                         (dom, lvl, msg) => {
190                                         print("%s: %s\n", dom, msg);
191                                 });
192                         }
193                         
194                 
195                 }
196                 void listProjects()
197                 {
198                         if (!BuilderApplication.opt_list_projects) {
199                                 return;
200                         }
201                         print("Projects\n %s\n", Project.Project.listAllToString());
202                         GLib.Process.exit(Posix.EXIT_SUCCESS);
203                 
204                 }
205                 Project.Project? compileProject()
206                 {
207                         
208                         if (BuilderApplication.opt_compile_project == null) {
209                                 return null;
210                          }
211                         Project.Project cur_project = null;
212                         cur_project = Project.Project.getProjectByHash( BuilderApplication.opt_compile_project);
213                         
214                         if (cur_project == null) {
215                                 GLib.error("invalid project %s, use --list-projects to show project ids",BuilderApplication.opt_compile_project);
216                         }
217                         cur_project.scanDirs();
218                                 
219                         return cur_project;
220                 
221                 }
222                 void listFiles(Project.Project? cur_project)
223                 {
224                         if (!BuilderApplication.opt_list_files) {
225                                 return;
226                         }
227                         if (cur_project == null) {
228                                 GLib.error("missing project, use --project to select which project");
229                         }
230                         print("Files for %s\n %s\n", cur_project.name, cur_project.listAllFilesToString());
231                         GLib.Process.exit(Posix.EXIT_SUCCESS);
232                         
233                 }
234                 
235                 /**
236                  Test to see if the internal BJS reader/writer still outputs the same files.
237                  -- probably need this for the generator as well.
238                 */
239                 
240                 void testBjs(Project.Project? cur_project)
241                 {
242                         if (!BuilderApplication.opt_bjs_test) {
243                                 return;
244                         }
245                         if (cur_project == null) {
246                                 GLib.error("missing project, use --project to select which project");
247                         }
248                         print("Checking files\n");
249                         var ar = cur_project.sortedFiles();
250                         foreach(var file in ar) {
251                                 string oldstr;
252
253                                 file.loadItems();
254                                 GLib.FileUtils.get_contents(file.path, out oldstr);                             
255                                 var outstr = file.toJsonString();
256                                 if (outstr != oldstr) { 
257                                         
258                                         GLib.FileUtils.set_contents("/tmp/" + file.name ,   outstr);
259                                         print("meld  %s /tmp/%s\n", file.path,  file.name);
260                                         //GLib.Process.exit(Posix.EXIT_SUCCESS);                
261                                 }
262                                 print("# Files match %s\n", file.name);
263                                 
264                         }
265                         
266                         print("All files pass");
267                         GLib.Process.exit(Posix.EXIT_SUCCESS);
268                 }
269                 
270                 void compileBjs(Project.Project? cur_project)
271                 {
272                         if (BuilderApplication.opt_bjs_compile == null) {
273                                 return;
274                         }
275                         if (cur_project == null) {
276                                 GLib.error("missing project, use --project to select which project");
277                         }
278                         
279                         if (BuilderApplication.opt_bjs_compile == "all") {
280                                 var ar = cur_project.sortedFiles();
281                                 foreach(var file in ar) {
282                                         string oldstr;
283
284                                         file.loadItems();
285                                         var oldfn = file.targetName();
286                                         GLib.FileUtils.get_contents(oldfn, out oldstr);
287                                                                         
288                                         var outstr = file.toSourceCode();
289                                         if (outstr != oldstr) { 
290                                                 
291                                                 GLib.FileUtils.set_contents("/tmp/" + file.name   + ".out",   outstr);
292                                                 print("meld   %s /tmp/%s\n", oldfn,  file.name + ".out");
293                                                 //GLib.Process.exit(Posix.EXIT_SUCCESS);                
294                                         }
295                                         print("# Files match %s\n", file.name);
296                                         
297                                 }
298                                 GLib.Process.exit(Posix.EXIT_SUCCESS);
299                         
300                         }
301                         
302                         
303                         
304                         var file = cur_project.getByName(BuilderApplication.opt_bjs_compile);
305                         if (file == null) {
306                                 // then compile them all, and compare them...
307                                 
308                         
309                         
310                         
311                         
312                         
313                                 GLib.error("missing file %s in project %s", BuilderApplication.opt_bjs_compile, cur_project.name);
314                         }
315                         file.loadItems();
316                                                 
317                         if (BuilderApplication.opt_bjs_compile_glade) {
318                                 var str = file.toGlade();
319                                 print("%s", str);
320                                 GLib.Process.exit(Posix.EXIT_SUCCESS);
321                         }
322                         
323                         //BuilderApplication.compileBjs();
324
325                         var str = file.toSourceCode();
326                           
327                           
328                         if (!BuilderApplication.opt_debug) {
329                                 print("%s", str);
330                                 GLib.Process.exit(Posix.EXIT_SUCCESS);
331                         }
332                         
333                         // dump the node tree
334                         file.tree.dumpProps();
335                         
336                         
337                         
338                         
339                         
340                         var str_ar = str.split("\n");
341                         for(var i =0;i<str_ar.length;i++) {
342                                 var node = file.tree.lineToNode(i+1);
343                                 var prop = node == null ? null : node.lineToProp(i+1);
344                                 print("%d: %s   :  %s\n", 
345                                         i+1, 
346                                         node == null ? "......"  : (prop == null ? "????????" : prop),
347                                         str_ar[i]
348                                 );
349                         }
350                         
351                         GLib.Process.exit(Posix.EXIT_SUCCESS);
352                 }
353                 
354                 void compileVala()
355                 {
356                         if (BuilderApplication.opt_compile_target == null) {
357                                 return;
358                         }
359                         Palete.ValaSourceCompiler.buildApplication();
360                 
361                         GLib.Process.exit(Posix.EXIT_SUCCESS);
362         
363                 }
364                 void pullResources()
365                 {
366                         if (!opt_pull_resources) {
367                                 return;
368                         }
369                         var loop = new MainLoop();
370                         Resources.singleton().updateProgress.connect((p,t) => {
371                                 print("Got %d/%d", (int) p,(int)t);
372                                 if (p == t) {
373                                         loop.quit();
374                                 }
375                         });
376                         Resources.singleton().fetchStart();     
377                         loop.run();
378                         GLib.Process.exit(Posix.EXIT_SUCCESS);
379                 }
380                 
381                 
382                 void runTests()
383                 {
384                         if (opt_test == null) {
385                                 return;
386                         }
387                         switch(opt_test) {
388                                 case "help":
389                                         print("""
390 help             - list available tests
391 flutter-project  - create a flutter project in /tmp/test-flutter
392 """);           
393                                         break;
394                                 case "flutter-project":
395                                 Project.Project.loadAll();
396                                         var p =   Project.Project.factory("Flutter", "/tmp/test-flutter");
397                                         /*var pa = p.palete as Palete.Flutter;
398                                         pa.dumpusage();
399                                          var ar = pa.getChildList("material.Scaffold");
400                                         GLib.debug("childlist for material.Scaffold is %s", 
401                                                 string.joinv( "\n-- ", ar)
402                                         );
403                                         ar = pa.getDropList("material.MaterialApp");
404                                         GLib.debug("droplist for material.MaterialApp is %s", 
405                                                 string.joinv( "\n-- ", ar)
406                                         );
407                                         */
408                                         break;
409                                         
410                                 default:
411                                         print("Invalid test\n");
412                                         break;
413
414
415                         }
416                         GLib.Process.exit(Posix.EXIT_SUCCESS);          
417                 }
418                 
419          
420         } 
421
422  
423
424