diff --git a/lib/travis/api/v3.rb b/lib/travis/api/v3.rb index 824f90bd..d2c19859 100644 --- a/lib/travis/api/v3.rb +++ b/lib/travis/api/v3.rb @@ -21,6 +21,7 @@ module Travis end extend self + load_dir("#{__dir__}/v3/extensions") load_dir("#{__dir__}/v3") ClientError = Error .create(status: 400) diff --git a/lib/travis/api/v3/access_control/generic.rb b/lib/travis/api/v3/access_control/generic.rb index 8c49dce9..fd68c26f 100644 --- a/lib/travis/api/v3/access_control/generic.rb +++ b/lib/travis/api/v3/access_control/generic.rb @@ -52,8 +52,17 @@ module Travis::API::V3 private def dispatch(object, method = caller_locations.first.base_label) - method = object.class.name.underscore + ?_.freeze + method + method = method_for(object.class, method) send(method, object) if respond_to?(method, true) end + + @@method_for_cache = Tool::ThreadLocal.new + + def method_for(type, method) + @@method_for_cache[[type, method]] ||= begin + prefix = type.name.sub(/^Travis::API::V3::Models::/, ''.freeze).underscore + "#{prefix}_#{method}" + end + end end end diff --git a/lib/travis/api/v3/extensions/belongs_to.rb b/lib/travis/api/v3/extensions/belongs_to.rb new file mode 100644 index 00000000..dc0fcba3 --- /dev/null +++ b/lib/travis/api/v3/extensions/belongs_to.rb @@ -0,0 +1,32 @@ +module Travis::API::V3 + module Extensions + module BelongsTo + module ClassMethods + def polymorfic_foreign_types + @polymorfic_foreign_types ||= [] + end + + def belongs_to(field, options = {}) + polymorfic_foreign_types << (options[:foreign_type] || "#{field}_type") if options[:polymorphic] + super + end + end + + def self.included(base) + base.extend(ClassMethods) + super + end + + def [](key) + value = super + value &&= "#{self.class.parent}::#{value}" if self.class.polymorfic_foreign_types.include?(key) + value + end + + def []=(key, value) + value &&= value.sub("#{self.class.parent}::") if self.class.polymorfic_foreign_types.include?(key) + super(key, value) + end + end + end +end diff --git a/lib/travis/api/v3/model.rb b/lib/travis/api/v3/model.rb new file mode 100644 index 00000000..90b26d1d --- /dev/null +++ b/lib/travis/api/v3/model.rb @@ -0,0 +1,6 @@ +module Travis::API::V3 + class Model < ActiveRecord::Base + include Extensions::BelongsTo + self.abstract_class = true + end +end diff --git a/lib/travis/api/v3/models.rb b/lib/travis/api/v3/models.rb new file mode 100644 index 00000000..3504a13a --- /dev/null +++ b/lib/travis/api/v3/models.rb @@ -0,0 +1,5 @@ +module Travis::API::V3 + module Models + extend ConstantResolver + end +end diff --git a/lib/travis/api/v3/models/broadcast.rb b/lib/travis/api/v3/models/broadcast.rb new file mode 100644 index 00000000..9c713d8e --- /dev/null +++ b/lib/travis/api/v3/models/broadcast.rb @@ -0,0 +1,5 @@ +module Travis::API::V3 + class Models::Broadcast < Model + belongs_to :recipient, polymorphic: true + end +end diff --git a/lib/travis/api/v3/models/build.rb b/lib/travis/api/v3/models/build.rb new file mode 100644 index 00000000..9b7f766b --- /dev/null +++ b/lib/travis/api/v3/models/build.rb @@ -0,0 +1,10 @@ +module Travis::API::V3 + class Models::Build < Model + belongs_to :repository + belongs_to :commit + belongs_to :request + belongs_to :repository, autosave: true + belongs_to :owner, polymorphic: true + has_many :jobs, as: :source, order: :id, dependent: :destroy + end +end diff --git a/lib/travis/api/v3/models/commit.rb b/lib/travis/api/v3/models/commit.rb new file mode 100644 index 00000000..ac1add22 --- /dev/null +++ b/lib/travis/api/v3/models/commit.rb @@ -0,0 +1,6 @@ +module Travis::API::V3 + class Models::Commit < Model + belongs_to :repository + has_one :request + end +end diff --git a/lib/travis/api/v3/models/email.rb b/lib/travis/api/v3/models/email.rb new file mode 100644 index 00000000..6fd9cd7e --- /dev/null +++ b/lib/travis/api/v3/models/email.rb @@ -0,0 +1,5 @@ +module Travis::API::V3 + class Models::Email < Model + belongs_to :user + end +end diff --git a/lib/travis/api/v3/models/job.rb b/lib/travis/api/v3/models/job.rb new file mode 100644 index 00000000..2db5df10 --- /dev/null +++ b/lib/travis/api/v3/models/job.rb @@ -0,0 +1,10 @@ +module Travis::API::V3 + class Models::Job < Model + has_one :log, dependent: :destroy + belongs_to :repository + belongs_to :commit + belongs_to :build, autosave: true, foreign_key: 'source_id' + belongs_to :owner, polymorphic: true + serialize :config + end +end diff --git a/lib/travis/api/v3/models/log.rb b/lib/travis/api/v3/models/log.rb new file mode 100644 index 00000000..d1c3219b --- /dev/null +++ b/lib/travis/api/v3/models/log.rb @@ -0,0 +1,7 @@ +module Travis::API::V3 + class Models::Log < Model + belongs_to :job + belongs_to :removed_by, class_name: 'User', foreign_key: :removed_by + has_many :log_parts, dependent: :destroy + end +end diff --git a/lib/travis/api/v3/models/log_part.rb b/lib/travis/api/v3/models/log_part.rb new file mode 100644 index 00000000..43fc7370 --- /dev/null +++ b/lib/travis/api/v3/models/log_part.rb @@ -0,0 +1,5 @@ +module Travis::API::V3 + class Models::LogPart < Model + belongs_to :log + end +end diff --git a/lib/travis/api/v3/models/membership.rb b/lib/travis/api/v3/models/membership.rb new file mode 100644 index 00000000..b32fe2ea --- /dev/null +++ b/lib/travis/api/v3/models/membership.rb @@ -0,0 +1,6 @@ +module Travis::API::V3 + class Models::Membership < Model + belongs_to :user + belongs_to :organization + end +end diff --git a/lib/travis/api/v3/models/organization.rb b/lib/travis/api/v3/models/organization.rb new file mode 100644 index 00000000..e42e3364 --- /dev/null +++ b/lib/travis/api/v3/models/organization.rb @@ -0,0 +1,7 @@ +module Travis::API::V3 + class Models::Organization < Model + has_many :memberships + has_many :users, through: :memberships + has_many :repositories, as: :owner + end +end diff --git a/lib/travis/api/v3/models/permission.rb b/lib/travis/api/v3/models/permission.rb new file mode 100644 index 00000000..7c592903 --- /dev/null +++ b/lib/travis/api/v3/models/permission.rb @@ -0,0 +1,6 @@ +module Travis::API::V3 + class Models::Permission < Model + belongs_to :user + belongs_to :repository + end +end diff --git a/lib/travis/api/v3/models/repository.rb b/lib/travis/api/v3/models/repository.rb new file mode 100644 index 00000000..67aa37e8 --- /dev/null +++ b/lib/travis/api/v3/models/repository.rb @@ -0,0 +1,23 @@ +module Travis::API::V3 + class Models::Repository < Model + has_many :commits, dependent: :delete_all + has_many :requests, dependent: :delete_all + has_many :builds, dependent: :delete_all + has_many :permissions, dependent: :delete_all + has_many :users, through: :permissions + + belongs_to :owner, polymorphic: true + + has_one :last_build, + class_name: 'Travis::API::V3::Models::Build'.freeze, + order: 'id DESC'.freeze + + def slug + @slug ||= "#{owner_name}/#{name}" + end + + def last_build_on(branch) + builds.order('id DESC'.freeze).where(branch: branch, event_type: 'push'.freeze).first + end + end +end diff --git a/lib/travis/api/v3/models/request.rb b/lib/travis/api/v3/models/request.rb new file mode 100644 index 00000000..fd1387a8 --- /dev/null +++ b/lib/travis/api/v3/models/request.rb @@ -0,0 +1,10 @@ +module Travis::API::V3 + class Models::Request < Model + belongs_to :commit + belongs_to :repository + belongs_to :owner, polymorphic: true + has_many :builds + serialize :config + serialize :payload + end +end diff --git a/lib/travis/api/v3/models/ssl_key.rb b/lib/travis/api/v3/models/ssl_key.rb new file mode 100644 index 00000000..eb45758c --- /dev/null +++ b/lib/travis/api/v3/models/ssl_key.rb @@ -0,0 +1,5 @@ +module Travis::API::V3 + class Models::SSLKey < Model + belongs_to :repository + end +end diff --git a/lib/travis/api/v3/models/user.rb b/lib/travis/api/v3/models/user.rb new file mode 100644 index 00000000..73136efd --- /dev/null +++ b/lib/travis/api/v3/models/user.rb @@ -0,0 +1,5 @@ +module Travis::API::V3 + class Models::User < Model + has_many :emails + end +end diff --git a/lib/travis/api/v3/queries/build.rb b/lib/travis/api/v3/queries/build.rb index 7d1594a2..f227761a 100644 --- a/lib/travis/api/v3/queries/build.rb +++ b/lib/travis/api/v3/queries/build.rb @@ -3,7 +3,7 @@ module Travis::API::V3 params :id def find - return ::Build.find_by_id(id) if id + return Models::Build.find_by_id(id) if id raise WrongParams end end diff --git a/lib/travis/api/v3/queries/organization.rb b/lib/travis/api/v3/queries/organization.rb index a88f412c..ae971d7a 100644 --- a/lib/travis/api/v3/queries/organization.rb +++ b/lib/travis/api/v3/queries/organization.rb @@ -3,7 +3,7 @@ module Travis::API::V3 params :id def find - return ::Organization.find_by_id(id) if id + return Models::Organization.find_by_id(id) if id raise WrongParams end end diff --git a/lib/travis/api/v3/queries/organizations.rb b/lib/travis/api/v3/queries/organizations.rb index 42d84d4f..faa3f68b 100644 --- a/lib/travis/api/v3/queries/organizations.rb +++ b/lib/travis/api/v3/queries/organizations.rb @@ -1,7 +1,7 @@ module Travis::API::V3 class Queries::Organizations < Query def for_member(user) - ::Organization.joins(:users).where(users: user_condition(user)) + Models::Organization.joins(:users).where(users: user_condition(user)) end end end diff --git a/lib/travis/api/v3/queries/repositories.rb b/lib/travis/api/v3/queries/repositories.rb index 1f4c0c22..04834ccd 100644 --- a/lib/travis/api/v3/queries/repositories.rb +++ b/lib/travis/api/v3/queries/repositories.rb @@ -8,7 +8,7 @@ module Travis::API::V3 def all @all ||= begin - all = ::Repository + all = Models::Repository all = all.where(active: bool(active)) unless active.nil? all = all.where(private: bool(private)) unless private.nil? all diff --git a/lib/travis/api/v3/queries/repository.rb b/lib/travis/api/v3/queries/repository.rb index fa1e6d35..6542c7b9 100644 --- a/lib/travis/api/v3/queries/repository.rb +++ b/lib/travis/api/v3/queries/repository.rb @@ -3,7 +3,7 @@ module Travis::API::V3 params :id def find - return ::Repository.find_by_id(id) if id + return Models::Repository.find_by_id(id) if id raise WrongParams end end diff --git a/lib/travis/api/v3/renderer/model_renderer.rb b/lib/travis/api/v3/renderer/model_renderer.rb index 0c508172..65de8be1 100644 --- a/lib/travis/api/v3/renderer/model_renderer.rb +++ b/lib/travis/api/v3/renderer/model_renderer.rb @@ -47,17 +47,17 @@ module Travis::API::V3 result end - def render_model(model, type: model.class.name.to_sym, mode: :minimal, **options) + def render_model(model, type: model.class.name[/[^:]+$/].to_sym, mode: :minimal, **options) Renderer[type].render(model, mode, script_name: script_name, **options) end def render_value(value) case value - when Hash then value.map { |k, v| [k, render_value(v)] }.to_h - when Array then value.map { |v | render_value(v) } - when *PRIMITIVE then value - when Time then value.strftime('%Y-%m-%dT%H:%M:%SZ') - when Travis::Model then render_model(value) + when Hash then value.map { |k, v| [k, render_value(v)] }.to_h + when Array then value.map { |v | render_value(v) } + when *PRIMITIVE then value + when Time then value.strftime('%Y-%m-%dT%H:%M:%SZ') + when Model then render_model(value) else raise ArgumentError, 'cannot render %p (%p)' % [value.class, value] end end