profile
viewpoint
Ufuk Kayserilioglu paracycle @Shopify Kyrenia, Cyprus

chanzuckerberg/sorbet-rails 522

A set of tools to make the Sorbet typechecker work with Ruby on Rails seamlessly.

bgarret/google-analytics-rails 318

Rails 3 helpers to manage google analytics tracking. Mostly intended for small to medium websites.

AaronC81/pry-sorbet 10

Pry extension for Sorbet

paracycle/BsonME 9

A J2ME implementation for BSON

paracycle/authentic 8

A Google Authenticator replacement for OS X CLI

paracycle/dotfiles 2

.files, including ~/.osx — sensible hacker defaults for OS X

atesgoral/doorbell-ringer 1

Rings a doorbell

atesgoral/node-commander 1

An X Commander running on Node

paracycle/backup 1

Provides an elegant DSL in Ruby for performing backups on UNIX-like systems.

push eventShopify/tapioca

Ufuk Kayserilioglu

commit sha b7fd3a605bf9b280b39687dfa6c5400b59015724

Add failing test for namespaced models with associations to each other

view details

Ufuk Kayserilioglu

commit sha 883a69fe07319aa86f4e0ee3fa812264343ddfa1

Fix reflection target class existence validation We were wrongly assuming that constantizing the class name of the reflection would be enough to find the target constant of the reflection. However, it turns out that what AR does is to call `compute_type` on the original model class, which ends up discovering the reflection target class by walking out of the namespaces of the original model. We were not matching that behaviour in our check and thus generating the wrong RBI file as reported in #603. Since the code to discover the correct class for the given reflection target is too complex to replicate in our codebase, I decided to catch the failure of calling `reflection.klass` and reporting a `NameError` raised by that call to mean that the target constant doesn't exist. In order to do this properly, I had to refactor the model validation code to its own method and group all the checks in there.

view details

Ufuk Kayserilioglu

commit sha 3276a472a6731526397057deac7f46baf19bf7cc

Merge pull request #634 from Shopify/uk-fix-ar-assoc-target-checks

view details

push time in 7 hours

delete branch Shopify/tapioca

delete branch : uk-fix-ar-assoc-target-checks

delete time in 7 hours

PR merged Shopify/tapioca

Fix reflection target class existence check

Motivation

<!-- Explain why you are making this change. Include links to issues or describe the problem being solved, not the solution. --> Fixes #603

We were wrongly assuming that constantizing the class name of the reflection would be enough to find the target constant of the reflection. However, it turns out that what AR does is to call compute_type on the original model class, which ends up discovering the reflection target class by walking out of the namespaces of the original model.

We were not matching that behaviour in our check and thus generating the wrong RBI file as reported in #603.

Implementation

<!-- How did you implement your changes? Explain your solution, design decisions, things reviewers should watch out for. -->

Since the code to discover the correct class for the given reflection target is too complex to replicate in our codebase, I decided to catch the failure of calling reflection.klass and reporting a NameError raised by that call to mean that the target constant doesn't exist.

In order to do this properly, I had to refactor the model validation code to its own method and group all the checks in there.

Tests

<!-- We hope you added tests as part of your changes, just state that you have. If you haven't, state why. -->

Added an expanded version of the reproduction case reported in #603 as a test case.

+146 -7

0 comment

2 changed files

paracycle

pr closed time in 7 hours

issue closedShopify/tapioca

`ActiveRecordAssociations#type_for` incorrectly filters relations on classes with nested namespaces

Hello! I believe #584 introduced a regression that is causing some relations to be filtered out of generated RBI. ActiveRecord::Reflection#class_name returns a class that doesn't include a full namespace prefix, which in turn causes safe_constantize to fail for classes that are inside a namespace, like this:

module Blog
  class Post < ActiveRecord::Base
    belongs_to :author
  end

  class Author < ActiveRecord::Base
  end
end

In the above example, when inspecting the :author relation, class_name will return Author (not Blog::Author) and safe_constantize won't be able to find that constant. As a result, no author method will show up in the generated RBI for Post. I should caveat that my application isn't using rails (just ActiveRecord) and so it's possible that this would work in a different environment. But regardless, I think the fix is to use klass.name instead of class_name in ActiveRecordAssociations#type_for:

class_name = if reflection.through_reflection?
  reflection.send(:delegate_reflection).klass.name
else
  reflection.klass.name
end

Thanks for your help!

closed time in 7 hours

jflinter

issue commentShopify/tapioca

Support `ActionDispatch::SystemTestCase` within UrlHelpers compiler

We already do this for ActionDispatch::IntegrationTest, I see no reason to not do it for ActionDispatch::SystemTestCase as well.

KaanOzkan

comment created time in 7 hours

push eventShopify/tapioca

Ufuk Kayserilioglu

commit sha 883a69fe07319aa86f4e0ee3fa812264343ddfa1

Fix reflection target class existence validation We were wrongly assuming that constantizing the class name of the reflection would be enough to find the target constant of the reflection. However, it turns out that what AR does is to call `compute_type` on the original model class, which ends up discovering the reflection target class by walking out of the namespaces of the original model. We were not matching that behaviour in our check and thus generating the wrong RBI file as reported in #603. Since the code to discover the correct class for the given reflection target is too complex to replicate in our codebase, I decided to catch the failure of calling `reflection.klass` and reporting a `NameError` raised by that call to mean that the target constant doesn't exist. In order to do this properly, I had to refactor the model validation code to its own method and group all the checks in there.

view details

push time in 7 hours

push eventShopify/tapioca

Étienne Barrié

commit sha 68d8bbb71ec9161dc837775c24b1cbe6a2a1e689

Compare modules by identity for Tapioca::Compilers::Dsl::Base#processable_constants This prevents exceptions from badly-behaved modules that implement eql? in a manner incompatible with Object#eql?. bad_module = Object.new def bad_module.eql?() end # incompatible with Object#eql? hash_conflict = Object.new hash_conflict.define_singleton_method(:hash) { bad_module.hash } require "set" set = Set.new set << hash_conflict set.include?(bad_module) rescue p $! set.compare_by_identity p set.include?(bad_module) There's nothing specific about modules, but since Module doesn't implement eql? for its instances, we can assume it's equivalent to comparing by identity.

view details

Étienne Barrié

commit sha 63bd6b650e5c881f9e08eb08549608c8cf45b4fd

Add shim for Set#compare_by_identity

view details

Ufuk Kayserilioglu

commit sha b0d50be1b7ba5112fbc2ea8a747e785505636727

Merge pull request #627 from Shopify/remove-flakiness Compare modules by identity for Tapioca::Compilers::Dsl::Base#processable_constants

view details

push time in 13 hours

delete branch Shopify/tapioca

delete branch : remove-flakiness

delete time in 13 hours

PR merged Shopify/tapioca

Compare modules by identity for Tapioca::Compilers::Dsl::Base#processable_constants

This prevents exceptions from badly-behaved modules that implement eql? in a manner incompatible with Object#eql?.

bad_module = Object.new
def bad_module.eql?() end # incompatible with Object#eql?

hash_conflict = Object.new
hash_conflict.define_singleton_method(:hash) { bad_module.hash }

require "set"
set = Set.new
set << hash_conflict
set.include?(bad_module) rescue p $!
set.compare_by_identity
p set.include?(bad_module)

There's nothing specific about modules, but since Module doesn't implement eql? for its instances, we can assume it's equivalent to comparing by identity.

Motivation

We have a bin/tapioca dsl --verify in our CI and it randomly fails. I tracked it down to a misbehaved Dry::Logic::Predicates implementing eql? (at the singleton level) in a manner incompatible with Object#eql?, see https://github.com/dry-rb/dry-logic/issues/73#issuecomment-971595351.

While ultimately the fix should be in there, I felt like this was acceptable given we know we're dealing with modules which don't define eql? and hash, hence we know our set can use comparison by identity.

Implementation

Use Set#compare_by_identity on the set of processable_constants. Define the shim because it's missing from Sorbet.

Tests

I didn't see any tests specifically for Tapioca::Compilers::Dsl::Base#processable_constants or Tapioca::Compilers::Dsl::Base#handles? so I left it out.

+6 -0

0 comment

2 changed files

etiennebarrie

pr closed time in 13 hours

PullRequestReviewEvent

push eventShopify/tapioca

Ufuk Kayserilioglu

commit sha 6613171fcc23ba9eaa6ce7be1b90bc9ed7da272b

Fix reflection target class existence validation We were wrongly assuming that contantizing the class name of the reflection would be enough to find the target constant of the reflection. However, it turns out that what AR does is to call `compute_type` on the original model class, which ends up discovering the reflection target class by walking out of the namespaces of the original model. We were not matching that behaviour in our check and thus generating the wrong RBI file as reported in #603. Since the code to discover the correct class for the given reflection target is too complex to replicate in our codebase, I decided to catch the failure of calling `reflection.klass` and reporting a `NameError` raised by that call to mean that the target constant doesn't exist. In order to do this properly, I had to refactor the model validation code to its own method and group all the checks in there.

view details

push time in 3 days

PR opened Shopify/tapioca

Fix reflection target class existence check

Motivation

<!-- Explain why you are making this change. Include links to issues or describe the problem being solved, not the solution. --> Fixes #603

We were wrongly assuming that contantizing the class name of the reflection would be enough to find the target constant of the reflection. However, it turns out that what AR does is to call compute_type on the original model class, which ends up discovering the reflection target class by walking out of the namespaces of the original model.

We were not matching that behaviour in our check and thus generating the wrong RBI file as reported in #603.

Implementation

<!-- How did you implement your changes? Explain your solution, design decisions, things reviewers should watch out for. -->

Since the code to discover the correct class for the given reflection target is too complex to replicate in our codebase, I decided to catch the failure of calling reflection.klass and reporting a NameError raised by that call to mean that the target constant doesn't exist.

In order to do this properly, I had to refactor the model validation code to its own method and group all the checks in there.

Tests

<!-- We hope you added tests as part of your changes, just state that you have. If you haven't, state why. -->

Added an expanded version of the reproduction case reported in #603 as a test case.

+142 -7

0 comment

2 changed files

pr created time in 3 days

push eventShopify/tapioca

Ufuk Kayserilioglu

commit sha 39568943d9454efcf7ace01b754d331abdd2c9bc

Merge pull request #633 from Shopify/uk-pessimitic-version-dep-on-own-gems

view details

push time in 3 days

create barnchShopify/tapioca

branch : uk-fix-ar-assoc-target-checks

created branch time in 3 days

issue commentShopify/tapioca

`ActiveRecordAssociations#type_for` incorrectly filters relations on classes with nested namespaces

Hey @jflinter, thanks for testing the latest changes and thanks for the very clear reproduction. Indeed the changes on main were falling short of namespaces, and that seems to be due to me misreading the behaviour of Active Record.

However, using reflection.klass is not the fix, since, if the reflection target class does not exist, then reflection.klass is the thing that throws an exception in the first place. The whole code change was to prevent that exception by detecting that situation earlier.

I have a fix for this that seems to work with your test case. I will be doing a couple of more checks on it and create a PR.

jflinter

comment created time in 3 days

PullRequestReviewEvent
PullRequestReviewEvent

release Shopify/tapioca

v0.5.5

released time in 4 days

push eventShopify/tapioca

Ufuk Kayserilioglu

commit sha b3e5e93ec134c1ee70f8cf8d4d12b459bc77770e

Bump version to v0.5.5

view details

push time in 4 days

PullRequestReviewEvent

push eventShopify/tapioca

Ufuk Kayserilioglu

commit sha 1de544d0dd88af9f7b1a491adbb2c9bbdf6741f1

Add pessimistic version dependencies on our gems Given that we are likely to break API compatibility often in RBI or Spoom, we need a way for Tapioca to not allow people to install incompatible versions of those gems. For that reason, we should add pessimistic version dependencies on those gems (as described here: https://guides.rubygems.org/patterns/#pessimistic-version-constraint), so that RBI and Spoom can bump the minor version when they make an incompatible release and Tapioca will not automatically allow end users to install those versions.

view details

Ufuk Kayserilioglu

commit sha 6c59daf4e7ed66435a242adfe14730a4c9b531dd

Merge pull request #633 from Shopify/uk-pessimitic-version-dep-on-own-gems

view details

push time in 4 days

delete branch Shopify/tapioca

delete branch : uk-pessimitic-version-dep-on-own-gems

delete time in 4 days

PR merged Shopify/tapioca

Add pessimistic version dependencies on our gems

Motivation

<!-- Explain why you are making this change. Include links to issues or describe the problem being solved, not the solution. --> Given that we are likely to break API compatibility often in RBI or Spoom, we need a way for Tapioca to not allow people to install incompatible versions of those gems. For that reason, we should add pessimistic version dependencies on those gems (as described here: https://guides.rubygems.org/patterns/#pessimistic-version-constraint), so that RBI and Spoom can bump the minor version when they make an incompatible release and Tapioca will not automatically allow end users to install those versions.

Note: This is PR against the 0-5-stable branch for now. I will cherry-pick this on main afterwards.

+4 -4

0 comment

2 changed files

paracycle

pr closed time in 4 days

PR opened Shopify/tapioca

Add pessimistic version dependencies on our gems

Motivation

<!-- Explain why you are making this change. Include links to issues or describe the problem being solved, not the solution. --> Given that we are likely to break API compatibility often in RBI or Spoom, we need a way for Tapioca to not allow people to install incompatible versions of those gems. For that reason, we should add pessimistic version dependencies on those gems (as described here: https://guides.rubygems.org/patterns/#pessimistic-version-constraint), so that RBI and Spoom can bump the minor version when they make an incompatible release and Tapioca will not automatically allow end users to install those versions.

Note: This is PR against the 0-5-stable branch for now. I will cherry-pick this on main afterwards.

+4 -4

0 comment

2 changed files

pr created time in 4 days

push eventShopify/tapioca

Alexandre Terrasa

commit sha a7e658d72c2293fe9c5337c27741eb917bfe054c

Merge pull request #630 from Shopify/at-bump-rbi Bump `rbi` to v0.0.8

view details

push time in 4 days

create barnchShopify/tapioca

branch : uk-pessimitic-version-dep-on-own-gems

created branch time in 4 days

push eventShopify/tapioca

Ufuk Kayserilioglu

commit sha d6f9fa329b7b0299383a6e7000233975c44e98a3

Add ActiveRecord relations generator

view details

Ufuk Kayserilioglu

commit sha dda5731e613344cb487fac963642a5eeaf038502

Handle include? finder method

view details

Ufuk Kayserilioglu

commit sha abb6c2e1c41a776ad5a5e74357ceda14a830303e

The column_name parameter of the count calculation method is optional

view details

Ufuk Kayserilioglu

commit sha 4312eaba2b425bf82f8c8c418fb6c00207fc1ee2

Fix new, build, create and create! signatures

view details

Ufuk Kayserilioglu

commit sha a244b71117ce1884a601ac31faf5748f1b367e38

Drop `first_or_xxx` methods These methods are not in the AR public API anymore and should not be used, so dropping support for them. Ref: https://rubyinrails.com/2020/05/26/rails-first-or-create-vs-find-or-create-by/

view details

Ufuk Kayserilioglu

commit sha ded66605b12d65245799a938db1d5e5cfd99248e

Fix some method names

view details

Ufuk Kayserilioglu

commit sha 2d39a9d9ed9acae20ff3744d012bcbc1dfd9fa83

The first argument of `sum` is nilable

view details

Ufuk Kayserilioglu

commit sha f043839a594a68c704dace9a413ff94a3d741e5a

Parametrize the return value of `sum`

view details

Ufuk Kayserilioglu

commit sha 548a8da55df0ed4efd474696cb6e1855ab8363f5

`new` and `build` also accept arrays

view details

Ufuk Kayserilioglu

commit sha 2f3d0a62a2473602522a11c639928f6ef2d8ae30

Include relation modules from parent models We should be including the relation modules from parent model classes as long as the parent model is not an abstract class or it is not `ActiveRecord::Base`.

view details

Ufuk Kayserilioglu

commit sha 1f3fe29203432ca192a768ca0b7b5a4d059c08bd

Templatizing `sum` doesn't work if no block is given We have to fallback to `T.untyped` for `sum` return value.

view details

Ufuk Kayserilioglu

commit sha 53355107e3b7ecfc1c690c8d2359ea17b7718a8c

Generate scope methods from parent models Including relation methods modules from parent models does not work properly since the method return type of the included scope methods are still of the parent relation types. A better solution is to collect all the scope methods from all the parent models of the current model until we hit AR::Base or an abstract model.

view details

Ufuk Kayserilioglu

commit sha 0f1316225688e8aa8f11b493fc239ffbc9941883

Refactor generated relation modules Extract common methods that don't depend on the difference between the association or simple relation modules into a common methods module.

view details

Ufuk Kayserilioglu

commit sha 625da41e3614c16561222a743abc0476c09c4d38

Start generating methods specific to each relation class

view details

Ufuk Kayserilioglu

commit sha a0140428eea67a34447e17e2e67ff74b286c1ff8

Name refactoring

view details

Ufuk Kayserilioglu

commit sha cc646ab07c179dc2355895453a1d3e61a74f686c

Generate scope method from abstract parent models as well

view details

Ufuk Kayserilioglu

commit sha 545f13e98666e46cfaef45d05ba9d55e57940815

Make calculation methods untyped

view details

Ufuk Kayserilioglu

commit sha eefd76ccf54b0eb1a8caf01ac7c9d44e7400abd0

Fix code comment

view details

Ufuk Kayserilioglu

commit sha 3c2b6630ac90de1537f0fad997e9c0b0bbeb00c0

Add to_ary methods on relation classes to make flatten work

view details

Ufuk Kayserilioglu

commit sha 5f276498519824f7a52ecf5cc91d40fd537c5750

Make some method name renames

view details

push time in 4 days

issue closedShopify/tapioca

ActionCable support

I noticed that ActionCable is not a valid DSL.

How can I generate an RBI file from this definition?

# typed: true
class ExampleChannel < ApplicationCable::Channel
  def subscribed
    stream_from 'visitors'
  end
end

Right now I had to manually create:

# typed: true

module ApplicationCable
  class Channel
    def stream_from(arg0); end
  end
end

Is there a better way?

closed time in 4 days

Overload119

issue commentShopify/tapioca

ActionCable support

This is not a DSL generation problem since the stream_from method should be defined inside ActionCable::Channel::Streams: http://api.rubyonrails.org/classes/ActionCable/Channel/Streams.html#method-i-stream_from

Since that method is not a dynamically defined method, there should be no need for a DSL generator. The gem RBI for the actioncable gem should have that method definition. If it doesn't, then you might be missing an explicit require in the tapioca/require.rb file.

Overload119

comment created time in 4 days

PullRequestReviewEvent
more