Browse files

Add extra module to get updated and created time from git

  • Loading branch information...
1 parent f440966 commit 4e36340cefa2d01e5cb42967b3228ff804a116eb @ai committed May 20, 2012
Showing with 147 additions and 0 deletions.
  1. +2 −0 lib/plain_record.rb
  2. +90 −0 lib/plain_record/git.rb
  3. +55 −0 spec/git_spec.rb
View
2 lib/plain_record.rb
@@ -35,6 +35,8 @@
require dir + 'resource'
module PlainRecord
+ autoload :Git, 'plain_record/git'
+
class << self
# Set new root for Model#entry_in or Model#list_in.
#
View
90 lib/plain_record/git.rb
@@ -0,0 +1,90 @@
+=begin
+Extention to get time from git commits of model file.
+
+Copyright (C) 2012 Andrey “A.I.” Sitnik <andrey@sitnik.ru>,
+sponsored by Evil Martians.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+=end
+
+module PlainRecord
+ # Extention to get time from git commits of model file.
+ #
+ # It make sense only with `entry_in` models. You can get created or modified
+ # time from first or last git commit time.
+ #
+ # It is additional extention, so you need to include `PlainRecord::Git`
+ # module to your model.
+ #
+ # class Post
+ # include PlainRecord::Resource
+ # include PlainRecord::Git
+ #
+ # virtual :created_at, git_created_time
+ # virtual :updated_at, git_modify_time
+ # end
+ module Git
+ class << self
+ def included(base) #:nodoc:
+ base.send :extend, Model
+ end
+ end
+
+ # Return time of first commit of model file (created time).
+ #
+ # If file isn’t commited yet, it will return `Time.now`.
+ def first_git_commit
+ return Time.now unless file
+ times = `git log --reverse --date=iso --pretty=format:%cD #{file}`
+ time = times.split("\n").first
+ time ? Time.parse(time) : Time.now
+ end
+
+ # Return time of last commit of model file (modified time).
+ #
+ # If file isn’t commited yet, it will return `Time.now`.
+ def last_git_commit
+ return Time.now if file.nil? or git_uncommitted?
+ time = `git log -1 --date=iso --pretty=format:%cD #{file}`
+ time ? Time.parse(time) : Time.now
+ end
+
+ # If file have changes, that is not commited yet.
+ def git_uncommitted?
+ not `git status -s #{file}`.empty?
+ end
+
+ module Model
+ def git_modified_time
+ proc do |model, name, type|
+ model.add_accessors <<-EOS, __FILE__, __LINE__
+ def #{name}
+ super || last_git_commit
+ end
+ EOS
+ end
+ end
+
+ def git_created_time
+ proc do |model, name, type|
+ model.add_accessors <<-EOS, __FILE__, __LINE__
+ def #{name}
+ super || first_git_commit
+ end
+ EOS
+ end
+ end
+ end
+ end
+end
View
55 spec/git_spec.rb
@@ -0,0 +1,55 @@
+require File.join(File.dirname(__FILE__), 'spec_helper')
+
+describe PlainRecord::Git do
+
+ before :all do
+ class TimedPost
+ include PlainRecord::Resource
+ include PlainRecord::Git
+
+ entry_in 'data/*/post.md'
+
+ virtual :name, in_filepath(1)
+ field :created, git_created_time
+ field :updated, git_modified_time
+ end
+ end
+
+ before do
+ @post = TimedPost.first(:name => '2')
+
+ @now = Time.at(256)
+ Time.stub!(:now).and_return(@now)
+ end
+
+ it "should take file create time from git" do
+ @post.created.utc.should == Time.parse('2012-05-17 22:23:47 UTC')
+ end
+
+ it "should take file updated time from git" do
+ @post.updated.utc.should == Time.parse('2012-05-18 07:41:52 UTC')
+ end
+
+ it "should overrided git time" do
+ post = TimedPost.new
+
+ post.created = Time.at(0)
+ post.created.should == Time.at(0)
+
+ post.updated = Time.at(1)
+ post.updated.should == Time.at(1)
+ end
+
+ it "should return now for new model" do
+ post = TimedPost.new
+ post.created.should == @now
+ post.updated.should == @now
+ end
+
+ it "shoult return now if file has uncommitted changes" do
+ @post.stub!(:git_uncommitted?).and_return(true)
+ @post.created.utc.should == Time.parse('2012-05-17 22:23:47 UTC')
+ @post.updated.should == @now
+ end
+
+end

0 comments on commit 4e36340

Please sign in to comment.