importing.rb revision 396ba4b002168a7a3dca4f05ac79266b8f26a172
bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch#
5e0ce63bb65db34d7f48b34bbb5545fa791781c4Timo Sirainen# States:
53d794b1cb99c0cc437ec9449d19abf504058390Timo Sirainen# * pending - Job is enqueued.
a857fb61f1cc77a81d18adee6a95ae04c27a5ffbTimo Sirainen# * fetching - Fetching new commits from the remote repository.
53d794b1cb99c0cc437ec9449d19abf504058390Timo Sirainen# * processing - Inserting fetched commits into the local database-
53d794b1cb99c0cc437ec9449d19abf504058390Timo Sirainen# * done - Everthing is fine, nothing to do-
1904e2fc786dbc037039d284b371730777277fc5Aki Tuomi# * failed - Something has gone wrong.
1904e2fc786dbc037039d284b371730777277fc5Aki Tuomi#
1904e2fc786dbc037039d284b371730777277fc5Aki Tuomimodule Repository::Importing
a95a4743552a44f95f72e9bd3ad41cc44609632dTimo Sirainen extend ActiveSupport::Concern
1904e2fc786dbc037039d284b371730777277fc5Aki Tuomi
fb09842fd58e4f8c30de9dd0836434c712c62198Timo Sirainen SOURCE_TYPES = %w( git svn )
53d794b1cb99c0cc437ec9449d19abf504058390Timo Sirainen STATES = State::STATES
5a35caefcf8cf38c347f8406b26701487c8cda57Timo Sirainen
53d794b1cb99c0cc437ec9449d19abf504058390Timo Sirainen IMPORT_INTERVAL = 15.minutes
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen included do
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen include StateUpdater
53d794b1cb99c0cc437ec9449d19abf504058390Timo Sirainen
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen scope :with_source, where("source_type IS NOT null")
53d794b1cb99c0cc437ec9449d19abf504058390Timo Sirainen
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen # Ready for pulling
53d794b1cb99c0cc437ec9449d19abf504058390Timo Sirainen scope :outdated, ->{
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen with_source
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen .where("imported_at IS NULL or imported_at < ?", IMPORT_INTERVAL.ago )
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen .where(state: 'done')
53d794b1cb99c0cc437ec9449d19abf504058390Timo Sirainen }
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen validates_inclusion_of :state, in: STATES
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen validates_with SourceTypeValidator, if: :mirror?
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen before_validation ->{ detect_source_type }
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen after_create ->{ async_remote :clone }, if: :mirror?
35283613d4c04ce18836e9fc431582c87b3710a0Timo Sirainen end
35283613d4c04ce18836e9fc431582c87b3710a0Timo Sirainen
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen def mirror?
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen source_address?
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen end
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen def convert_to_local!
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen self.source_address = nil
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen self.source_type = nil
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen save!
a07b1d77c546256eebda95b7c403e92e1bbcbe94Timo Sirainen end
a07b1d77c546256eebda95b7c403e92e1bbcbe94Timo Sirainen
a07b1d77c546256eebda95b7c403e92e1bbcbe94Timo Sirainen # do not allow new actions in specific states
a07b1d77c546256eebda95b7c403e92e1bbcbe94Timo Sirainen def locked?
a07b1d77c546256eebda95b7c403e92e1bbcbe94Timo Sirainen !%w( done failed ).include?(state)
a07b1d77c546256eebda95b7c403e92e1bbcbe94Timo Sirainen end
a07b1d77c546256eebda95b7c403e92e1bbcbe94Timo Sirainen
a07b1d77c546256eebda95b7c403e92e1bbcbe94Timo Sirainen # enqueues a pull/clone job
53d794b1cb99c0cc437ec9449d19abf504058390Timo Sirainen def async_remote(method)
53d794b1cb99c0cc437ec9449d19abf504058390Timo Sirainen raise "object is #{state}" if locked?
53d794b1cb99c0cc437ec9449d19abf504058390Timo Sirainen update_state! 'pending'
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen async :remote_send, method
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen end
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen # executes a pull/clone job
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen def remote_send(method)
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen # build arguments
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen args = []
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen args << source_address if method == 'clone'
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen # build method name
53d794b1cb99c0cc437ec9449d19abf504058390Timo Sirainen method = method.to_s
53d794b1cb99c0cc437ec9449d19abf504058390Timo Sirainen method += '_svn' if source_type == 'svn'
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen do_or_set_failed do
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen update_state! 'fetching'
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen result = git.send(method, *args)
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen update_state! 'processing'
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen suspended_save_ontologies \
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen start_oid: result.current,
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen stop_oid: result.previous,
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen walk_order: Rugged::SORT_REVERSE
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen self.imported_at = Time.now
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen update_state! 'done'
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen result
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen end
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen end
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen module ClassMethods
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen # creates a new repository and imports the contents from the remote repository
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen def import_remote(type, user, source, name, params={})
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen raise ArgumentError, "invalid source type: #{type}" unless SOURCE_TYPES.include?(type)
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen raise Repository::ImportError, "#{source} is not a #{type} repository" unless GitRepository.send "is_#{type}_repository?", source
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen params[:name] = name
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen params[:source_type] = type
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen params[:source_address] = source
94d0d29f23083c4e79a3fc6b76e9ed761b0e3511Timo Sirainen params[:access] = params[:access] ?
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen Repository::Access.as_read_only(params[:access]) :
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen Repository::Access::DEFAULT_OPTION
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen r = Repository.new(params)
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen r.user = user
53d794b1cb99c0cc437ec9449d19abf504058390Timo Sirainen r.save!
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen r
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen end
eb627e89fba85791ec894e57f96752b1bd64d001Timo Sirainen end
eb627e89fba85791ec894e57f96752b1bd64d001Timo Sirainen
eb627e89fba85791ec894e57f96752b1bd64d001Timo Sirainen protected
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen def detect_source_type
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen if GitRepository.is_git_repository?(source_address)
eb627e89fba85791ec894e57f96752b1bd64d001Timo Sirainen self.source_type = 'git'
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen elsif GitRepository.is_svn_repository?(source_address)
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen self.source_type = 'svn'
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen end
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen end
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen class SourceTypeValidator < ActiveModel::Validator
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen def validate(record)
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen if record.mirror? && !record.source_type.present?
53d794b1cb99c0cc437ec9449d19abf504058390Timo Sirainen record.errors[:source_address] = "not a valid remote repository (types supported: #{SOURCE_TYPES.join(', ')})"
53d794b1cb99c0cc437ec9449d19abf504058390Timo Sirainen record.errors[:source_type] = "not present"
53d794b1cb99c0cc437ec9449d19abf504058390Timo Sirainen end
53d794b1cb99c0cc437ec9449d19abf504058390Timo Sirainen end
30be8c9beaa6944c13d80130fa7a1778b2f8a470Timo Sirainen end
53d794b1cb99c0cc437ec9449d19abf504058390Timo Sirainenend
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen