Modified source engine (2017) developed by valve and leaked in 2020. Not for commercial purporses
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

217 lines
6.3 KiB

#!/usr/bin/env python
# Copyright 2010 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS-IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Script for running Google-style applications.
Unlike normal scripts run through setuptools console_script entry points,
Google-style applications must be run as top-level scripts.
Given an already-imported module, users can use the RunScriptModule function to
set up the appropriate executable environment to spawn a new Python process to
run the module as a script.
To use this technique in your project, first create a module called e.g.
stubs.py with contents like:
from google.apputils import run_script_module
def RunMyScript():
import my.script
run_script_module.RunScriptModule(my.script)
def RunMyOtherScript():
import my.other_script
run_script_module.RunScriptModule(my.other_script)
Then, set up entry points in your setup.py that point to the functions in your
stubs module:
setup(
...
entry_points = {
'console_scripts': [
'my_script = my.stubs:RunMyScript',
'my_other_script = my.stubs.RunMyOtherScript',
],
},
)
When your project is installed, setuptools will generate minimal wrapper scripts
to call your stub functions, which in turn execv your script modules. That's it!
"""
__author__ = 'dborowitz@google.com (Dave Borowitz)'
import os
import re
import sys
def FindEnv(progname):
"""Find the program in the system path.
Args:
progname: The name of the program.
Returns:
The full pathname of the program.
Raises:
AssertionError: if the program was not found.
"""
for path in os.environ['PATH'].split(':'):
fullname = os.path.join(path, progname)
if os.access(fullname, os.X_OK):
return fullname
raise AssertionError(
"Could not find an executable named '%s' in the system path" % progname)
def GetPdbArgs(python):
"""Try to get the path to pdb.py and return it in a list.
Args:
python: The full path to a Python executable.
Returns:
A list of strings. If a relevant pdb.py was found, this will be
['/path/to/pdb.py']; if not, return ['-m', 'pdb'] and hope for the best.
(This latter technique will fail for Python 2.2.)
"""
# Usually, python is /usr/bin/pythonxx and pdb is /usr/lib/pythonxx/pdb.py
components = python.split('/')
if len(components) >= 2:
pdb_path = '/'.join(components[0:-2] + ['lib'] +
components[-1:] + ['pdb.py'])
if os.access(pdb_path, os.R_OK):
return [pdb_path]
# No pdb module found in the python path, default to -m pdb
return ['-m', 'pdb']
def StripDelimiters(s, beg, end):
if s[0] == beg:
assert s[-1] == end
return (s[1:-1], True)
else:
return (s, False)
def StripQuotes(s):
(s, stripped) = StripDelimiters(s, '"', '"')
if not stripped:
(s, stripped) = StripDelimiters(s, "'", "'")
return s
def PrintOurUsage():
"""Print usage for the stub script."""
print 'Stub script %s (auto-generated). Options:' % sys.argv[0]
print ('--helpstub '
'Show help for stub script.')
print ('--debug_binary '
'Run python under debugger specified by --debugger.')
print ('--debugger=<debugger> '
"Debugger for --debug_binary. Default: 'gdb --args'.")
print ('--debug_script '
'Run wrapped script with python debugger module (pdb).')
print ('--show_command_and_exit '
'Print command which would be executed and exit.')
print ('These options must appear first in the command line, all others will '
'be passed to the wrapped script.')
def RunScriptModule(module):
"""Run a module as a script.
Locates the module's file and runs it in the current interpreter, or
optionally a debugger.
Args:
module: The module object to run.
"""
args = sys.argv[1:]
debug_binary = False
debugger = 'gdb --args'
debug_script = False
show_command_and_exit = False
while args:
if args[0] == '--helpstub':
PrintOurUsage()
sys.exit(0)
if args[0] == '--debug_binary':
debug_binary = True
args = args[1:]
continue
if args[0] == '--debug_script':
debug_script = True
args = args[1:]
continue
if args[0] == '--show_command_and_exit':
show_command_and_exit = True
args = args[1:]
continue
matchobj = re.match('--debugger=(.+)', args[0])
if matchobj is not None:
debugger = StripQuotes(matchobj.group(1))
args = args[1:]
continue
break
# Now look for my main python source file
# TODO(dborowitz): This will fail if the module was zipimported, which means
# no egg depending on this script runner can be zip_safe.
main_filename = module.__file__
assert os.path.exists(main_filename), ('Cannot exec() %r: file not found.' %
main_filename)
assert os.access(main_filename, os.R_OK), ('Cannot exec() %r: file not'
' readable.' % main_filename)
args = [main_filename] + args
if debug_binary:
debugger_args = debugger.split()
program = debugger_args[0]
# If pathname is not absolute, determine full path using PATH
if not os.path.isabs(program):
program = FindEnv(program)
python_path = sys.executable
command_vec = [python_path]
if debug_script:
command_vec.extend(GetPdbArgs(python_path))
args = [program] + debugger_args[1:] + command_vec + args
elif debug_script:
args = [sys.executable] + GetPdbArgs(program) + args
else:
program = sys.executable
args = [sys.executable] + args
if show_command_and_exit:
print 'program: "%s"' % program
print 'args:', args
sys.exit(0)
try:
sys.stdout.flush()
os.execv(program, args)
except EnvironmentError as e:
if not getattr(e, 'filename', None):
e.filename = program # Add info to error message
raise