<s> from collections import defaultdict <EOL> from collections import namedtuple <EOL> import datetime <EOL> import errno <EOL> import shlex <EOL> import os <EOL> import re <EOL> import signal <EOL> from . import compat <EOL> if compat . ON_WINDOWS : <EOL> import ctypes <EOL> PROCFILE_LINE = re . compile ( r'<STR_LIT>' ) <EOL> class Env ( object ) : <EOL> def now ( self ) : <EOL> return datetime . datetime . now ( ) <EOL> if compat . ON_WINDOWS : <EOL> def terminate ( self , pid ) : <EOL> handle = ctypes . windll . kernel32 . OpenProcess ( <NUM_LIT:1> , False , pid ) <EOL> ctypes . windll . kernel32 . TerminateProcess ( handle , - <NUM_LIT:1> ) <EOL> ctypes . windll . kernel32 . CloseHandle ( handle ) <EOL> else : <EOL> def terminate ( self , pid ) : <EOL> try : <EOL> os . killpg ( pid , signal . SIGTERM ) <EOL> except OSError as e : <EOL> if e . errno not in [ errno . EPERM , errno . ESRCH ] : <EOL> raise <EOL> if compat . ON_WINDOWS : <EOL> def kill ( self , pid ) : <EOL> self . terminate ( pid ) <EOL> else : <EOL> def kill ( self , pid ) : <EOL> try : <EOL> os . killpg ( pid , signal . SIGKILL ) <EOL> except OSError as e : <EOL> if e . errno not in [ errno . EPERM , errno . ESRCH ] : <EOL> raise <EOL> class Procfile ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> self . processes = compat . OrderedDict ( ) <EOL> def add_process ( self , name , command ) : <EOL> assert name not in self . processes , "<STR_LIT>" <EOL> self . processes [ name ] = command <EOL> def parse_procfile ( contents ) : <EOL> p = Procfile ( ) <EOL> for line in contents . splitlines ( ) : <EOL> m = PROCFILE_LINE . match ( line ) <EOL> if m : <EOL> p . add_process ( m . group ( <NUM_LIT:1> ) , m . group ( <NUM_LIT:2> ) ) <EOL> return p <EOL> def parse ( content ) : <EOL> """<STR_LIT>""" <EOL> values = { } <EOL> for line in content . splitlines ( ) : <EOL> lexer = shlex . shlex ( line , posix = True ) <EOL> tokens = list ( lexer ) <EOL> if len ( tokens ) < <NUM_LIT:3> : <EOL> continue <EOL> name , op = tokens [ : <NUM_LIT:2> ] <EOL> value = '<STR_LIT>' . join ( tokens [ <NUM_LIT:2> : ] ) <EOL> if op != '<STR_LIT:=>' : <EOL> continue <EOL> if not re . match ( r'<STR_LIT>' , name ) : <EOL> continue <EOL> value = value . replace ( r'<STR_LIT:\n>' , '<STR_LIT:\n>' ) <EOL> value = value . replace ( r'<STR_LIT:\t>' , '<STR_LIT:\t>' ) <EOL> values [ name ] = value <EOL> return values <EOL> ProcessParams = namedtuple ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> def expand_processes ( processes , concurrency = None , env = None , quiet = None , port = None ) : <EOL> """<STR_LIT>""" <EOL> if env is not None and env . get ( "<STR_LIT>" ) is not None : <EOL> port = int ( env . get ( "<STR_LIT>" ) ) <EOL> if quiet is None : <EOL> quiet = [ ] <EOL> con = defaultdict ( lambda : <NUM_LIT:1> ) <EOL> if concurrency is not None : <EOL> con . update ( concurrency ) <EOL> out = [ ] <EOL> for name , cmd in compat . iteritems ( processes ) : <EOL> for i in range ( con [ name ] ) : <EOL> n = "<STR_LIT>" . format ( name , i + <NUM_LIT:1> ) <EOL> c = cmd <EOL> q = name in quiet <EOL> e = { } <EOL> if env is not None : <EOL> e . update ( env ) <EOL> if port is not None : <EOL> e [ '<STR_LIT>' ] = str ( port + i ) <EOL> params = ProcessParams ( n , c , q , e ) <EOL> out . append ( params ) <EOL> if port is not None : <EOL> port += <NUM_LIT:100> <EOL> return out </s>
