Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
if manifest['runSpec']['interpreter'] in ["python2.7", "bash"]:
if "file" in manifest['runSpec']:
entry_point_file = os.path.abspath(os.path.join(src_dir, manifest['runSpec']['file']))
try:
_check_file_syntax(entry_point_file, temp_dir, override_lang=manifest['runSpec']['interpreter'], enforce=enforce)
except IOError as e:
raise dxpy.app_builder.AppBuilderException(
'Could not open runSpec.file=%r. The problem was: %s' % (entry_point_file, e))
except DXSyntaxError:
raise dxpy.app_builder.AppBuilderException('Entry point file %s has syntax errors, see above for details. Rerun with --no-check-syntax to proceed anyway.' % (entry_point_file,))
elif "code" in manifest['runSpec']:
try:
_check_syntax(manifest['runSpec']['code'], manifest['runSpec']['interpreter'], temp_dir, enforce=enforce)
except DXSyntaxError:
raise dxpy.app_builder.AppBuilderException('Code in runSpec.code has syntax errors, see above for details. Rerun with --no-check-syntax to proceed anyway.')
if 'execDepends' in manifest['runSpec']:
if not isinstance(manifest['runSpec']['execDepends'], list):
raise dxpy.app_builder.AppBuilderException('Expected runSpec.execDepends to be an array. Rerun with --no-check-syntax to proceed anyway.')
if not all(isinstance(dep, dict) for dep in manifest['runSpec']['execDepends']):
raise dxpy.app_builder.AppBuilderException('Expected runSpec.execDepends to be an array of hashes. Rerun with --no-check-syntax to proceed anyway.')
if any(dep.get('package_manager', 'apt') != 'apt' for dep in manifest['runSpec']['execDepends']):
if not isinstance(manifest.get('access'), dict) or 'network' not in manifest['access']:
msg = '\n'.join(['runSpec.execDepends specifies non-APT dependencies, but no network access spec is given.',
'Add {"access": {"network": ["*"]}} to allow dependencies to install.',
'See https://wiki.dnanexus.com/Developer-Tutorials/Request-Additional-App-Resources#Network-Access.',
'Rerun with --no-check-syntax to proceed anyway.'])
raise dxpy.app_builder.AppBuilderException(msg)
if 'authorizedUsers' in manifest:
if not isinstance(manifest['authorizedUsers'], list) or isinstance(manifest['authorizedUsers'], basestring):
dirname = os.path.basename(os.path.dirname(os.path.abspath(dxapp_json_filename)))
if mode == "app":
if 'title' not in app_spec:
logger.warn('app is missing a title, please add one in the "title" field of dxapp.json')
if 'summary' in app_spec:
if app_spec['summary'].endswith('.'):
logger.warn('summary "%s" should be a short phrase not ending in a period' % (app_spec['summary'],))
else:
logger.warn('app is missing a summary, please add one in the "summary" field of dxapp.json')
readme_filename = _find_readme(os.path.dirname(dxapp_json_filename))
if 'description' in app_spec:
if readme_filename:
raise dxpy.app_builder.AppBuilderException('Description was provided both in Readme.md '
'and in the "description" field of {file}. Please consolidate content in Readme.md '
'and remove the "description" field.'.format(file=dxapp_json_filename))
if not app_spec['description'].strip().endswith('.'):
logger.warn('"description" field should be written in complete sentences and end with a period')
else:
if readme_filename is None:
logger.warn("app is missing a description, please supply one in README.md")
if 'categories' in app_spec:
for category in app_spec['categories']:
if category not in APP_CATEGORIES:
logger.warn('app has unrecognized category "%s"' % (category,))
if category == 'Import':
if 'title' in app_spec and not app_spec['title'].endswith('Importer'):
logger.warn('title "%s" should end in "Importer"' % (app_spec['title'],))
if category == 'Export':
if 'title' in app_spec and not app_spec['title'].endswith('Exporter'):
_check_syntax(manifest['runSpec']['code'], manifest['runSpec']['interpreter'], temp_dir, enforce=enforce)
except DXSyntaxError:
raise dxpy.app_builder.AppBuilderException('Code in runSpec.code has syntax errors, see above for details. Rerun with --no-check-syntax to proceed anyway.')
if 'execDepends' in manifest['runSpec']:
if not isinstance(manifest['runSpec']['execDepends'], list):
raise dxpy.app_builder.AppBuilderException('Expected runSpec.execDepends to be an array. Rerun with --no-check-syntax to proceed anyway.')
if not all(isinstance(dep, dict) for dep in manifest['runSpec']['execDepends']):
raise dxpy.app_builder.AppBuilderException('Expected runSpec.execDepends to be an array of hashes. Rerun with --no-check-syntax to proceed anyway.')
if any(dep.get('package_manager', 'apt') != 'apt' for dep in manifest['runSpec']['execDepends']):
if not isinstance(manifest.get('access'), dict) or 'network' not in manifest['access']:
msg = '\n'.join(['runSpec.execDepends specifies non-APT dependencies, but no network access spec is given.',
'Add {"access": {"network": ["*"]}} to allow dependencies to install.',
'See https://wiki.dnanexus.com/Developer-Tutorials/Request-Additional-App-Resources#Network-Access.',
'Rerun with --no-check-syntax to proceed anyway.'])
raise dxpy.app_builder.AppBuilderException(msg)
if 'authorizedUsers' in manifest:
if not isinstance(manifest['authorizedUsers'], list) or isinstance(manifest['authorizedUsers'], basestring):
raise dxpy.app_builder.AppBuilderException('Expected authorizedUsers to be a list of strings')
for thing in manifest['authorizedUsers']:
if thing != 'PUBLIC' and (not isinstance(thing, basestring) or not re.match("^(org-|user-)", thing)):
raise dxpy.app_builder.AppBuilderException('authorizedUsers field contains an entry which is not either the string "PUBLIC" or a user or org ID')
# Check all other files that are going to be in the resources tree.
# For these we detect the language based on the filename extension.
# Obviously this check can have false positives, since the app can
# execute (or not execute!) all these files in whatever way it
# wishes, e.g. it could use Python != 2.7 or some non-bash shell.
# Consequently errors here are non-fatal.
files_with_problems = []
for dirpath, dirnames, filenames in os.walk(os.path.abspath(os.path.join(src_dir, "resources"))):
# execute (or not execute!) all these files in whatever way it
# wishes, e.g. it could use Python != 2.7 or some non-bash shell.
# Consequently errors here are non-fatal.
files_with_problems = []
for dirpath, dirnames, filenames in os.walk(os.path.abspath(os.path.join(src_dir, "resources"))):
for filename in filenames:
# On Mac OS, the resource fork for "FILE.EXT" gets tarred up
# as a file named "._FILE.EXT". To a naive check this
# appears to be a file of the same extension. Therefore, we
# exclude these from syntax checking since they are likely
# to not parse as whatever language they appear to be.
if not filename.startswith("._"):
try:
_check_file_syntax(os.path.join(dirpath, filename), temp_dir, enforce=True)
except IOError as e:
raise dxpy.app_builder.AppBuilderException(
'Could not open file in resources directory %r. The problem was: %s' %
(os.path.join(dirpath, filename), e)
)
except DXSyntaxError:
# Suppresses errors from _check_file_syntax so we
# only print a nice error message
files_with_problems.append(os.path.join(dirpath, filename))
if files_with_problems:
# Make a message of the form:
# "/path/to/my/app.py"
# OR "/path/to/my/app.py and 3 other files"
files_str = files_with_problems[0] if len(files_with_problems) == 1 else (files_with_problems[0] + " and " + str(len(files_with_problems) - 1) + " other file" + ("s" if len(files_with_problems) > 2 else ""))
logging.warn('%s contained syntax errors, see above for details' % (files_str,))
# Check if we have JSON or string
if isinstance(suggestion['value']['$dnanexus_link'], dict):
if 'project' in suggestion['value']['$dnanexus_link']:
try:
dxpy.api.project_describe(suggestion['value']['$dnanexus_link']['project'])
except dxpy.exceptions.DXAPIError as e:
if e.code == 404:
logger.warn('Suggested project {name} does not exist, or not accessible by user'.format(
name=suggestion['value']['$dnanexus_link']['project']))
elif isinstance(suggestion['value']['$dnanexus_link'], basestring):
if suggestion['value']['$dnanexus_link'].startswith(('file-', 'record-', 'gtable-')):
try:
dnanexus_link = dxpy.describe(suggestion['value']['$dnanexus_link'])
except dxpy.exceptions.DXAPIError as e:
if e.code == 404:
raise dxpy.app_builder.AppBuilderException(
'Suggested object {name} could not be found'.format(
name=suggestion['value']['$dnanexus_link']))
except Exception as e:
raise dxpy.app_builder.AppBuilderException(str(e))
if 'execDepends' in manifest['runSpec']:
if not isinstance(manifest['runSpec']['execDepends'], list):
raise dxpy.app_builder.AppBuilderException('Expected runSpec.execDepends to be an array. Rerun with --no-check-syntax to proceed anyway.')
if not all(isinstance(dep, dict) for dep in manifest['runSpec']['execDepends']):
raise dxpy.app_builder.AppBuilderException('Expected runSpec.execDepends to be an array of hashes. Rerun with --no-check-syntax to proceed anyway.')
if any(dep.get('package_manager', 'apt') != 'apt' for dep in manifest['runSpec']['execDepends']):
if not isinstance(manifest.get('access'), dict) or 'network' not in manifest['access']:
msg = '\n'.join(['runSpec.execDepends specifies non-APT dependencies, but no network access spec is given.',
'Add {"access": {"network": ["*"]}} to allow dependencies to install.',
'See https://wiki.dnanexus.com/Developer-Tutorials/Request-Additional-App-Resources#Network-Access.',
'Rerun with --no-check-syntax to proceed anyway.'])
raise dxpy.app_builder.AppBuilderException(msg)
if 'authorizedUsers' in manifest:
if not isinstance(manifest['authorizedUsers'], list) or isinstance(manifest['authorizedUsers'], basestring):
raise dxpy.app_builder.AppBuilderException('Expected authorizedUsers to be a list of strings')
for thing in manifest['authorizedUsers']:
if thing != 'PUBLIC' and (not isinstance(thing, basestring) or not re.match("^(org-|user-)", thing)):
raise dxpy.app_builder.AppBuilderException('authorizedUsers field contains an entry which is not either the string "PUBLIC" or a user or org ID')
# Check all other files that are going to be in the resources tree.
# For these we detect the language based on the filename extension.
# Obviously this check can have false positives, since the app can
# execute (or not execute!) all these files in whatever way it
# wishes, e.g. it could use Python != 2.7 or some non-bash shell.
# Consequently errors here are non-fatal.
files_with_problems = []
for dirpath, dirnames, filenames in os.walk(os.path.abspath(os.path.join(src_dir, "resources"))):
for filename in filenames:
# On Mac OS, the resource fork for "FILE.EXT" gets tarred up
# as a file named "._FILE.EXT". To a naive check this
# appears to be a file of the same extension. Therefore, we
if not all(isinstance(dep, dict) for dep in manifest['runSpec']['execDepends']):
raise dxpy.app_builder.AppBuilderException('Expected runSpec.execDepends to be an array of hashes. Rerun with --no-check-syntax to proceed anyway.')
if any(dep.get('package_manager', 'apt') != 'apt' for dep in manifest['runSpec']['execDepends']):
if not isinstance(manifest.get('access'), dict) or 'network' not in manifest['access']:
msg = '\n'.join(['runSpec.execDepends specifies non-APT dependencies, but no network access spec is given.',
'Add {"access": {"network": ["*"]}} to allow dependencies to install.',
'See https://wiki.dnanexus.com/Developer-Tutorials/Request-Additional-App-Resources#Network-Access.',
'Rerun with --no-check-syntax to proceed anyway.'])
raise dxpy.app_builder.AppBuilderException(msg)
if 'authorizedUsers' in manifest:
if not isinstance(manifest['authorizedUsers'], list) or isinstance(manifest['authorizedUsers'], basestring):
raise dxpy.app_builder.AppBuilderException('Expected authorizedUsers to be a list of strings')
for thing in manifest['authorizedUsers']:
if thing != 'PUBLIC' and (not isinstance(thing, basestring) or not re.match("^(org-|user-)", thing)):
raise dxpy.app_builder.AppBuilderException('authorizedUsers field contains an entry which is not either the string "PUBLIC" or a user or org ID')
# Check all other files that are going to be in the resources tree.
# For these we detect the language based on the filename extension.
# Obviously this check can have false positives, since the app can
# execute (or not execute!) all these files in whatever way it
# wishes, e.g. it could use Python != 2.7 or some non-bash shell.
# Consequently errors here are non-fatal.
files_with_problems = []
for dirpath, dirnames, filenames in os.walk(os.path.abspath(os.path.join(src_dir, "resources"))):
for filename in filenames:
# On Mac OS, the resource fork for "FILE.EXT" gets tarred up
# as a file named "._FILE.EXT". To a naive check this
# appears to be a file of the same extension. Therefore, we
# exclude these from syntax checking since they are likely
# to not parse as whatever language they appear to be.
if not filename.startswith("._"):
_verify_app_source_dir(src_dir, mode, enforce=do_check_syntax)
if mode == "app" and not dry_run:
_verify_app_writable(app_json['name'])
working_project = None
using_temp_project = False
override_folder = None
override_applet_name = None
requested_regional_options = dxpy.app_builder.get_regional_options(app_json)
# The set of regions specified on the command-line (i.e., --region) and the
# set of enabled regions in dxapp.json disagree.
if (requested_regional_options is not None and region is not None and
set(requested_regional_options) != set(region)):
raise dxpy.app_builder.AppBuilderException("--region and the 'regionalOptions' key in dxapp.json do not agree")
enabled_regions = None
if requested_regional_options is not None:
enabled_regions = requested_regional_options.keys()
elif region is not None:
enabled_regions = region
if enabled_regions is not None and len(enabled_regions) == 0:
raise AssertionError("This app should be enabled in at least one region")
# Cannot build multi-region app if `use_temp_build_project` is falsy.
if enabled_regions is not None and len(enabled_regions) > 1 and not use_temp_build_project:
raise dxpy.app_builder.AppBuilderException("Cannot specify --no-temp-build-project when building multi-region apps")
projects_by_region = None
if mode == "applet" and destination_override:
def verify_developer_rights(prefixed_name):
"""
Checks if the current user is a developer of the app or global workflow
with the given name. If the app/global workflow exists and the user has
developer rights to it, the function returns a named tuple representing
the executable that was queried.
"""
assert(prefixed_name.startswith('app-') or prefixed_name.startswith('globalworkflow-'))
if prefixed_name.partition('-')[0] == 'app':
exception_type = dxpy.app_builder.AppBuilderException
describe_method = dxpy.api.app_describe
exception_msg = \
'An app with the given name already exists and you are not a developer of that app'
else:
exception_type = dxpy.workflow_builder.WorkflowBuilderException
describe_method = dxpy.api.global_workflow_describe
exception_msg = \
'A global workflow with the given name already exists and you are not a developer of that workflow'
name_already_exists = True
is_developer = False
version = None
executable_id = None
FoundExecutable = collections.namedtuple('FoundExecutable', ['name', 'version', 'id'])
try:
describe_output = describe_method(prefixed_name,