1. SCons
  2. Core
  3. SCons


SCons / src / scons / Node / FS.py


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
    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)
	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
    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

# 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['..']

# 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)