Support searching jobs by script_version_descends_from. refs #1445
[arvados.git] / app / models / commit_ancestor.rb
diff --git a/app/models/commit_ancestor.rb b/app/models/commit_ancestor.rb
new file mode 100644 (file)
index 0000000..c3c6d53
--- /dev/null
@@ -0,0 +1,40 @@
+# Usage:
+#
+# x = CommitAncestor.find_or_create_by_descendant_and_ancestor(a, b)
+# "b is an ancestor of a" if x.is
+#
+
+class CommitAncestor < ActiveRecord::Base
+  before_create :ask_git_whether_is
+
+  class CommitNotFoundError < ArgumentError
+  end
+
+  protected
+
+  def ask_git_whether_is
+    @gitdirbase = Rails.configuration.git_repositories_dir
+    self.is = nil
+    Dir.foreach @gitdirbase do |repo|
+      next if repo.match /^\./
+      git_dir = repo.match(/\.git$/) ? repo : File.join(repo, '.git')
+      repo_name = repo.sub(/\.git$/, '')
+      ENV['GIT_DIR'] = File.join(@gitdirbase, repo, '.git')
+      IO.foreach("|git rev-list --format=oneline '#{self.descendant.gsub /[^0-9a-f]/,""}'") do |line|
+        self.is = false
+        sha1, message = line.strip.split(" ", 2)
+        if sha1 == self.ancestor
+          self.is = true
+          break
+        end
+      end
+      if !self.is.nil?
+        self.repository_name = repo_name
+        break
+      end
+    end
+    if self.is.nil?
+      raise CommitNotFoundError: "Specified commit was not found"
+    end
+  end
+end