files.py
3.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# -*- coding: utf-8 -*- #
# Copyright 2013 Google LLC. 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.
"""Some general file utilities used that can be used by the Cloud SDK."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
import os
from fire.console import encoding as encoding_util
from fire.console import platforms
import six
def _GetSystemPath():
"""Returns properly encoded system PATH variable string."""
return encoding_util.GetEncodedValue(os.environ, 'PATH')
def _FindExecutableOnPath(executable, path, pathext):
"""Internal function to a find an executable.
Args:
executable: The name of the executable to find.
path: A list of directories to search separated by 'os.pathsep'.
pathext: An iterable of file name extensions to use.
Returns:
str, the path to a file on `path` with name `executable` + `p` for
`p` in `pathext`.
Raises:
ValueError: invalid input.
"""
if isinstance(pathext, six.string_types):
raise ValueError('_FindExecutableOnPath(..., pathext=\'{0}\') failed '
'because pathext must be an iterable of strings, but got '
'a string.'.format(pathext))
# Prioritize preferred extension over earlier in path.
for ext in pathext:
for directory in path.split(os.pathsep):
# Windows can have paths quoted.
directory = directory.strip('"')
full = os.path.normpath(os.path.join(directory, executable) + ext)
# On Windows os.access(full, os.X_OK) is always True.
if os.path.isfile(full) and os.access(full, os.X_OK):
return full
return None
def _PlatformExecutableExtensions(platform):
if platform == platforms.OperatingSystem.WINDOWS:
return ('.exe', '.cmd', '.bat', '.com', '.ps1')
else:
return ('', '.sh')
def FindExecutableOnPath(executable, path=None, pathext=None,
allow_extensions=False):
"""Searches for `executable` in the directories listed in `path` or $PATH.
Executable must not contain a directory or an extension.
Args:
executable: The name of the executable to find.
path: A list of directories to search separated by 'os.pathsep'. If None
then the system PATH is used.
pathext: An iterable of file name extensions to use. If None then
platform specific extensions are used.
allow_extensions: A boolean flag indicating whether extensions in the
executable are allowed.
Returns:
The path of 'executable' (possibly with a platform-specific extension) if
found and executable, None if not found.
Raises:
ValueError: if executable has a path or an extension, and extensions are
not allowed, or if there's an internal error.
"""
if not allow_extensions and os.path.splitext(executable)[1]:
raise ValueError('FindExecutableOnPath({0},...) failed because first '
'argument must not have an extension.'.format(executable))
if os.path.dirname(executable):
raise ValueError('FindExecutableOnPath({0},...) failed because first '
'argument must not have a path.'.format(executable))
if path is None:
effective_path = _GetSystemPath()
else:
effective_path = path
effective_pathext = (pathext if pathext is not None
else _PlatformExecutableExtensions(
platforms.OperatingSystem.Current()))
return _FindExecutableOnPath(executable, effective_path,
effective_pathext)