Esempio n. 1
0
    def addFileOp(self, cmd, context, source, output_path):
        # Try to detect if our output_path is actually a folder, via trailing
        # slash or '.'/'' indicating the context folder.
        detected_folder = None
        if util.IsString(output_path):
            if output_path[-1] == os.sep or output_path[-1] == os.altsep:
                detected_folder = os.path.join(context.buildFolder,
                                               os.path.normpath(output_path))
            elif output_path == '.' or output_path == '':
                detected_folder = context.buildFolder

            # Since we're building something relative to the context folder, ensure
            # that the context folder exists.
            self.getLocalFolder(context)
        else:
            assert output_path.type != nodetypes.Source
            local_path = os.path.relpath(output_path.path, context.buildFolder)
            detected_folder = os.path.join(context.buildFolder, local_path)
            detected_folder = os.path.normpath(detected_folder)

        source_entry = self.parseInput(context, source)

        # This is similar to a "cp a b/", so we append to get "b/a" as the path.
        if detected_folder is not None:
            base, output_path = os.path.split(source_entry.path)
            assert len(output_path)

            output_folder = detected_folder
        else:
            output_folder = context.buildFolder

        output_path = nodetypes.combine(output_folder, output_path)

        # For copy operations, it's okay to use the path from the current folder.
        # However, when performing symlinks, we always want an absolute path.
        if cmd == nodetypes.Symlink:
            if source_entry.type == nodetypes.Source:
                source_path = source_entry.path
            else:
                source_path = os.path.join(context.buildPath,
                                           source_entry.path)
        else:
            source_path = source_entry.path

        # For clarity of spew, we always execute file operations in the root of
        # the build folder. This means that no matter what context we're in,
        # we can use absolute-ish folders and get away with it.
        return self.addCommand(context=context,
                               node_type=cmd,
                               folder=None,
                               data=(source_path, output_path),
                               inputs=[source_entry],
                               outputs=[output_path])
Esempio n. 2
0
  def addFileOp(self, cmd, context, source, output_path):
    # Try to detect if our output_path is actually a folder, via trailing
    # slash or '.'/'' indicating the context folder.
    detected_folder = None
    if util.IsString(output_path):
      if output_path[-1] == os.sep or output_path[-1] == os.altsep:
        detected_folder = os.path.join(context.buildFolder, os.path.normpath(output_path))
      elif output_path == '.' or output_path == '':
        detected_folder = context.buildFolder

      # Since we're building something relative to the context folder, ensure
      # that the context folder exists.
      self.getLocalFolder(context)
    else:
      assert output_path.type != nodetypes.Source
      local_path = os.path.relpath(output_path.path, context.buildFolder)
      detected_folder = os.path.join(context.buildFolder, local_path)
      detected_folder = os.path.normpath(detected_folder)

    source_entry = self.parseInput(context, source)

    # This is similar to a "cp a b/", so we append to get "b/a" as the path.
    if detected_folder is not None:
      base, output_path = os.path.split(source_entry.path)
      assert len(output_path)

      output_folder = detected_folder
    else:
      output_folder = context.buildFolder

    output_path = nodetypes.combine(output_folder, output_path)

    # For copy operations, it's okay to use the path from the current folder.
    # However, when performing symlinks, we always want an absolute path.
    if cmd == nodetypes.Symlink:
      if source_entry.type == nodetypes.Source:
        source_path = source_entry.path
      else:
        source_path = os.path.join(context.buildPath, source_entry.path)
    else:
      source_path = source_entry.path

    # For clarity of spew, we always execute file operations in the root of
    # the build folder. This means that no matter what context we're in,
    # we can use absolute-ish folders and get away with it.
    return self.addCommand(
      context = context,
      node_type = cmd,
      folder = None,
      data = (source_path, output_path),
      inputs = [source_entry],
      outputs = [output_path]
    )
Esempio n. 3
0
    def parseOutput(self, cwd_entry, path, kind):
        if path[-1] == os.sep or path[
                -1] == os.altsep or path == '.' or path == '':
            util.con_err(util.ConsoleRed, 'Path "', util.ConsoleBlue, path,
                         util.ConsoleRed,
                         '" looks like a folder; a folder was not expected.',
                         util.ConsoleNormal)
            raise Exception('Expected folder, but path has a trailing slash')

        path = os.path.normpath(path)

        path, name = os.path.split(path)
        path = nodetypes.combine(cwd_entry, path)

        # We should have caught a case like 'x/' earlier.
        assert len(name)

        # If we resolved that there is no prefix path, then take this to mean the
        # root folder.
        if path:
            folder_entry = self.validateOutputFolder(path)
            output_path = os.path.join(path, name)
        else:
            folder_entry = None
            output_path = name

        entry = self.db.query_path(output_path)
        if not entry:
            if self.refactoring:
                util.con_err(util.ConsoleRed, 'New output file introduced: ',
                             util.ConsoleBlue, output_path, util.ConsoleNormal)
                raise Exception('Refactoring error')
            return self.db.add_output(folder_entry, output_path, kind)

        if entry.type == kind:
            return entry

        if entry.type == nodetypes.Mkdir:
            if entry not in self.old_folders_:
                util.con_err(util.ConsoleRed,
                             'A folder is being re-used as an output file: "',
                             util.ConsoleBlue, entry.path, util.ConsoleRed,
                             '"', util.ConsoleNormal)
                raise Exception(
                    'Attempted to re-use a folder as generated file')

            if self.refactoring:
                util.con_err(
                    util.ConsoleRed,
                    'A generated folder has changed to a generated file: ',
                    util.ConsoleBlue, entry.path, util.ConsoleNormal)
                raise Exception('Refactoring error')

            # We keep the node in old_folders_. This should be okay, since we've
            # changed the type to Output now. This way we can stick to one folder
            # deletion routine, since it's fairly complicated.
        elif entry.type == nodetypes.Output:
            # If we're asking for a shared output, make sure we can reuse this one.
            input_cmd = self.db.query_command_of(entry)
            if input_cmd and input_cmd not in self.old_commands_:
                util.con_err(util.ConsoleRed, 'First defined with command: ',
                             input_cmd.format(), util.ConsoleNormal)
                raise Exception(
                    'Existing output cannot be a shared output: {0}'.format(
                        entry.path))

            if self.refactoring:
                util.con_err(util.ConsoleRed,
                             'An output has changed to a shared output: ',
                             util.ConsoleBlue, entry.path, util.ConsoleNormal)
                raise Exception('Refactoring error')
        elif entry.type == nodetypes.SharedOutput:
            input_cmds = self.db.query_shared_commands_of(entry)
            for input_cmd in input_cmds:
                if input_cmd not in self.old_commands_:
                    util.con_err(
                        util.ConsoleRed,
                        'A shared output cannot be specified as an normal output.',
                        util.ConsoleNormal)
                    raise Exception(
                        'Existing shared output cannot be a normal output: {0}'
                        .format(entry.path))

            if self.refactoring:
                util.con_err(
                    util.ConsoleRed,
                    'A shared output has changed to a normal output: ',
                    util.ConsoleBlue, entry.path, util.ConsoleNormal)
                raise Exception('Refactoring error')
        else:
            util.con_err(
                util.ConsoleRed,
                'An existing node has been specified as an output file: "',
                util.ConsoleBlue, entry.format(), util.ConsoleRed, '"',
                util.ConsoleNormal)
            raise Exception(
                'Attempted to re-use an incompatible node as an output')

        self.db.change_to_output(entry, kind)
        return entry
Esempio n. 4
0
  def parseOutput(self, cwd_entry, path, kind):
    if path[-1] == os.sep or path[-1] == os.altsep or path == '.' or path == '':
      util.con_err(util.ConsoleRed, 'Path "',
                   util.ConsoleBlue, path,
                   util.ConsoleRed, '" looks like a folder; a folder was not expected.',
                   util.ConsoleNormal)
      raise Exception('Expected folder, but path has a trailing slash')

    path = os.path.normpath(path)

    path, name = os.path.split(path)
    path = nodetypes.combine(cwd_entry, path)

    # We should have caught a case like 'x/' earlier.
    assert len(name)

    # If we resolved that there is no prefix path, then take this to mean the
    # root folder.
    if path:
      folder_entry = self.validateOutputFolder(path)
      output_path = os.path.join(path, name)
    else:
      folder_entry = None
      output_path = name

    entry = self.db.query_path(output_path)
    if not entry:
      if self.refactoring:
        util.con_err(util.ConsoleRed, 'New output file introduced: ',
                     util.ConsoleBlue, output_path,
                     util.ConsoleNormal)
        raise Exception('Refactoring error')
      return self.db.add_output(folder_entry, output_path, kind)

    if entry.type == kind:
      return entry

    if entry.type == nodetypes.Mkdir:
      if entry not in self.old_folders_:
        util.con_err(util.ConsoleRed, 'A folder is being re-used as an output file: "',
                     util.ConsoleBlue, entry.path,
                     util.ConsoleRed, '"',
                     util.ConsoleNormal)
        raise Exception('Attempted to re-use a folder as generated file')

      if self.refactoring:
        util.con_err(util.ConsoleRed, 'A generated folder has changed to a generated file: ',
                     util.ConsoleBlue, entry.path,
                     util.ConsoleNormal)
        raise Exception('Refactoring error')

      # We keep the node in old_folders_. This should be okay, since we've
      # changed the type to Output now. This way we can stick to one folder
      # deletion routine, since it's fairly complicated.
    elif entry.type == nodetypes.Output:
      # If we're asking for a shared output, make sure we can reuse this one.
      input_cmd = self.db.query_command_of(entry)
      if input_cmd and input_cmd not in self.old_commands_:
        util.con_err(util.ConsoleRed, 'First defined with command: ', input_cmd.format(), util.ConsoleNormal)
        raise Exception('Existing output cannot be a shared output: {0}'.format(entry.path))

      if self.refactoring:
        util.con_err(util.ConsoleRed, 'An output has changed to a shared output: ',
                     util.ConsoleBlue, entry.path,
                     util.ConsoleNormal)
        raise Exception('Refactoring error')
    elif entry.type == nodetypes.SharedOutput:
      input_cmds = self.db.query_shared_commands_of(entry)
      for input_cmd in input_cmds:
        if input_cmd not in self.old_commands_:
          util.con_err(util.ConsoleRed, 'A shared output cannot be specified as an normal output.',
                       util.ConsoleNormal)
          raise Exception('Existing shared output cannot be a normal output: {0}'.format(entry.path))

      if self.refactoring:
        util.con_err(util.ConsoleRed, 'A shared output has changed to a normal output: ',
                     util.ConsoleBlue, entry.path,
                     util.ConsoleNormal)
        raise Exception('Refactoring error')
    else:
      util.con_err(util.ConsoleRed, 'An existing node has been specified as an output file: "',
                   util.ConsoleBlue, entry.format(),
                   util.ConsoleRed, '"',
                   util.ConsoleNormal)
      raise Exception('Attempted to re-use an incompatible node as an output')

    self.db.change_to_output(entry, kind)
    return entry