From: dsc Date: Sun, 28 Nov 2010 01:01:26 +0000 (-0800) Subject: Fixes cjs bugs. X-Git-Url: http://git.lttlst.com:3516/?a=commitdiff_plain;h=1413238228e2c92b625d8534e5a620b2f08df900;p=tanks.git Fixes cjs bugs. --- diff --git a/bin/cjs.py b/bin/cjs.py index 95706e3..250e42d 100755 --- a/bin/cjs.py +++ b/bin/cjs.py @@ -18,19 +18,22 @@ from path import path import pystache -REQUIRE_PAT = re.compile(r'require\(\s*([\'"])(.*?)\1\s*\)') -ROOT = path(__file__).abspath().dirname().dirname() -LIB = ROOT/'lib/cjs' -CWD = path('.') -BLANK = path('') -MODULE_TEMPLATE = '' +LINE_COMMENT_PAT = re.compile(r'(.*?)(//.*?)(?:\n|$)') +PAIR_COMMENT_PAT = re.compile(r'(.*?)(/\*.*?\*/)') +REQUIRE_PAT = re.compile(r'\brequire\(\s*([\'"])(.*?)\1\s*\)') +ROOT = path(__file__).abspath().dirname().dirname() +LIB = ROOT/'lib/cjs' +CWD = path('.') +BLANK = path('') +MODULE_TEMPLATE = '' try: with (LIB/'module.js').open('rU') as f : MODULE_TEMPLATE = f.read() except Exception as ex: print - print 'ROOT={ROOT}, LIB={LIB}, module.js={}'.format(LIB/'module.js', **locals()) + print 'Error reading module template file!' + print ' ROOT={ROOT}, LIB={LIB}, module.js={}'.format(LIB/'module.js', **locals()) raise @@ -69,7 +72,7 @@ def canonicalise(query, base=None): query = trim(query, '/index.cjs', '.cjs', '/index.js', '.js') basedir = path(base or '').dirname() - print "canonicalise(query={query}, basedir={basedir})".format(**locals()) + # print "canonicalise(query={query}, basedir={basedir})".format(**locals()) if query.startswith('.'): id = ( basedir / query ).normpath() @@ -79,10 +82,22 @@ def canonicalise(query, base=None): if id.startswith('..'): raise ResolutionError('Impossible to resolve {} from {}!'.format(query, base)) - print " -->", str(id) + # print " -->", str(id) return str(id) +class Repo(object): + def __init__(self, filepath, url): + self.path = filepath + self.url = url + + def __repr__(self): + return 'Repo({}, url={})'.format(self.path, self.url) + + def __str__(self): + return repr(self) + + class Module(Bunch): DEFAULTS = { @@ -97,7 +112,7 @@ class Module(Bunch): } - def __init__(self, id, file, out=None, compile=True): + def __init__(self, id, file, uri='', out=None, compile=True): self.update(Module.DEFAULTS) self.id = id @@ -109,12 +124,13 @@ class Module(Bunch): else: out = self.file.replace('.cjs', '.js') self.outpath = path(out) + self.uri = uri if compile: self.compile() - print "new!", repr(self) + # print "new!", repr(self) - def compile(self, uri=''): - if uri: self.uri = uri.format(**self) # TODO: calc uri + def compile(self): + # if uri: self.uri = uri.format(**self) # TODO: calc uri if not self.file.endswith('.cjs'): return self @@ -144,10 +160,17 @@ class Module(Bunch): def contents(self): return self.read('contents') + def findRequires(self, text): + text = LINE_COMMENT_PAT.subn(r'\1 ', text)[0] + text = PAIR_COMMENT_PAT.subn(r'\1 ', text)[0] + # print " findRequires() -> %r" % line + for mreq in REQUIRE_PAT.finditer(text): + yield canonicalise(mreq.group(2), self) + @property def requires(self): if self._requires is None: - self._requires = [ canonicalise(m.group(2), self) for m in REQUIRE_PAT.finditer(self.text) ] + self._requires = list(self.findRequires(self.text)) return self._requires def __hash__(self): @@ -172,17 +195,17 @@ class CommonJS(object): """ Compiles JS modules into browser-safe JS files. """ @staticmethod - def discover(files, repos, out=None): + def discover(files, repos, **options): "Discover listed modules and their dependencies." - cjs = CommonJS(repos, out) + cjs = CommonJS(repos, **options) queue = [ cjs.lookup(f) for f in files ] seen = set() while queue: mod = queue.pop(0) seen.add(mod) - print mod, "requirements:", mod.requires + # print mod, "requirements:", mod.requires for query in mod.requires: - print mod, "requires", query + # print mod, "requires", query req = cjs.lookup(query, mod) if req not in seen: queue.append(req) @@ -194,10 +217,14 @@ class CommonJS(object): _graph = None # id -> set(dependants) - def __init__(self, repos, out=None): + def __init__(self, repos, out='build', clean=True): self.modules = {} self.repos = set( path(path(p).abspath()+'/') for p in repos) - self.out = out + self.out = None if out is '' else out + + if self.out is not None and clean: + out = path(self.out) + if out.exists(): out.rmtree() def register(self, id, file): mod = self.modules[id] = Module(id=id, file=file, out=self.out) @@ -206,7 +233,7 @@ class CommonJS(object): def lookup(self, query, base=None): absquery = path(query).abspath() id = canonicalise(query, base) - print "lookup(query={query}, base={base}) -> id={id}".format(**locals()) + # print "lookup(query={query}, base={base}) -> id={id}".format(**locals()) if id in self.modules: return self.modules[id] @@ -223,6 +250,10 @@ class CommonJS(object): raise ResolutionError('Unable to find file for (query={query}, id={id}, base={base}) in repos={}!'.format(map(str, self.repos), **locals())) + def __iter__(self): + for k, mod in self.modules.iteritems(): + yield k, mod + @property def graph(self): if self._graph is None: @@ -259,12 +290,17 @@ def main(): parser = OptionParser( usage = 'usage: %prog [options] file[...] [-- [repo_path[...]]]', - description = 'Resolves imports in JS files', + description = 'Compiles CommonJS modules.', version = '%prog'+" %i.%i.%i" % __version__) parser.add_option("-p", "--repo-paths", dest='repos', default='', - help="Comma-seperated paths to search for unqualified modules. [default: .]") - parser.add_option("-o", "--out", default=None, - help="Root directory to write compiled JS files. [default: Module's directory]") + help="Comma-seperated paths to search for unqualified modules. " + "If a path contains :, the portion afterward will be taken as the repo URL. [default: .]") + parser.add_option("-o", "--out", default='build', + help="Root directory to write compiled JS files. Specify '' to write to module's dir. [default: build]") + parser.add_option("-C", "--no-clean", dest='clean', default=True, action="store_false", + help="Do not clean the out-dir of compiled files. [default: False if -o, True otherwise]") + parser.add_option("-d", "--print-deps", default=False, action="store_true", + help="Prints module dependencies after compiling. [default: %default]") (options, args) = parser.parse_args() @@ -276,15 +312,19 @@ def main(): repos = filter(lambda f: f in args, repos) repos.extend( filter(None, options.repos.split(',')) ) - print 'files:', files, 'repos:', (repos or ['.']) - js = CommonJS.discover(files=files, repos=repos or ['.'], out=options.out) + # print 'files:', files, 'repos:', (repos or ['.']) + js = CommonJS.discover(files=files, repos=repos or ['.'], **options.__dict__) - print 'deplist:' - print js.deplist - print - print 'dependencies:' - print '\n'.join(js.dependencies) - print + if options.print_deps: + column = Popen(['column', '-s', '\t', '-t'], stderr=sys.stderr, stdin=PIPE, stdout=PIPE) + mods = js.modules.values() + for mod in sorted(mods, key=lambda m: len(m.requires), reverse=True): + column.stdin.write('%s\t->\t%r\n' % (mod, sorted(mod.requires))) + # print '%s\t->\t%r' % (mod, sorted(mod.requires)) + + column.stdin.close() + if column.wait() != 0: print 'Some sort of error has occurred!' + print column.stdout.read() return 0 diff --git a/lib/functional.js b/lib/functional/functional.js similarity index 100% rename from lib/functional.js rename to lib/functional/functional.js diff --git a/src/Y/tofunction.cjs b/lib/functional/to-function.js similarity index 100% rename from src/Y/tofunction.cjs rename to lib/functional/to-function.js diff --git a/src/Y/index.cjs b/src/Y/index.cjs index 4b3e16b..bc8097e 100644 --- a/src/Y/index.cjs +++ b/src/Y/index.cjs @@ -1,7 +1,7 @@ /// Import our external deps first /// -require('lessly/future'); -require('functional/to-function'); +// require('lessly/future'); +// require('functional/to-function'); /// Set up core and utilities /// var core = require('Y/core')