| | 129 | |
|---|
| | 130 | def run (sourceDirectory, outputFilename = None, configFile = None): |
|---|
| | 131 | cfg = None |
|---|
| | 132 | if configFile: |
|---|
| | 133 | cfg = Config(configFile) |
|---|
| | 134 | |
|---|
| | 135 | print cfg.include |
|---|
| | 136 | allFiles = [] |
|---|
| | 137 | |
|---|
| | 138 | ## Find all the Javascript source files |
|---|
| | 139 | for root, dirs, files in os.walk(sourceDirectory): |
|---|
| | 140 | for filename in files: |
|---|
| | 141 | if filename.endswith(SUFFIX_JAVASCRIPT) and not filename.startswith("."): |
|---|
| | 142 | filepath = os.path.join(root, filename)[len(sourceDirectory)+1:] |
|---|
| | 143 | if cfg and cfg.include: |
|---|
| | 144 | if filepath in cfg.include or filepath in cfg.forceFirst: |
|---|
| | 145 | allFiles.append(filepath) |
|---|
| | 146 | elif (not cfg) or (filepath not in cfg.exclude): |
|---|
| | 147 | allFiles.append(filepath) |
|---|
| | 148 | |
|---|
| | 149 | ## Header inserted at the start of each file in the output |
|---|
| | 150 | HEADER = "/* " + "=" * 70 + " %s\n" + " " + "=" * 70 + " */\n\n" |
|---|
| | 151 | |
|---|
| | 152 | files = {} |
|---|
| | 153 | |
|---|
| | 154 | order = [] # List of filepaths to output, in a dependency satisfying order |
|---|
| | 155 | |
|---|
| | 156 | ## Import file source code |
|---|
| | 157 | ## TODO: Do import when we walk the directories above? |
|---|
| | 158 | for filepath in allFiles: |
|---|
| | 159 | print "Importing: %s" % filepath |
|---|
| | 160 | fullpath = os.path.join(sourceDirectory, filepath) |
|---|
| | 161 | content = open(fullpath, "U").read() # TODO: Ensure end of line @ EOF? |
|---|
| | 162 | files[filepath] = SourceFile(filepath, content) # TODO: Chop path? |
|---|
| | 163 | |
|---|
| | 164 | ## Resolve the dependencies |
|---|
| | 165 | print "\nResolving dependencies...\n" |
|---|
| | 166 | |
|---|
| | 167 | from toposort import toposort |
|---|
| | 168 | |
|---|
| | 169 | nodes = [] |
|---|
| | 170 | routes = [] |
|---|
| | 171 | |
|---|
| | 172 | for filepath, info in files.items(): |
|---|
| | 173 | nodes.append(filepath) |
|---|
| | 174 | for neededFilePath in info.requires: |
|---|
| | 175 | routes.append((neededFilePath, filepath)) |
|---|
| | 176 | |
|---|
| | 177 | for dependencyLevel in toposort(nodes, routes): |
|---|
| | 178 | for filepath in dependencyLevel: |
|---|
| | 179 | order.append(filepath) |
|---|
| | 180 | |
|---|
| | 181 | |
|---|
| | 182 | ## Move forced first and last files to the required position |
|---|
| | 183 | if cfg: |
|---|
| | 184 | print "Re-ordering files...\n" |
|---|
| | 185 | order = cfg.forceFirst + [item |
|---|
| | 186 | for item in order |
|---|
| | 187 | if ((item not in cfg.forceFirst) and |
|---|
| | 188 | (item not in cfg.forceLast))] + cfg.forceLast |
|---|
| | 189 | |
|---|
| | 190 | ## Double check all dependencies have been met |
|---|
| | 191 | for fp in order: |
|---|
| | 192 | if max([order.index(rfp) for rfp in files[fp].requires] + |
|---|
| | 193 | [order.index(fp)]) != order.index(fp): |
|---|
| | 194 | print "Inconsistent!" |
|---|
| | 195 | raise SystemExit |
|---|
| | 196 | |
|---|
| | 197 | |
|---|
| | 198 | ## Output the files in the determined order |
|---|
| | 199 | result = [] |
|---|
| | 200 | |
|---|
| | 201 | for fp in order: |
|---|
| | 202 | f = files[fp] |
|---|
| | 203 | print "Exporting: ", f.filepath |
|---|
| | 204 | result.append(HEADER % f.filepath) |
|---|
| | 205 | source = f.source |
|---|
| | 206 | result.append(source) |
|---|
| | 207 | if not source.endswith("\n"): |
|---|
| | 208 | result.append("\n") |
|---|
| | 209 | |
|---|
| | 210 | print "\nTotal files merged: %d " % len(allFiles) |
|---|
| | 211 | |
|---|
| | 212 | if outputFilename: |
|---|
| | 213 | print "\nGenerating: %s" % (outputFilename) |
|---|
| | 214 | open(outputFilename, "w").write("".join(result)) |
|---|
| | 215 | return "".join(result) |
|---|
| 151 | | cfg = Config(filename) |
|---|
| 152 | | |
|---|
| 153 | | print cfg.include |
|---|
| 154 | | allFiles = [] |
|---|
| 155 | | |
|---|
| 156 | | ## Find all the Javascript source files |
|---|
| 157 | | for root, dirs, files in os.walk(sourceDirectory): |
|---|
| 158 | | for filename in files: |
|---|
| 159 | | if filename.endswith(SUFFIX_JAVASCRIPT) and not filename.startswith("."): |
|---|
| 160 | | filepath = os.path.join(root, filename)[len(sourceDirectory)+1:] |
|---|
| 161 | | if cfg and cfg.include: |
|---|
| 162 | | if filepath in cfg.include or filepath in cfg.forceFirst: |
|---|
| 163 | | allFiles.append(filepath) |
|---|
| 164 | | elif (not cfg) or (filepath not in cfg.exclude): |
|---|
| 165 | | allFiles.append(filepath) |
|---|
| 166 | | |
|---|
| 167 | | ## Header inserted at the start of each file in the output |
|---|
| 168 | | HEADER = "/* " + "=" * 70 + " %s\n" + " " + "=" * 70 + " */\n\n" |
|---|
| 169 | | |
|---|
| 170 | | files = {} |
|---|
| 171 | | |
|---|
| 172 | | order = [] # List of filepaths to output, in a dependency satisfying order |
|---|
| 173 | | |
|---|
| 174 | | ## Import file source code |
|---|
| 175 | | ## TODO: Do import when we walk the directories above? |
|---|
| 176 | | for filepath in allFiles: |
|---|
| 177 | | print "Importing: %s" % filepath |
|---|
| 178 | | fullpath = os.path.join(sourceDirectory, filepath) |
|---|
| 179 | | content = open(fullpath, "U").read() # TODO: Ensure end of line @ EOF? |
|---|
| 180 | | files[filepath] = SourceFile(filepath, content) # TODO: Chop path? |
|---|
| 181 | | |
|---|
| 182 | | ## Resolve the dependencies |
|---|
| 183 | | print "\nResolving dependencies...\n" |
|---|
| 184 | | |
|---|
| 185 | | from toposort import toposort |
|---|
| 186 | | |
|---|
| 187 | | nodes = [] |
|---|
| 188 | | routes = [] |
|---|
| 189 | | |
|---|
| 190 | | for filepath, info in files.items(): |
|---|
| 191 | | nodes.append(filepath) |
|---|
| 192 | | for neededFilePath in info.requires: |
|---|
| 193 | | routes.append((neededFilePath, filepath)) |
|---|
| 194 | | |
|---|
| 195 | | for dependencyLevel in toposort(nodes, routes): |
|---|
| 196 | | for filepath in dependencyLevel: |
|---|
| 197 | | order.append(filepath) |
|---|
| 198 | | |
|---|
| 199 | | |
|---|
| 200 | | ## Move forced first and last files to the required position |
|---|
| 201 | | if cfg: |
|---|
| 202 | | print "Re-ordering files...\n" |
|---|
| 203 | | order = cfg.forceFirst + [item |
|---|
| 204 | | for item in order |
|---|
| 205 | | if ((item not in cfg.forceFirst) and |
|---|
| 206 | | (item not in cfg.forceLast))] + cfg.forceLast |
|---|
| 207 | | |
|---|
| 208 | | ## Double check all dependencies have been met |
|---|
| 209 | | for fp in order: |
|---|
| 210 | | if max([order.index(rfp) for rfp in files[fp].requires] + |
|---|
| 211 | | [order.index(fp)]) != order.index(fp): |
|---|
| 212 | | print "Inconsistent!" |
|---|
| 213 | | raise SystemExit |
|---|
| 214 | | |
|---|
| 215 | | |
|---|
| 216 | | ## Output the files in the determined order |
|---|
| 217 | | result = [] |
|---|
| 218 | | |
|---|
| 219 | | for fp in order: |
|---|
| 220 | | f = files[fp] |
|---|
| 221 | | print "Exporting: ", f.filepath |
|---|
| 222 | | result.append(HEADER % f.filepath) |
|---|
| 223 | | source = f.source |
|---|
| 224 | | result.append(source) |
|---|
| 225 | | if not source.endswith("\n"): |
|---|
| 226 | | result.append("\n") |
|---|
| 227 | | |
|---|
| 228 | | print "\nTotal files merged: %d " % len(allFiles) |
|---|
| 229 | | |
|---|
| 230 | | print "\nGenerating: %s" % (outputFilename) |
|---|
| 231 | | |
|---|
| 232 | | open(outputFilename, "w").write("".join(result)) |
|---|
| | 238 | run( sourceDirectory, outputFilename, configFile ) |
|---|