282f31b2b7ad4ca69287402d6d3a91a280bcb15eJulian Kornberger#
282f31b2b7ad4ca69287402d6d3a91a280bcb15eJulian Kornberger# States:
282f31b2b7ad4ca69287402d6d3a91a280bcb15eJulian Kornberger# * pending - Job is enqueued.
282f31b2b7ad4ca69287402d6d3a91a280bcb15eJulian Kornberger# * fetching - Fetching new commits from the remote repository.
282f31b2b7ad4ca69287402d6d3a91a280bcb15eJulian Kornberger# * processing - Inserting fetched commits into the local database-
282f31b2b7ad4ca69287402d6d3a91a280bcb15eJulian Kornberger# * done - Everthing is fine, nothing to do-
282f31b2b7ad4ca69287402d6d3a91a280bcb15eJulian Kornberger# * failed - Something has gone wrong.
ee5342a8882c2fc7631fcffb5497e6597747887cTim Reddehase#
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornbergermodule Repository::Importing
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger extend ActiveSupport::Concern
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger SOURCE_TYPES = %w( git svn )
8f845e804ef24c045876941e34930a9ac6720dbfEugen Kuksa REMOTE_TYPES = %w( fork mirror )
fda87b00b3f144f81547c33512cd397f211b5bbaSascha Graef STATES = State::STATES
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger
5379e11f2c6c49c6df4872d6a55f2ff390969e66Julian Kornberger IMPORT_INTERVAL = 15.minutes
5379e11f2c6c49c6df4872d6a55f2ff390969e66Julian Kornberger
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger included do
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger include StateUpdater
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger
51da3d91f66d9b359075e91acf63b46b7c13b604Eugen Kuksa before_validation :clean_and_initialize_record
97669a2ab79fef55a04bd6f0e51267e5119ddab7Eugen Kuksa after_commit ->() { call_remote :clone }, on: :create, if: :source_address?
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger end
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger
1d30f949f910951ed77a466a5267ae3069df8410Eugen Kuksa def mirror?
8f845e804ef24c045876941e34930a9ac6720dbfEugen Kuksa remote_type == 'mirror'
63690d8280c5282c6bd057da5330a6ae8859af35Eugen Kuksa end
63690d8280c5282c6bd057da5330a6ae8859af35Eugen Kuksa
63690d8280c5282c6bd057da5330a6ae8859af35Eugen Kuksa def fork?
8f845e804ef24c045876941e34930a9ac6720dbfEugen Kuksa remote_type == 'fork'
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger end
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger
79c84e7439066dd27ecbdab0ecd1379141d7ad1bEugen Kuksa def remote?
79c84e7439066dd27ecbdab0ecd1379141d7ad1bEugen Kuksa REMOTE_TYPES.include?(remote_type)
79c84e7439066dd27ecbdab0ecd1379141d7ad1bEugen Kuksa end
79c84e7439066dd27ecbdab0ecd1379141d7ad1bEugen Kuksa
08070fff5598f6d5d7662e321becf59f18d00176Eugen Kuksa def convert_to_local!
8f845e804ef24c045876941e34930a9ac6720dbfEugen Kuksa self.remote_type = 'fork'
08070fff5598f6d5d7662e321becf59f18d00176Eugen Kuksa save!
08070fff5598f6d5d7662e321becf59f18d00176Eugen Kuksa end
08070fff5598f6d5d7662e321becf59f18d00176Eugen Kuksa
282f31b2b7ad4ca69287402d6d3a91a280bcb15eJulian Kornberger # do not allow new actions in specific states
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger def locked?
282f31b2b7ad4ca69287402d6d3a91a280bcb15eJulian Kornberger !%w( done failed ).include?(state)
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger end
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger
5379e11f2c6c49c6df4872d6a55f2ff390969e66Julian Kornberger # enqueues a pull/clone job
56f97c5af9f86663f034049274ae16642c5ba4dfEugen Kuksa def call_remote(method)
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger raise "object is #{state}" if locked?
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger update_state! 'pending'
c975e932187f329ac00049d8fd7cc796633f9e92Eugen Kuksa RepositoryFetchingWorker.perform_async(id, method, remote_type)
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger end
93ff918a7a1656d812f27a767a976ea33da0921fJulian Kornberger
5379e11f2c6c49c6df4872d6a55f2ff390969e66Julian Kornberger # executes a pull/clone job
c975e932187f329ac00049d8fd7cc796633f9e92Eugen Kuksa def fetch(method, remote_type = nil)
5379e11f2c6c49c6df4872d6a55f2ff390969e66Julian Kornberger # build arguments
5379e11f2c6c49c6df4872d6a55f2ff390969e66Julian Kornberger args = []
5379e11f2c6c49c6df4872d6a55f2ff390969e66Julian Kornberger args << source_address if method == 'clone'
5379e11f2c6c49c6df4872d6a55f2ff390969e66Julian Kornberger
5379e11f2c6c49c6df4872d6a55f2ff390969e66Julian Kornberger # build method name
93ff918a7a1656d812f27a767a976ea33da0921fJulian Kornberger method = method.to_s
5379e11f2c6c49c6df4872d6a55f2ff390969e66Julian Kornberger method += '_svn' if source_type == 'svn'
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger do_or_set_failed do
d94a4d9e48f0ca6d52f1bb7ed7860dbcadbd90d6Eugen Kuksa process_fetch(method, args, remote_type)
d94a4d9e48f0ca6d52f1bb7ed7860dbcadbd90d6Eugen Kuksa end
d94a4d9e48f0ca6d52f1bb7ed7860dbcadbd90d6Eugen Kuksa end
282f31b2b7ad4ca69287402d6d3a91a280bcb15eJulian Kornberger
d94a4d9e48f0ca6d52f1bb7ed7860dbcadbd90d6Eugen Kuksa def process_fetch(method, args, remote_type)
d94a4d9e48f0ca6d52f1bb7ed7860dbcadbd90d6Eugen Kuksa update_state! 'fetching'
d94a4d9e48f0ca6d52f1bb7ed7860dbcadbd90d6Eugen Kuksa result = git.send(method, *args)
d94a4d9e48f0ca6d52f1bb7ed7860dbcadbd90d6Eugen Kuksa convert_to_local! if remote_type == 'fork'
282f31b2b7ad4ca69287402d6d3a91a280bcb15eJulian Kornberger
d94a4d9e48f0ca6d52f1bb7ed7860dbcadbd90d6Eugen Kuksa update_state! 'processing'
d94a4d9e48f0ca6d52f1bb7ed7860dbcadbd90d6Eugen Kuksa update_database_after_fetch(result)
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger
d94a4d9e48f0ca6d52f1bb7ed7860dbcadbd90d6Eugen Kuksa self.imported_at = Time.now
d94a4d9e48f0ca6d52f1bb7ed7860dbcadbd90d6Eugen Kuksa update_state! 'done'
d94a4d9e48f0ca6d52f1bb7ed7860dbcadbd90d6Eugen Kuksa
d94a4d9e48f0ca6d52f1bb7ed7860dbcadbd90d6Eugen Kuksa result
d94a4d9e48f0ca6d52f1bb7ed7860dbcadbd90d6Eugen Kuksa end
d94a4d9e48f0ca6d52f1bb7ed7860dbcadbd90d6Eugen Kuksa
d94a4d9e48f0ca6d52f1bb7ed7860dbcadbd90d6Eugen Kuksa def update_database_after_fetch(range)
006de713cc0c62dc3dd8549f4d74c00e8b822dd2Eugen Kuksa OntologySaver.new(self).
006de713cc0c62dc3dd8549f4d74c00e8b822dd2Eugen Kuksa suspended_save_ontologies(start_oid: range.current,
006de713cc0c62dc3dd8549f4d74c00e8b822dd2Eugen Kuksa stop_oid: range.previous,
006de713cc0c62dc3dd8549f4d74c00e8b822dd2Eugen Kuksa walk_order: :reverse)
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger end
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger module ClassMethods
8f845e804ef24c045876941e34930a9ac6720dbfEugen Kuksa # Creates a new repository and imports the contents from the remote
8f845e804ef24c045876941e34930a9ac6720dbfEugen Kuksa # repository.
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger def import_remote(type, user, source, name, params={})
8f845e804ef24c045876941e34930a9ac6720dbfEugen Kuksa unless SOURCE_TYPES.include?(type)
8f845e804ef24c045876941e34930a9ac6720dbfEugen Kuksa raise ArgumentError, "invalid source type: #{type}"
8f845e804ef24c045876941e34930a9ac6720dbfEugen Kuksa end
8f845e804ef24c045876941e34930a9ac6720dbfEugen Kuksa unless GitRepository.send "is_#{type}_repository?", source
8f845e804ef24c045876941e34930a9ac6720dbfEugen Kuksa raise Repository::ImportError, "#{source} is not a #{type} repository"
8f845e804ef24c045876941e34930a9ac6720dbfEugen Kuksa end
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger params[:name] = name
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger params[:source_type] = type
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger params[:source_address] = source
e81334464ee46b772442343c2f871ea82d4a3c82Eugen Kuksa params[:access] = params[:access] ?
e81334464ee46b772442343c2f871ea82d4a3c82Eugen Kuksa Repository::Access.as_read_only(params[:access]) :
e81334464ee46b772442343c2f871ea82d4a3c82Eugen Kuksa Repository::Access::DEFAULT_OPTION
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger
89575ed6ea1f9c9058164005c0c8a64e8aeae3a4Julian Kornberger r = Repository.new(params)
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger r.user = user
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger r.save!
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger r
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger end
5422b48ab5841a2909cd9e53905dae4cd8418f0aJulian Kornberger end
39d0ed9f8e3c74205b66e86abcf317c6a56900ccEugen Kuksa
39d0ed9f8e3c74205b66e86abcf317c6a56900ccEugen Kuksa protected
39d0ed9f8e3c74205b66e86abcf317c6a56900ccEugen Kuksa
51da3d91f66d9b359075e91acf63b46b7c13b604Eugen Kuksa def clean_and_initialize_record
51da3d91f66d9b359075e91acf63b46b7c13b604Eugen Kuksa self.remote_type = nil unless source_address?
51da3d91f66d9b359075e91acf63b46b7c13b604Eugen Kuksa detect_source_type if new_record?
51da3d91f66d9b359075e91acf63b46b7c13b604Eugen Kuksa end
51da3d91f66d9b359075e91acf63b46b7c13b604Eugen Kuksa
8f845e804ef24c045876941e34930a9ac6720dbfEugen Kuksa def detect_source_type
54df3ee204cac2763de267b1b3de745c908c20b5Eugen Kuksa if source_address?
6370334d0670bd95d0685a2f5ab9b85ade15f68bEugen Kuksa self.source_type =
6370334d0670bd95d0685a2f5ab9b85ade15f68bEugen Kuksa if GitRepository.is_git_repository?(source_address)
6370334d0670bd95d0685a2f5ab9b85ade15f68bEugen Kuksa 'git'
6370334d0670bd95d0685a2f5ab9b85ade15f68bEugen Kuksa elsif GitRepository.is_svn_repository?(source_address)
6370334d0670bd95d0685a2f5ab9b85ade15f68bEugen Kuksa 'svn'
6370334d0670bd95d0685a2f5ab9b85ade15f68bEugen Kuksa end
8f845e804ef24c045876941e34930a9ac6720dbfEugen Kuksa end
8f845e804ef24c045876941e34930a9ac6720dbfEugen Kuksa end
08070fff5598f6d5d7662e321becf59f18d00176Eugen Kuksaend