summaryrefslogtreecommitdiff
path: root/lib/rake/contrib/sys.rb
blob: aefd4a19133f82375c90955d343bda7dbfec7a7e (plain)
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
warn 'Sys has been deprecated in favor of FileUtils'

#--
# Copyright 2003-2010 by Jim Weirich (jim.weirich@gmail.com)
# All rights reserved.
#++
#
begin
  require 'ftools'
rescue LoadError
end
require 'rbconfig'

######################################################################
# Sys provides a number of file manipulation tools for the convenience
# of writing Rakefiles.  All commands in this module will announce
# their activity on standard output if the $verbose flag is set
# ($verbose = true is the default).  You can control this by globally
# setting $verbose or by using the +verbose+ and +quiet+ methods.
#
# Sys has been deprecated in favor of the FileUtils module available
# in Ruby 1.8.
#
module Sys
  RUBY = RbConfig::CONFIG['ruby_install_name']

  # Install all the files matching +wildcard+ into the +dest_dir+
  # directory.  The permission mode is set to +mode+.
  def install(wildcard, dest_dir, mode)
    Rake.glob(wildcard).each do |fn|
      File.install(fn, dest_dir, mode, $verbose)
    end
  end

  # Run the system command +cmd+.
  def run(cmd)
    log cmd
    system(cmd) or fail "Command Failed: [#{cmd}]"
  end

  # Run a Ruby interpreter with the given arguments.
  def ruby(*args)
    run "#{RUBY} #{args.join(' ')}"
  end

  # Copy a single file from +file_name+ to +dest_file+.
  def copy(file_name, dest_file)
    log "Copying file #{file_name} to #{dest_file}"
    File.copy(file_name, dest_file)
  end

  # Copy all files matching +wildcard+ into the directory +dest_dir+.
  def copy_files(wildcard, dest_dir)
    for_matching_files(wildcard, dest_dir) { |from, to| copy(from, to) }
  end

  # Link +file_name+ to +dest_file+.
  def link(file_name, dest_file)
    log "Linking file #{file_name} to #{dest_file}"
    File.link(file_name, dest_file)
  end

  # Link all files matching +wildcard+ into the directory +dest_dir+.
  def link_files(wildcard, dest_dir)
    for_matching_files(wildcard, dest_dir) { |from, to| link(from, to) }
  end

  # Symlink +file_name+ to +dest_file+.
  def symlink(file_name, dest_file)
    log "Symlinking file #{file_name} to #{dest_file}"
    File.symlink(file_name, dest_file)
  end

  # Symlink all files matching +wildcard+ into the directory +dest_dir+.
  def symlink_files(wildcard, dest_dir)
    for_matching_files(wildcard, dest_dir) { |from, to| link(from, to) }
  end

  # Remove all files matching +wildcard+.  If a matching file is a
  # directory, it must be empty to be removed.  used +delete_all+ to
  # recursively delete directories.
  def delete(*wildcards)
    wildcards.each do |wildcard|
      Rake.glob(wildcard).each do |fn|
        if File.directory?(fn)
          log "Deleting directory #{fn}"
          Dir.delete(fn)
        else
          log "Deleting file #{fn}"
          File.delete(fn)
        end
      end
    end
  end

  # Recursively delete all files and directories matching +wildcard+.
  def delete_all(*wildcards)
    wildcards.each do |wildcard|
      Rake.glob(wildcard).each do |fn|
        next if ! File.exist?(fn)
        if File.directory?(fn)
          Rake.glob("#{fn}/*").each do |subfn|
            next if subfn=='.' || subfn=='..'
            delete_all(subfn)
          end
          log "Deleting directory #{fn}"
          Dir.delete(fn)
        else
          log "Deleting file #{fn}"
          File.delete(fn)
        end
      end
    end
  end

  # Make the directories given in +dirs+.
  def makedirs(*dirs)
    dirs.each do |fn|
      log "Making directory #{fn}"
      File.makedirs(fn)
    end
  end

  # Make +dir+ the current working directory for the duration of
  # executing the given block.
  def indir(dir)
    olddir = Dir.pwd
    Dir.chdir(dir)
    yield
  ensure
    Dir.chdir(olddir)
  end

  # Split a file path into individual directory names.
  #
  # For example:
  #   split_all("a/b/c") =>  ['a', 'b', 'c']
  def split_all(path)
    head, tail = File.split(path)
    return [tail] if head == '.' || tail == '/'
    return [head, tail] if head == '/'
    return split_all(head) + [tail]
  end

  # Write a message to standard error if $verbose is enabled.
  def log(msg)
    print "  " if $trace && $verbose
    $stderr.puts msg if $verbose
  end

  # Perform a block with $verbose disabled.
  def quiet(&block)
    with_verbose(false, &block)
  end

  # Perform a block with $verbose enabled.
  def verbose(&block)
    with_verbose(true, &block)
  end

  # Perform a block with each file matching a set of wildcards.
  def for_files(*wildcards)
    wildcards.each do |wildcard|
      Rake.glob(wildcard).each do |fn|
        yield(fn)
      end
    end
  end

  extend(self)

  private # ----------------------------------------------------------

  def for_matching_files(wildcard, dest_dir)
    Rake.glob(wildcard).each do |fn|
      dest_file = File.join(dest_dir, fn)
      parent = File.dirname(dest_file)
      makedirs(parent) if ! File.directory?(parent)
      yield(fn, dest_file)
    end
  end

  def with_verbose(v)
    oldverbose = $verbose
    $verbose = v
    yield
  ensure
    $verbose = oldverbose
  end

end