Upgrade to ExtJS 4.0.1 - Released 05/18/2011
[extjs.git] / jsbuilder / src / Generator.js
1 load(JSBuilderPath + 'src/Template.js');
2 load(JSBuilderPath + 'src/XTemplate.js');
3
4 Ext.generator = {};
5
6 /**
7  * @class Ext.generator.Base
8  * @extends Object
9  * Base class for all Generators
10  */
11 Ext.generator.Base = Ext.extend(Object, {
12     /**
13      * @cfg {Boolean} pretend True to only output what the generator would do (e.g. which files would be created),
14      * without actually modifying anything on the filesystem.
15      */
16     pretend: false,
17     
18     basePath: '.',
19     
20     constructor: function(config) {
21         Ext.apply(this, config);
22         
23         if (this.args) {
24             this.decodeArgs(this.args);
25         }
26     },
27     
28     /**
29      * Creates an empty directory at the given location
30      * @param {String} path The directory path
31      */
32     mkdir: function() {
33         var length = arguments.length,
34             dirName, i;
35         
36         for (i = 0; i < length; i++) {
37             dirName = this.basePath + "/" + arguments[i];
38             Logger.log("    Creating dir: " + dirName);
39             
40             if (!this.pretend) {
41                 Filesystem.mkdir(dirName);
42             }
43         }
44     },
45     
46     /**
47      * Applies data to an XTemplate, saving its output to the given file name
48      * @param {String} name The name of the template
49      */
50     template: function(name, data, filename) {
51         Logger.log("    Creating file: " + filename);
52         
53         // dirty hack to let <tpl> get through without being picked up
54         Ext.apply(data, {
55             tpl: 'tpl'
56         });
57         
58         var name        = 'src/generators/' + this.dirName + '/templates/' + name + '.js',
59             stream      = new Stream(name, 'rw'),
60             template    = new Ext.XTemplate(stream.readText()),
61             contents    = template.apply(data),
62             destination = this.basePath + '/' + filename,
63             newFile     = new Stream(destination, "w");
64         
65         newFile.writeLine(contents);
66         system.move(destination, filename, true);
67         newFile.close();
68     },
69     
70     /**
71      * Copies a file from the generator's files directory into the app
72      * @param {String} fileName The name of the file to copy
73      * @param {String} destination The destination path (defaults to the fileName)
74      * @param {Boolean} silent True to not log any messages (defaults to false)
75      */
76     file: function(fileName, destination, silent) {
77         Logger.log("    Copying " + fileName);
78         
79         destination = this.basePath + '/' + (destination || fileName);
80         fileName = 'src/generators/' + this.dirName + '/files/' + fileName;
81         
82         if (!this.pretend && this.silent !== true) {
83             Filesystem.copy(fileName, destination);
84         }
85     },
86     
87     /**
88      * Copies all contents of the given source directory to a destination
89      * @param {String} dirName The name of the directory to copy
90      * @param {String} destination The destination for the source files
91      */
92     copyDir: function(dirName, destination) {
93         destination = this.basePath + '/' + (destination || dirName);
94         
95         if (!this.pretend) {
96             Filesystem.copy(dirName, destination);
97         }
98     },
99     
100     /**
101      * Inserts a script tag to load the given src file inside the given div id
102      * @param {String} path The path to the script to be included
103      * @param {String} id The id of the div to include after
104      * @param {String} htmlFile Optional html file to update (defaults to index.html)
105      */
106     insertInclude: function(path, id, htmlFile) {
107         htmlFile = htmlFile || 'index.html';
108         
109         var stream = new Stream(htmlFile, 'rw'),
110             regex  = new RegExp('<div id="' + id + '">'),
111             lines  = [],
112             line;
113         
114         while (line = stream.readLine()) {
115             lines.push(line);
116             
117             if (regex.test(line)) {
118                 lines.push('            <script type="text/javascript" src="' + path + '"></script>');
119             }
120         }
121         
122         var destination = htmlFile + "-modified",
123             newFile     = new Stream(destination, "w");
124         
125         newFile.writeLine(lines.join("\n"));
126         system.move(destination, htmlFile, true);
127         newFile.close();
128     },
129     
130     /**
131      * Convenience function for displaying a clear message to the user
132      * @param {String} message The message to display
133      */
134     headline: function(message) {
135         Logger.log("");
136         Logger.log("*********************************************");
137         Logger.log(message);
138         Logger.log("*********************************************");
139         Logger.log("");
140     },
141     
142     generate: function() {
143         
144     }
145 });
146
147 /**
148  * @class GeneratorHelper
149  * @extends Cli
150  * Generates files and folders based on a template
151  */
152 Ext.generator.Factory = Ext.extend(Object, {
153     name: "Generator",
154     version: "0.0.1",
155     
156     constructor: function(config) {
157         Ext.apply(this, config);
158         
159         Cli.call(this);
160     },
161     
162     initArguments: function() {},
163     
164     usage: [
165         'Example usage:',
166         'Arguments in square brackets are optional',
167         '',
168         'Generating an application:',
169         '    ./generate app AppName [../path/to/app]',
170         '',
171         'Generating a model:',
172         '    ./generate model User id:int name:string active:boolean',
173         '',
174         'Generating a controller:',
175         '    ./generate controller users create update destroy',
176         ''
177     ],
178     
179     run: function() {
180         var args = this.args || system.arguments,
181             Gen  = Ext.generator.Factory.types[args[0]];
182         
183         if (Gen) {
184             new Gen({args: args.slice(1)}).generate();
185         } else {
186             this.printUsage();
187         }
188     }
189 });
190
191 Ext.generator.Factory.types = {};
192 Ext.regGenerator = function(name, constructor) {
193     Ext.generator.Factory.types[name] = constructor;
194     
195     constructor.prototype.dirName = name;
196     constructor.templates = {};
197 };
198
199 Ext.regDispatchable('generate', Ext.generator.Factory);
200
201 // generate app FB examples/facebook
202 // generate model User id:int name:string email:string
203 // generate controller users index build show new