1warn 'Sys has been deprecated in favor of FileUtils'
2
3#--
4# Copyright 2003-2010 by Jim Weirich (jim.weirich@gmail.com)
5# All rights reserved.
6#++
7#
8begin
9  require 'ftools'
10rescue LoadError
11end
12require 'rbconfig'
13require 'rake/file_list'
14
15######################################################################
16# Sys provides a number of file manipulation tools for the convenience
17# of writing Rakefiles.  All commands in this module will announce
18# their activity on standard output if the $verbose flag is set
19# ($verbose = true is the default).  You can control this by globally
20# setting $verbose or by using the +verbose+ and +quiet+ methods.
21#
22# Sys has been deprecated in favor of the FileUtils module available
23# in Ruby 1.8.
24#
25module Sys
26  RUBY = RbConfig::CONFIG['ruby_install_name']
27
28  # Install all the files matching +wildcard+ into the +dest_dir+
29  # directory.  The permission mode is set to +mode+.
30  def install(wildcard, dest_dir, mode)
31    FileList.glob(wildcard).each do |fn|
32      File.install(fn, dest_dir, mode, $verbose)
33    end
34  end
35
36  # Run the system command +cmd+.
37  def run(cmd)
38    log cmd
39    system(cmd) or fail "Command Failed: [#{cmd}]"
40  end
41
42  # Run a Ruby interpreter with the given arguments.
43  def ruby(*args)
44    run "#{RUBY} #{args.join(' ')}"
45  end
46
47  # Copy a single file from +file_name+ to +dest_file+.
48  def copy(file_name, dest_file)
49    log "Copying file #{file_name} to #{dest_file}"
50    File.copy(file_name, dest_file)
51  end
52
53  # Copy all files matching +wildcard+ into the directory +dest_dir+.
54  def copy_files(wildcard, dest_dir)
55    for_matching_files(wildcard, dest_dir) { |from, to| copy(from, to) }
56  end
57
58  # Link +file_name+ to +dest_file+.
59  def link(file_name, dest_file)
60    log "Linking file #{file_name} to #{dest_file}"
61    File.link(file_name, dest_file)
62  end
63
64  # Link all files matching +wildcard+ into the directory +dest_dir+.
65  def link_files(wildcard, dest_dir)
66    for_matching_files(wildcard, dest_dir) { |from, to| link(from, to) }
67  end
68
69  # Symlink +file_name+ to +dest_file+.
70  def symlink(file_name, dest_file)
71    log "Symlinking file #{file_name} to #{dest_file}"
72    File.symlink(file_name, dest_file)
73  end
74
75  # Symlink all files matching +wildcard+ into the directory +dest_dir+.
76  def symlink_files(wildcard, dest_dir)
77    for_matching_files(wildcard, dest_dir) { |from, to| link(from, to) }
78  end
79
80  # Remove all files matching +wildcard+.  If a matching file is a
81  # directory, it must be empty to be removed.  used +delete_all+ to
82  # recursively delete directories.
83  def delete(*wildcards)
84    wildcards.each do |wildcard|
85      FileList.glob(wildcard).each do |fn|
86        if File.directory?(fn)
87          log "Deleting directory #{fn}"
88          Dir.delete(fn)
89        else
90          log "Deleting file #{fn}"
91          File.delete(fn)
92        end
93      end
94    end
95  end
96
97  # Recursively delete all files and directories matching +wildcard+.
98  def delete_all(*wildcards)
99    wildcards.each do |wildcard|
100      FileList.glob(wildcard).each do |fn|
101        next if ! File.exist?(fn)
102        if File.directory?(fn)
103          FileList.glob("#{fn}/*").each do |subfn|
104            next if subfn=='.' || subfn=='..'
105            delete_all(subfn)
106          end
107          log "Deleting directory #{fn}"
108          Dir.delete(fn)
109        else
110          log "Deleting file #{fn}"
111          File.delete(fn)
112        end
113      end
114    end
115  end
116
117  # Make the directories given in +dirs+.
118  def makedirs(*dirs)
119    dirs.each do |fn|
120      log "Making directory #{fn}"
121      File.makedirs(fn)
122    end
123  end
124
125  # Make +dir+ the current working directory for the duration of
126  # executing the given block.
127  def indir(dir)
128    olddir = Dir.pwd
129    Dir.chdir(dir)
130    yield
131  ensure
132    Dir.chdir(olddir)
133  end
134
135  # Split a file path into individual directory names.
136  #
137  # For example:
138  #   split_all("a/b/c") =>  ['a', 'b', 'c']
139  def split_all(path)
140    head, tail = File.split(path)
141    return [tail] if head == '.' || tail == '/'
142    return [head, tail] if head == '/'
143    return split_all(head) + [tail]
144  end
145
146  # Write a message to standard error if $verbose is enabled.
147  def log(msg)
148    print "  " if $trace && $verbose
149    $stderr.puts msg if $verbose
150  end
151
152  # Perform a block with $verbose disabled.
153  def quiet(&block)
154    with_verbose(false, &block)
155  end
156
157  # Perform a block with $verbose enabled.
158  def verbose(&block)
159    with_verbose(true, &block)
160  end
161
162  # Perform a block with each file matching a set of wildcards.
163  def for_files(*wildcards)
164    wildcards.each do |wildcard|
165      FileList.glob(wildcard).each do |fn|
166        yield(fn)
167      end
168    end
169  end
170
171  extend(self)
172
173  private # ----------------------------------------------------------
174
175  def for_matching_files(wildcard, dest_dir)
176    FileList.glob(wildcard).each do |fn|
177      dest_file = File.join(dest_dir, fn)
178      parent = File.dirname(dest_file)
179      makedirs(parent) if ! File.directory?(parent)
180      yield(fn, dest_file)
181    end
182  end
183
184  def with_verbose(v)
185    oldverbose = $verbose
186    $verbose = v
187    yield
188  ensure
189    $verbose = oldverbose
190  end
191
192end
193