public
Description: Piston is a utility that eases vendor branch management. This repository is a complete reimplementation of Piston to provide different backends, depending on the repositories and working copies you pistonize from.
Homepage: http://piston.rubyforge.org/
Clone URL: git://github.com/francois/piston.git
Search Repo:
piston / lib / piston / working_copy.rb
100644 125 lines (100 sloc) 3.148 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
117
118
119
120
121
122
123
124
125
module Piston
  class WorkingCopy
    class UnhandledWorkingCopy < RuntimeError; end
    class NotWorkingCopy < RuntimeError; end
 
    class << self
      def logger
        @@logger ||= Log4r::Logger["handler"]
      end
 
      def guess(path)
        path = path.kind_of?(Pathname) ? path : Pathname.new(path.to_s)
        logger.info {"Guessing the working copy type of #{path.inspect}"}
        handler = handlers.detect do |handler|
          logger.debug {"Asking #{handler.name} if it understands #{path}"}
          handler.understands_dir?(path)
        end
 
        raise UnhandledWorkingCopy, "Don't know what working copy type #{path} is." if handler.nil?
        handler.new(path)
      end
 
      @@handlers = Array.new
      def add_handler(handler)
        @@handlers << handler
      end
 
      def handlers
        @@handlers
      end
      private :handlers
    end
 
    attr_reader :path
 
    def initialize(path)
      @path = path.kind_of?(Pathname) ? path : Pathname.new(path)
      logger.debug {"Initialized on #{@path}"}
    end
 
    def logger
      self.class.logger
    end
 
    def to_s
      "Piston::WorkingCopy(#{@path})"
    end
 
    def exist?
      @path.exist? && @path.directory?
    end
    
    def pistonized?
      yaml_path.exist? && yaml_path.file?
    end
 
    # Creates the initial working copy for pistonizing a new repository.
    def create
      logger.debug {"Creating working copy at #{path}"}
    end
 
    # Copy files from +revision+. +revision+ must
    # #respond_to?(:each), and return each file that is to be copied.
    # Only files must be returned.
    #
    # Each item yielded by Revision#each must be a relative path.
    #
    # WorkingCopy will call Revision#copy_to with the full path to where the
    # file needs to be copied.
    def copy_from(revision)
      revision.each do |relpath|
        target = path + relpath
        target.dirname.mkdir rescue nil
 
        logger.debug {"Copying #{relpath} to #{target}"}
        revision.copy_to(relpath, target)
      end
    end
 
    # Stores a Hash of values that can be retrieved later.
    def remember(values, handler_values)
      values["format"] = 1
 
      # Stringify keys
      values.keys.each do |key|
        values[key.to_s] = values.delete(key)
      end
 
      logger.debug {"Remembering #{values.inspect} as well as #{handler_values.inspect}"}
      File.open(yaml_path, "wb") do |f|
        f.write(values.merge("handler" => handler_values).to_yaml)
      end
 
      logger.debug {"Calling \#after_remember on #{yaml_path}"}
      after_remember(yaml_path)
    end
 
    # Callback after #remember is done, to do whatever the
    # working copy needs to do with the file.
    def after_remember(path)
    end
 
    # Recalls a Hash of values from the working copy.
    def recall
      YAML.load(File.read(yaml_path))
    end
 
    def finalize
      logger.debug {"Finalizing #{path}"}
    end
    
    # Returns basic information about this working copy.
    def info
      recall
    end
    
 
    protected
    # The path to the piston YAML file.
    def yaml_path
      path + ".piston.yml"
    end
  end
end