ENH: No verbose a2x output when building UserGuide
[freefoam.git] / data / python / FreeFOAM / path.py
blobe4ab27b02be64edab6288b50e17816822d817e84
1 #-------------------------------------------------------------------------------
2 # ______ _ ____ __ __
3 # | ____| _| |_ / __ \ /\ | \/ |
4 # | |__ _ __ ___ ___ / \| | | | / \ | \ / |
5 # | __| '__/ _ \/ _ ( (| |) ) | | |/ /\ \ | |\/| |
6 # | | | | | __/ __/\_ _/| |__| / ____ \| | | |
7 # |_| |_| \___|\___| |_| \____/_/ \_\_| |_|
9 # FreeFOAM: The Cross-Platform CFD Toolkit
11 # Copyright (C) 2008-2010 Michael Wild <themiwi@users.sf.net>
12 # Gerber van der Graaf <gerber_graaf@users.sf.net>
13 #-------------------------------------------------------------------------------
14 # License
15 # This file is part of FreeFOAM.
17 # FreeFOAM is free software; you can redistribute it and/or modify it
18 # under the terms of the GNU General Public License as published by the
19 # Free Software Foundation; either version 2 of the License, or (at your
20 # option) any later version.
22 # FreeFOAM is distributed in the hope that it will be useful, but WITHOUT
23 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
24 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 # for more details.
27 # You should have received a copy of the GNU General Public License
28 # along with FreeFOAM; if not, write to the Free Software Foundation,
29 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 # Description
32 # Path searching functions.
34 #-------------------------------------------------------------------------------
36 """Path manipulation and search functions."""
38 # want to be future proof
39 from FreeFOAM.compat import *
41 import FreeFOAM as _f
43 # local helper
44 def _isreadable(fname):
45 """Determine whether a file is readable by the user.
47 Parameters
48 ----------
49 fname : Path to the file to test.
51 Returns
52 -------
53 True if the file is readable by the user, False otherwise.
55 """
56 import os
57 return os.access(fname, os.R_OK)
59 # local helper
60 def _isexecutable(fname):
61 """Determine whether a file is executable by the user.
63 Parameters
64 ----------
65 fname : Path to the file to test.
67 Returns
68 -------
69 True if the file is executable by the user, False otherwise.
71 """
72 import os
73 import os.path
74 return os.path.isfile(fname) and os.access(fname, os.X_OK)
77 def split_search_path(path_str, normpath=True):
78 """Splits a search path string into a list of directories.
80 Parameters
81 ----------
82 path_str : The search path to split.
83 normpath : If True, os.path.normpath is applied to each element in the
84 returned list.
86 Returns
87 -------
88 path : A list of directories created by splitting 'path_str'.
90 """
91 import os
92 import os.path
93 # replace all os.pathsep by :
94 if os.pathsep != ':':
95 path_str = path_str.replace(os.pathsep,':')
96 # split at ':' and remove empty elements (e.g. from double :)
97 path = list(filter(len, path_str.split(':')))
98 # normalize paths if requested
99 if normpath and len(path):
100 path = list(map(os.path.normpath, path))
101 return path
103 def find_on_search_path(fname, path, predicate=_isreadable):
104 """Find a file on a search path subject to a predicate.
106 The first match for which 'predicate' returns true, will be selected.
107 It is completely up to 'predicate' to determine what a valid match is (e.g.
108 it is allowed to return True for a non-existing file).
110 Parameters
111 ----------
112 fname : Name of the file to find.
113 path : Either a sequence of directories or a ':' (on Windows also ';')
114 delimited string of directories to search.
115 predicate : A function which returns True if the file meets the requirements.
117 Returns
118 -------
119 path : The first path for which 'predicate' returned true.
122 import os.path
123 if isinstance(path, str):
124 path = split_search_path(path, True)
125 # loop over all directories in path
126 for dir in path:
127 # construct full candidate path
128 f = os.path.join(dir, fname)
129 # test whether it meets the predicate
130 if predicate(f):
131 return os.path.normpath(f)
132 # failed to find the file
133 return None
135 def create_app_search_path(basedir=_f.LIBEXEC_DIR, syspath=False):
136 """Create a search path for FreeFOAM applications.
138 First directories in the list given by the environment variable
139 'FREEFOAM_PATH' (if it is defined) are used. The elements of 'FREEFOAM_PATH'
140 must be separated by ':' (or optionally by ';' on Windows). Next the
141 directory '<basedir>' is appended, where '<basedir>' defaults to
142 'LIBEXEC_DIR'. This can be overriden using the 'basedir' argument. If the
143 argument 'syspath' is set to True, the directories in the system 'PATH'
144 variable will appended to the list.
146 Parameters
147 ----------
148 basedir : Directory in which the FreeFOAM applications are located.
149 syspath : If True, the system 'PATH' environment variable will also be
150 searched.
152 Returns
153 -------
154 path : A list of directories comprising the search path.
157 import os
158 import os.path
159 # set up the search path
160 path = []
161 # start with FREEFOAM_PATH elements if present
162 if 'FREEFOAM_PATH' in os.environ:
163 path.extend(split_search_path(os.environ['FREEFOAM_PATH']))
164 # append with basedir
165 path.append(os.path.abspath(basedir))
166 # append system PATH elements if present and desired by the user
167 if syspath and 'PATH' in os.environ:
168 path.extend(split_search_path(os.environ['PATH']))
169 # done
170 return path
172 def locate_app(fname, spath=None):
173 """Searches the search-path 'path' for an application named 'fname'.
175 The name of the file searched will be constructed as
176 'FreeFOAM.EXE_PREFIX+fname'. The elements of 'spath' will be searched for a
177 file with that name which is executable by the current user.
179 Parameters
180 ----------
181 fname : Name of the application to find.
182 spath : Sequence of directories to be used as the search path.
183 If set to None, the default search path will be constructed
184 by calling create_app_search_path with no arguments.
186 Returns
187 -------
188 path : The full path to the file if it was found, None otherwise.
191 import os.path
192 fname = os.path.normpath(fname)
193 # first check whether this is a relative/absolute path
194 if _isexecutable(fname):
195 if not os.path.isabs(fname) and fname[0] != '.':
196 fname = os.path.join('.',fname)
197 return fname
198 # construct default search path if none specified
199 if not spath:
200 spath = create_app_search_path()
201 # construct correct file name
202 fname = _f.EXE_PREFIX + fname + _f.EXE_SUFFIX
203 # find the thing
204 return find_on_search_path(fname, spath, _isexecutable)
206 def locate_config(fname):
207 """Searches the filesystem for a configuration file named 'fname'.
209 By default the 'CONFIG_DIR' directory is search, which can be overriden by
210 the 'FREEFOAM_CONFIG_DIR' environment variable.
212 Parameters
213 ----------
214 fname : Name of the configuration file to find.
216 Returns
217 -------
218 path : The full path to the file if it was found, None otherwise.
221 import os
222 import os.path
223 if 'FREEFOAM_CONFIG_DIR' in os.environ:
224 dir = os.environ['FREEFOAM_CONFIG_DIR']
225 else:
226 dir = _f.CONFIG_DIR
227 return find_on_search_path(fname, [dir])
229 def locate_tmpl(fname):
230 """Searches the filesystem for the template file 'fname'.
232 These text templates are searched for in 'DATA_DIR+"/templates"'.
234 Parameters
235 ----------
236 fname : Name of the template file to locate.
238 Returns
239 -------
240 path : The full path to the template file if it was found, None otherwise.
243 import os.path
244 dir = os.path.join(_f.DATA_DIR,'templates')
245 return find_on_search_path(fname, [dir])
247 # ------------------------- vim: set sw=3 sts=3 et: --------------- end-of-file