git_repositories.rb revision 556d9e007120cfbfbb79070544b4928f26bfa0eb
1057N/Arequire 'git_repository'
1057N/A
1057N/Amodule Repository::GitRepositories
1057N/A extend ActiveSupport::Concern
1703N/A
1057N/A delegate :dir?, :points_through_file?, :has_changed?, :commits, to: :git
660N/A
1057N/A included do
1057N/A after_create :create_and_init_git
1057N/A after_destroy :destroy_git
1057N/A end
1057N/A
1057N/A def git
1057N/A @git ||= GitRepository.new(local_path.to_s)
1057N/A end
1057N/A
1057N/A def local_path
1057N/A Ontohub::Application.config.git_root.join(id.to_s)
1057N/A end
1057N/A
660N/A def create_and_init_git
3311N/A git
1109N/A symlink_name = local_path.join("hooks")
2506N/A symlink_name.rmtree
2737N/A symlink_name.make_symlink(Rails.root.join('git','hooks').
2737N/A # replace capistrano-style release with 'current'-symlink
2737N/A sub(%r{/releases/\d+/}, '/current/'))
2437N/A end
2437N/A
2437N/A def destroy_git
3356N/A git.destroy
3356N/A end
2506N/A
2737N/A def empty?
2737N/A git.empty?
2737N/A end
2557N/A
2557N/A def is_head?(commit_oid=nil)
2557N/A git.is_head?(commit_oid)
2557N/A end
2737N/A
2737N/A def delete_file(filepath, user, message = nil, &block)
2737N/A message ||= "delete file #{filepath}"
2737N/A git.delete_file(user_info(user), filepath, &block)
2737N/A end
2557N/A
2557N/A def save_file(tmp_file, filepath, message, user, iri=nil)
2437N/A version = nil
2737N/A
2737N/A git.add_file(user_info(user), tmp_file, filepath, message) do |commit_oid|
2737N/A version = save_ontology(commit_oid, filepath, user, iri: iri)
2737N/A end
2737N/A touch
2557N/A version
2557N/A end
2557N/A
2557N/A def save_file_only(tmp_file, filepath, message, user)
2737N/A commit = nil
2737N/A name = user ? user.name : Settings.fallback_commit_user
2737N/A email = user ? user.email : Settings.fallback_commit_email
2437N/A git.add_file({email: email, name: name}, tmp_file, filepath, message) do |commit_oid|
2437N/A commit = commit_oid
2437N/A end
2506N/A touch
2506N/A commit
2737N/A end
2095N/A
2095N/A def save_ontology(commit_oid, filepath, user=nil, iri: nil, fast_parse: false, do_not_parse: false, previous_filepath: nil)
2095N/A # we expect that this method is only called, when the ontology is 'present'
2737N/A return unless Ontology.file_extensions.include?(File.extname(filepath))
2437N/A version = nil
2437N/A basepath = File.basepath(filepath)
2437N/A previous_basepath = File.basepath(previous_filepath) if previous_filepath
2737N/A file_extension = File.extname(filepath)
2437N/A o = ontologies.with_basepath(previous_basepath || basepath).without_parent.first
2437N/A
2437N/A if o
2437N/A return if !master_file?(o, previous_filepath || filepath)
2506N/A o.present = true
2506N/A unless o.versions.find_by_commit_oid(commit_oid)
2737N/A # update existing ontology
2095N/A version = o.versions.build({ commit_oid: commit_oid,
2095N/A user: user,
2095N/A basepath: basepath,
2737N/A file_extension: file_extension,
2095N/A fast_parse: fast_parse },
2095N/A { without_protection: true })
2095N/A o.ontology_version = version
2737N/A version.do_not_parse! if do_not_parse
2095N/A o.save!
2095N/A end
2095N/A else
2737N/A # create new ontology
2557N/A clazz = Ontology.file_extensions_distributed.include?(File.extname(filepath)) ? DistributedOntology : SingleOntology
2557N/A o = clazz.new
2557N/A o.basepath = basepath
2557N/A o.file_extension = file_extension
2557N/A
2557N/A o.iri = iri || generate_iri(basepath)
2557N/A o.name = filepath.split('/')[-1].split(".")[0].capitalize
2737N/A
2095N/A o.repository = self
2095N/A o.present = true
2095N/A o.save!
2095N/A version = o.versions.build({ commit_oid: commit_oid,
2095N/A user: user,
2437N/A basepath: basepath,
2506N/A file_extension: file_extension,
2506N/A fast_parse: fast_parse },
2506N/A { without_protection: true })
2737N/A version.do_not_parse! if do_not_parse
2737N/A version.save!
2737N/A o.ontology_version = version
2557N/A o.save!
2557N/A end
2557N/A
2557N/A version
2737N/A end
2737N/A
2737N/A def path_exists?(path, commit_oid=nil)
2737N/A path ||= '/'
2737N/A git.path_exists?(path, commit_oid)
2557N/A end
2557N/A
2557N/A def paths_starting_with(path, commit_oid=nil)
2557N/A dir = dir?(path, commit_oid) ? path : path.split('/')[0..-2].join('/')
2737N/A contents = git.folder_contents(commit_oid, dir)
2737N/A
2737N/A contents.map{ |entry| entry[:path] }.select{ |p| p.starts_with?(path) }
2506N/A end
2506N/A
2506N/A def path_info(path=nil, commit_oid=nil)
2737N/A path ||= '/'
2557N/A
2557N/A if git.empty?
2557N/A return { type: :dir, entries: [] }
2557N/A end
2506N/A
2506N/A if path_exists?(path, commit_oid)
2557N/A file = git.get_file(path, commit_oid)
2557N/A if file
2737N/A {
2557N/A type: :file,
2557N/A file: file,
2557N/A ontologies: ontologies.with_path(path).parents_first
2557N/A }
2557N/A else
2557N/A entries = list_folder(path, commit_oid)
2557N/A entries.each do |name, es|
2737N/A es.each do |e|
2095N/A e[:ontologies] = ontologies.with_path(e[:path]).parents_first
2095N/A end
2095N/A es.sort_by! { |e| -e[:ontologies].size }
2737N/A end
2437N/A {
2437N/A type: :dir,
2437N/A entries: entries
2737N/A }
2506N/A end
2506N/A else
2506N/A file = path.split('/')[-1]
2737N/A path = path.split('/')[0..-2].join('/')
2506N/A
2506N/A entries = git.folder_contents(commit_oid, path).select { |e| e[:name].split('.')[0] == file }
2506N/A
2737N/A case
2095N/A when entries.empty?
2095N/A nil
2095N/A when entries.size == 1
2737N/A {
2095N/A type: :file_base,
2095N/A entry: entries[0],
2095N/A }
2737N/A else
2095N/A {
2095N/A type: :file_base_ambiguous,
2095N/A entries: entries
2737N/A }
2095N/A end
2095N/A end
2095N/A end
2095N/A
2095N/A def read_file(filepath, commit_oid=nil)
2095N/A git.get_file(filepath, commit_oid)
2095N/A end
2095N/A
2095N/A # given a commit oid or a branch name, commit_id returns a hash of oid and branch name if existent
2095N/A def commit_id(oid)
2506N/A return { oid: git.head_oid, branch_name: 'master' } if oid.nil?
2095N/A if oid.match /[0-9a-fA-F]{40}/
2095N/A branch_names = git.branches.select { |b| b[:oid] == oid }
2095N/A if branch_names.empty?
2095N/A { oid: oid, branch_name: nil }
2095N/A else
2095N/A { oid: oid, branch_name: branch_names[0][:name] }
2095N/A end
2737N/A else
2095N/A if git.branch_oid(oid).nil?
2737N/A nil
2737N/A else
2737N/A { oid: git.branch_oid(oid), branch_name: oid }
2095N/A end
2095N/A end
2095N/A end
2737N/A
2737N/A def commit_message(oid=nil)
2737N/A git.commit_message(oid)
2737N/A end
2737N/A
2737N/A def entries_info(oid=nil, path=nil)
2737N/A dirpath = git.get_path_of_dir(oid, path)
2737N/A git.entries_info(oid,dirpath)
2737N/A end
2437N/A
2437N/A def changed_files(oid=nil)
2437N/A git.changed_files(commit_id(oid)[:oid])
2737N/A end
2737N/A
2737N/A def recent_changes
2543N/A commits(limit: 3)
2437N/A end
2437N/A
2437N/A def suspended_save_ontologies(options={})
2737N/A versions = []
2737N/A commits(options) { |commit|
2737N/A git.changed_files(commit.oid).each { |f|
2437N/A if f.added? || f.modified?
2437N/A versions << save_ontology(commit.oid, f.path, options.delete(:user), fast_parse: has_changed?(f.path, commit.oid), do_not_parse: true)
2437N/A elsif f.renamed?
2737N/A versions << save_ontology(commit.oid, f.path, options.delete(:user), fast_parse: has_changed?(f.path, commit.oid), do_not_parse: true, previous_filepath: f.delta.old_file[:path])
2543N/A end
2543N/A }
2543N/A }
2737N/A
2437N/A schedule_batch_parsing(versions)
2437N/A end
2437N/A
2737N/A def schedule_batch_parsing(versions)
2737N/A grouped_versions = versions.compact.group_by { |v| v.path }
2737N/A grouped_versions.each do |k,versions|
2543N/A optioned_versions = versions.map do |version|
2437N/A [version.id, { fast_parse: version.fast_parse }]
2737N/A end
2737N/A OntologyBatchParseWorker.perform_async(optioned_versions)
2737N/A end
2437N/A end
2437N/A
2437N/A def user_info(user)
2437N/A {email: user.email, name: user.name}
2506N/A end
2095N/A
2737N/A def master_file?(ontology, filepath)
2557N/A ontology.path == filepath
2557N/A end
2557N/A
2737N/A def generate_iri(basepath)
2557N/A "http://#{Settings.hostname}/#{self.path}/#{basepath}"
2557N/A end
2557N/Aend
1703N/A