Source

SCons / src / scons / Node / FS.py

Steven Knight 775e51e 









































































































































"""scons.Node.FS

File system nodes.

"""

__revision__ = "Node/FS.py __REVISION__ __DATE__ __DEVELOPER__"



import os
import os.path
from scons.Node import Node



Top = None
Root = {}



def init(path = None):
    """Initialize the Node.FS subsystem.

    The supplied path is the top of the source tree, where we
    expect to find the top-level build file.  If no path is
    supplied, the current directory is the default.
    """
    global Top
    if path == None:
	path = os.getcwd()
    Top = lookup(Dir, path, directory = None)
    Top.path = '.'

def lookup(fsclass, name, directory = Top):
    """Look up a file system node for a path name.  If the path
    name is relative, it will be looked up relative to the
    specified directory node, or to the top-level directory
    if no node was specified.  An initial '#' specifies that
    the name will be looked up relative to the top-level directory,
    regardless of the specified directory argument.  Returns the
    existing or newly-created node for the specified path name.
    The node returned will be of the specified fsclass (Dir or
    File).
    """
    global Top
    head, tail = os.path.split(name)
    if not tail:
	drive, path = os.path.splitdrive(head)
	if not Root.has_key(drive):
	    Root[drive] = Dir(head, None)
	    Root[drive].abspath = head
	    Root[drive].path = head
	return Root[drive]
    if tail[0] == '#':
	directory = Top
	tail = tail[1:]
    elif directory is None:
	directory = Top
    if head:
	directory = lookup(Dir, head, directory)
    try:
	self = directory.entries[tail]
    except AttributeError:
	# There was no "entries" attribute on the directory,
	# which essentially implies that it was a file.
	# Return it as a more descriptive exception.
	raise TypeError, directory
    except KeyError:
	# There was to entry for "tail," so create the new
	# node and link it in to the existing structure.
	self = fsclass(tail, directory)
	self.name = tail
	if self.path[0:2] == "./":
	    self.path = self.path[2:]
	directory.entries[tail] = self
    except:
	raise
    if self.__class__.__name__ != fsclass.__name__:
	# Here, we found an existing node for this path,
	# but it was the wrong type (a File when we were
	# looking for a Dir, or vice versa).
	raise TypeError, self
    return self



# XXX TODO?
# Annotate with the creator
# is_under
# rel_path
# srcpath / srcdir
# link / is_linked
# linked_targets
# is_accessible

class Dir(Node):
    """A class for directories in a file system.
    """

    def __init__(self, name, directory):
	self.entries = {}
	self.entries['.'] = self
	self.entries['..'] = directory
	if not directory is None:
	    self.abspath = os.path.join(directory.abspath, name, '')
	    self.path = os.path.join(directory.path, name, '')

    def up(self):
	return self.entries['..']


# XXX TODO?
# rfile
# precious
# no_rfile
# rpath
# rsrcpath
# source_exists
# derived_exists
# is_on_rpath
# local
# base_suf
# suffix
# addsuffix
# accessible
# ignore
# build
# bind
# is_under
# relpath

class File(Node):
    """A class for files in a file system.
    """

    def __init__(self, name, directory):
	self.abspath = os.path.join(directory.abspath, name)
	self.path = os.path.join(directory.path, name)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.