module Scrivito module Migrations # CMS Migrations can alter the structure and content of the CMS and allow # other developers to simultaneously apply changes. Migrations provide a set # of methods to create, update or delete CMS objects, attributes and object # classes. # # @example Simple Migration # # class CreateTestAttribute < Scrivito::Migrations::Migration # def up # ObjClass.find('Homepage').attributes.add(Attribute.new(name: 'test', type: :string)) # end # end class Migration class << self def copy(destination, sources) unless File.exist?(destination) FileUtils.mkdir_p(destination) end destination_migrations = Scrivito::Migrations::Migrator.determine_migrations(destination) last = destination_migrations.last sources.each do |scope, path| source_migrations = Scrivito::Migrations::Migrator.determine_migrations(path) source_migrations.each do |migration| next if duplicate_migration?(destination_migrations, migration.name, scope) name = migration.name version = next_migration_number(last ? last.version : 0) filename = File.join(destination, "#{version}_#{name.underscore}.#{scope}.rb") new_migration = self.new(name, version, filename, scope) FileUtils.cp(migration.filename, new_migration.filename) last = new_migration destination_migrations << new_migration end end end def duplicate_migration?(migrations, name, scope) migrations.detect do |migration| migration.name == name && migration.scope == scope.to_s end end def next_migration_number(current_migration_number) migration_number = current_migration_number + 1 [Time.now.utc.strftime('%Y%m%d%H%M%S'), '%.14d' % migration_number].max end end attr_accessor :name attr_accessor :version attr_accessor :filename attr_accessor :scope def initialize(name, version, filename, scope) @name = name @version = version.to_i @filename = filename @scope = scope.to_s end def migrate announce 'migrating' time = Benchmark.measure { up } announce 'migrated (%.4fs)' % time.real; puts end private def announce(message) text = "#{version} #{name}: #{message}" length = [0, 75 - text.length].max puts('== %s %s' % [text, '=' * length]) end end end end