Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

FileTask#timestamp should also include prereq timestamps #104

Closed
zenspider opened this Issue · 6 comments

3 participants

@zenspider

Running this rakefile as-is:

# -*- ruby -*-

class Rake::FileTask
  def timestamp
    if File.exist?(name)
      if ENV['ORIGINAL'] then
        File.mtime(name.to_s)
      else
        [File.mtime(name.to_s), super].max
      end
    else
      Rake::EARLY
    end
  end
end

rm_f %w[a.out f.c f.h]
sh "touch -t 200001010101 a.out f.c f.h"
sh "touch f.h"

file "a.out" => "f.c"

file "f.c" => "f.h"

task :clean do
  rm_f %w[a.out f.c f.h]
end

outputs with the original:

% rake -t a.out ORIGINAL=1
rm -f a.out f.c f.h
touch -t 200001010101 a.out f.c f.h
touch f.h
** Invoke a.out (first_time, not_needed)
** Invoke f.c (first_time)
** Invoke f.h (first_time, not_needed)
** Execute f.c

vs my patched version:

% rake -t a.out
rm -f a.out f.c f.h
touch -t 200001010101 a.out f.c f.h
touch f.h
** Invoke a.out (first_time)
** Invoke f.c (first_time)
** Invoke f.h (first_time, not_needed)
** Execute f.c
** Execute a.out
@zenspider

The problem is a bit trickier than I thought. I wound up with:

class Rake::FileTask
  alias old_needed? needed?
  alias old_timestamp timestamp

  def needed?
    ! File.exist?(name) || timestamp > real_timestamp
  end

  def real_timestamp
    File.exist?(name) && File.mtime(name.to_s) || Rake::EARLY
  end

  def timestamp
    if File.exist?(name)
      a = File.mtime(name.to_s)
      b = super unless prerequisites.empty?
      [a, b].compact.max
    else
      Rake::EARLY
    end
  end
end

Basically, a file task should always rebuild if it is older than one of its dependencies. This adds real_timestamp to the mix and compares it against the max timestamp of its deps.

@zenspider

PING

@zenspider

I'm tired of non-communication. I've released this in makerakeworkwell.

@jimweirich
Owner

Catching up on the backlog of open requests.

I know you and I have come to different conclusions on this topic, so be it. I feel that changing the semantics of the file task to be too large a change at this point for Rake.

I am entertaining the idea of introducing a new type of file task that supports these semantics, perhaps as an experimental add-on. But for now, I'm closing this issue.

@jimweirich jimweirich closed this
@DavidEGrayson

@zenspider Isn't the following line from your Rakefile wrong?

file "f.c" => "f.h"

In a typical C project, the file f.c would already exist and there doesn't need to be a task for building it. The contents of f.c do not depend on f.h.

I think you should try this instead, because the contents of a.out do depend on the contents of f.h:

file "a.out" => "f.h"

EDIT: I read the makerakeworkwell page and can see you have already considered my suggestion and decided against it, but my comment might benefit other people coming across this thread.

@zenspider

a.out depends on f.o depends on f.c depends on f.h.

Maybe f.c exists, maybe it doesn't.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.