Sorbet powered gem distribution [duplicate] - ruby

I have a gem I want to add types to (either by submitting a PR or by forking to use just in my project), but the documentation does not give any more guidance other than to create an /rbi folder.
Thinking out loud, should it mirror the files in lib/ with added type signatures, or should it be one large file (per version?) like the signatures in sorbet-typed?
I don't know of any gems doing this yet, and the documentation doesn't mention it either.

I recently went through this process for one of my gems - pdf-reader. It was my first experience with sorbet (so I'm no expert), and I also noticed the lack of documentation for the specific use case of adding types to a gem.
I ended up generating the initial rbi file using parlour, which put them all into a single file: https://github.com/yob/pdf-reader/blob/480aa240a531cd6f97a46a29279f19025821e886/rbi/pdf-reader.rbi
Sorbet seems happy with that, so I haven't changed it.

Related

What is the directory structure for adding Sorbet RBIs to a gem?

I have a gem I want to add types to (either by submitting a PR or by forking to use just in my project), but the documentation does not give any more guidance other than to create an /rbi folder.
Thinking out loud, should it mirror the files in lib/ with added type signatures, or should it be one large file (per version?) like the signatures in sorbet-typed?
I don't know of any gems doing this yet, and the documentation doesn't mention it either.
I recently went through this process for one of my gems - pdf-reader. It was my first experience with sorbet (so I'm no expert), and I also noticed the lack of documentation for the specific use case of adding types to a gem.
I ended up generating the initial rbi file using parlour, which put them all into a single file: https://github.com/yob/pdf-reader/blob/480aa240a531cd6f97a46a29279f19025821e886/rbi/pdf-reader.rbi
Sorbet seems happy with that, so I haven't changed it.

How to fix: Class PFLogger is implemented in both / Class PFFile is implemented in both

When I run my Workspace on the simulator I get the message
"Class PFFile/ PFLogger is implemented in both (Path) and (Path). One of the two will be used. Which one is undefined."
I don't know how to solve this problem. I already tried cleaning and resetting.
objc[7398]: Class PFFile is implemented in both
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/PhotoFoundation.framework/PhotoFoundation (0x11fdaf1b8)
and
/Users/Sven/Library/Developer/CoreSimulator/Devices/20F88AC5-6C5F-4492-8324-9205B54FB32C/data/Containers/Bundle/Application/8DD1D026-2D96-49E1-A485-6FCBD9899005/FitTip.app/Frameworks/Parse.framework/Parse (0x108c27408).
One of the two will be used. Which one is undefined.
objc[7398]: Class PFLogger is implemented in both
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/PhotoFoundation.framework/PhotoFoundation (0x11fdaff28)
and
/Users/Sven/Library/Developer/CoreSimulator/Devices/20F88AC5-6C5F-4492-8324-9205B54FB32C/data/Containers/Bundle/Application/8DD1D026-2D96-49E1-A485-6FCBD9899005/FitTip.app/Frameworks/Parse.framework/Parse (0x108c279f8).
One of the two will be used. Which one is undefined.
Cause
You're seeing this error because both Parse and PhotoFoundation have files named PFFile and PFLogger. In Objective-C, your program cannot have two classes that share the same class name. This is part of the reason why Apple advocates using a three letter prefix for your own class names. Apple's own frameworks always use two letter prefixes, hence PhotoFoundation related classes have a PF prefix.
Unfortunately in this case, Parse also chose to use the PF prefix across all of the classes in the library that they built. In isolation this won't cause a problem, but when other frameworks come into the picture there's a risk of namespace collisions (which is exactly what's happening here).
Solution
You avoid a namespace collision by simply making sure you don't use the same names. In your case, you don't own either of these classes so it's not as straightforward. Luckily this issue was already reported on the Parse SDK GitHub page and the fix was implemented on the latest version of the Parse SDK (1.17.2). Parse's PFFile and PFLogger were renamed to PFFileObject and PFSystemLogger respectively.
You probably have an older version of the Parse SDK installed in your project. This can be verified by going into the root folder of the project and opening up Podfile.lock in any text editor. You can see what version of the library is currently installed by CocoaPods. Run pod update Parse and CocoaPods should update it to the latest version.
TL;DR pod update Parse. If that fails: pod repo update, pod install
Slightly different problem. Etrecheck pointed out this problem:
Class MDSPathFilter is implemented in both /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Metadata (0x7fff9a7d1420)
and /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Support/mdbulkimport (0x10ad41948)
One of the two will be used. Which one is undefined.
I am not proficient in this stuff, but able to follow directions if anyone has any to share. They both look too important to poke at ...

Chef Shared Ruby Functions or libraries

We have a local Ruby Library that we include in a lot of our ruby projects. It contains a lot of configuration information that would be extremely useful to use in our chef scripts. This allows us to put all of our configuration in one place, so we don't have to make multiple places everytime we change a database etc. Trying to keep the code DRY. That being said, the code are straight ruby functions, not in the chef DSL.
I have been trying to pull the library into Chef, but have found it very difficult. Which makes me think I'm going against some sort of pattern.
I have tried and didn't work.
- Add the Ruby Code via require_relative and includes.
- Add the Ruby Code to it's own cookbook, then wrap the cookbook.
- Create a local ruby gem (not retrievable via rubygems, or other repo)
What worked:
- Copying and pasting the code into a cookbook. (but it's not sharable.)
My real question, what is the best way to share this ruby code library amongst many cookbooks? Depending on the best way, how do you actually do it?, or pointers in the right direction.
thanks.
myles.
I would use Halite (disclaimer: my project) to convert the gem into a cookbook and then upload it as a cookbook. Then you can depend on it and require stuff from it like normal in your Chef code.
You can create a cookbook and copy the ruby code into libraries folder of the cookbook. Then it will be loaded by Chef automatically on node, as soon as you include the cookbook into run list.
Could you tell, what exactly you did, and what didn't work when you tried "Add the Ruby Code to it's own cookbook, then wrap the cookbook"?
I have created a ruby library. Basically, it reads the ip of the server in opsworks. Once it gets that it knows what environment it is in, and it will set a hash. This hash is then used to set the attributes. This way all the server configurations are stored in one place.
I can put the code in each different cookbook that needs it. However, I have to duplicate the code in each different cookbook. I would like to put the code in one place, and include it in each cookbook. That way if I have to modify it, I only have to do it in one place.
I tried making it a gem, and requiring it with no luck.
I also created a cookbook with nothing but the ruby code in a library. I then included "depends etc" that cookbook in another and tried to run the library functions, but I couldn't get it to work.
I may have been on the right track, but I stopped before I got it working.
Essentially I want to write a simple ruby code library, that I can use in any cookbook I want. There must be a way to do this, but I've run into some dead ends. I'll keep banging my head against the wall. Eventually, a hole will open up!

Generate tests skeleton when creating a gem

Is there a tool for creating Ruby gem which automatically generate not only project file structure, but also tests file structure (with default ruby assert tests or rspec)?
You may want to take a look at hoe, which allows you to write your own project templates in erb, amongst other goodies. See http://docs.seattlerb.org/hoe/
Personally I have found, despite looking for something like this initially, that bundle gem <gemname> and a quick reference to an earlier project is not all that much work in practice, considering the number of gems I have written (about 7, though only one is published). Boris Stitnicky's comment rings true for me as well - understanding why a particular structure works, and building it from scratch at least a couple of times is worth the time invested in gaining Ruby knowledge.
However, if my day job project involved creating many in-house gems, I'd probably be using hoe, or a similar tool to get them started consistently.

Customize Gems or merge into main rails project

Currently I am writing a Ruby on Rails application, and I am using Gems, however sometimes I feel that Gems are not as flexible as I want them to be. To make them more flexible. Should I
Fork them on github, and customize it, but this still present the challenging of managing everything.
or
Strip and merge the code of the gem to the main application? This will allow further customization of the gem. This would be for situations where a Gem require another Gem's functionality.
or is there a better way of doing this?
Thanks
B
Choice A is the better answer for a number of reasons.
You get to merge in security updates, enhancements, and bug fixes easily.
Your changes may get merged into the core--in fact, consider if you could implement them in such a way as they live alongside the core functionality as options. If this happens, you have the ultimate win--nothing to maintain, and you can retire your fork.
Others can benefit from your changes.
Your project's footprint is kept smaller and focused by keeping the gem code isolated.
You'll have something to add to your Github "resume."
If its some kind if not so popular gem or "bicycle" from some previous studio or developer who started project(in my case).
I prefer deprecate this gem's and move code into project,
for example they have c***la-deploy - it's just wrapper to Capistrano 2 with own methods))) - I just delete it and rewrite on last Capistrano 3
Than that have own "CMS" c***la-cms where they wrap standard form_for or simple_form with name "twitter_form_for" ? - fist of all I start try to find gem who use this name, and than find in dependency gem's ...
Its take a lot of time for new developer involve in project - better move to standard rails methods/heplers
But anyway i understand for a what this studio do that - its just vendor lock and for client more hard to move out from them to another developers.
For example for startup its bad to use a lot of dependencies and if it's just simple website - dose not matter.

Resources