def do_case_expected(self): lessf, cssf, minf = args if os.path.exists(cssf): p = parser.LessParser() p.parse(filename=lessf) f = formatter.Formatter(Opt()) pout = f.format(p).split('\n') pl = len(pout) i = 0 with open(cssf) as cssf: for line in cssf.readlines(): if i >= pl: self.fail("%s: result has less lines (%d < %d)" % (cssf, i, pl)) line = line.rstrip() if not line: continue self.assertEqual(line, pout[i], '%s: Line %d' % (cssf, i + 1)) i += 1 if pl > i and i: self.fail("%s: result has more lines (%d > %d)" % (cssf, i, pl)) else: self.fail("%s not found..." % cssf) if minf: if os.path.exists(minf): p = parser.LessParser() opt = Opt() opt.minify = True p.parse(filename=lessf) f = formatter.Formatter(opt) mout = f.format(p).split('\n') ml = len(mout) i = 0 with open(minf) as cssf: for line in cssf.readlines(): if i >= ml: self.fail("%s: result has less lines (%d < %d)" % (minf, i, ml)) self.assertEqual(line.rstrip(), mout[i], '%s: Line %d' % (minf, i + 1)) i += 1 if ml > i and i: self.fail("%s: result has more lines (%d > %d)" % (minf, i, ml)) else: self.fail("%s not found..." % minf)
def ldirectory(inpath, outpath, args, scope): """Compile all *.less files in directory Args: inpath (str): Path to compile outpath (str): Output directory args (object): Argparse Object scope (Scope): Scope object or None """ yacctab = 'yacctab' if args.debug else None if not outpath: sys.exit("Compile directory option needs -o ...") else: if not os.path.isdir(outpath): if args.verbose: print("Creating '%s'" % outpath, file=sys.stderr) if not args.dry_run: os.mkdir(outpath) less = glob.glob(os.path.join(inpath, '*.less')) f = formatter.Formatter(args) for lf in less: outf = os.path.splitext(os.path.basename(lf)) minx = '.min' if args.min_ending else '' outf = "%s/%s%s.css" % (outpath, outf[0], minx) if not args.force and os.path.exists(outf): recompile = os.path.getmtime(outf) < os.path.getmtime(lf) else: recompile = True if recompile: print('%s -> %s' % (lf, outf)) p = parser.LessParser(yacc_debug=(args.debug), lex_optimize=True, yacc_optimize=(not args.debug), scope=scope, tabfile=yacctab, verbose=args.verbose) p.parse(filename=lf, debuglevel=0) css = f.format(p) if not args.dry_run: with open(outf, 'w') as outfile: outfile.write(css) elif args.verbose: print('skipping %s, not modified' % lf, file=sys.stderr) sys.stdout.flush() if args.recurse: [ ldirectory(os.path.join(inpath, name), os.path.join(outpath, name), args, scope) for name in os.listdir(inpath) if os.path.isdir(os.path.join(inpath, name)) and not name.startswith('.') and not name == outpath ]
def run(): """Run compiler """ aparse = argparse.ArgumentParser(description='LessCss Compiler', epilog='<< [email protected] @_o >>') aparse.add_argument('-v', '--version', action='version', version=VERSION_STR) aparse.add_argument('-I', '--include', action="store", type=str, help="Included less-files (comma separated)") aparse.add_argument('-V', '--verbose', action="store_true", default=False, help="Verbose mode") fgroup = aparse.add_argument_group('Formatting options') fgroup.add_argument('-x', '--minify', action="store_true", default=False, help="Minify output") fgroup.add_argument('-X', '--xminify', action="store_true", default=False, help="Minify output, no end of block newlines") fgroup.add_argument('-t', '--tabs', help="Use tabs", action="store_true") fgroup.add_argument('-s', '--spaces', help="Number of startline spaces (default 2)", default=2) dgroup = aparse.add_argument_group( 'Directory options', 'Compiles all *.less files in directory that ' 'have a newer timestamp than it\'s css file.') dgroup.add_argument('-o', '--out', action="store", help="Output directory") dgroup.add_argument('-r', '--recurse', action="store_true", help="Recursive into subdirectorys") dgroup.add_argument('-f', '--force', action="store_true", help="Force recompile on all files") dgroup.add_argument( '-m', '--min-ending', action="store_true", default=False, help="Add '.min' into output filename. eg, name.min.css") dgroup.add_argument('-D', '--dry-run', action="store_true", default=False, help="Dry run, do not write files") group = aparse.add_argument_group('Debugging') group.add_argument('-g', '--debug', action="store_true", default=False, help="Debugging information") group.add_argument('-S', '--scopemap', action="store_true", default=False, help="Scopemap") group.add_argument('-L', '--lex-only', action="store_true", default=False, help="Run lexer on target") group.add_argument('-N', '--no-css', action="store_true", default=False, help="No css output") aparse.add_argument('target', help="less file or directory") args = aparse.parse_args() try: # # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # if args.lex_only: lex = lexer.LessLexer() ll = lex.file(args.target) while True: tok = ll.token() if not tok: break if hasattr(tok, "lexer"): # literals don't have the lexer attribute print(tok, "State:", tok.lexer.lexstate) else: print(tok) print('EOF') sys.exit() # # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # yacctab = 'yacctab' if args.debug else None scope = None if args.include: for u in args.include.split(','): if os.path.exists(u): p = parser.LessParser(yacc_debug=(args.debug), lex_optimize=True, yacc_optimize=(not args.debug), tabfile=yacctab, verbose=args.verbose) p.parse(filename=u, debuglevel=args.debug) if not scope: scope = p.scope else: scope.update(p.scope) else: sys.exit('included file `%s` not found ...' % u) sys.stdout.flush() p = None f = formatter.Formatter(args) if not os.path.exists(args.target): sys.exit("Target not found '%s' ..." % args.target) if os.path.isdir(args.target): ldirectory(args.target, args.out, args, scope) if args.dry_run: print('Dry run, nothing done.', file=sys.stderr) else: p = parser.LessParser(yacc_debug=(args.debug), lex_optimize=True, yacc_optimize=(not args.debug), scope=copy.deepcopy(scope), verbose=args.verbose) p.parse(filename=args.target, debuglevel=args.debug) if args.scopemap: args.no_css = True p.scopemap() if not args.no_css and p: out = f.format(p) print(out) except (KeyboardInterrupt, SystemExit, IOError): sys.exit('\nAborting...')
def run(**kwargs): """ Run compiler. Callable with args so usable as a library. """ aparse = add_arguments() if kwargs: args = argparse.Namespace(**kwargs) return_css = True else: args = aparse.parse_args() return_css = False try: # # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # if args.lex_only: lex = lexer.LessLexer() ll = lex.file(args.target) while True: tok = ll.token() if not tok: break if hasattr(tok, "lexer"): # literals don't have the lexer attribute print(tok, "State:", tok.lexer.lexstate) else: print(tok) print('EOF') sys.exit() # # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # yacctab = 'yacctab' if args.debug else None scope = None if args.include: for u in args.include.split(','): if os.path.exists(u): p = parser.LessParser(yacc_debug=args.debug, lex_optimize=True, yacc_optimize=not args.debug, tabfile=yacctab, verbose=args.verbose) p.parse(filename=u, debuglevel=args.debug) if not scope: scope = p.scope else: scope.update(p.scope) else: sys.exit('included file `%s` not found ...' % u) sys.stdout.flush() f = formatter.Formatter(args) target = args.target if target == '-': # read less from stdin target = sys.stdin elif not os.path.exists(args.target): sys.exit("Target not found '%s' ..." % args.target) if os.path.isdir(args.target): ldirectory(args.target, args.out, args, scope) if args.dry_run: print('Dry run, nothing done.', file=sys.stderr) else: p = parser.LessParser(yacc_debug=args.debug, lex_optimize=True, yacc_optimize=(not args.debug), scope=copy.deepcopy(scope), verbose=args.verbose) p.parse(file=target, debuglevel=args.debug) if args.scopemap: args.no_css = True p.scopemap() if not args.no_css and p: css = f.format(p) if return_css: return css print(css) except (KeyboardInterrupt, SystemExit, IOError): sys.exit('\nAborting...')