<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Phil Schalm</title>
    <description>The latest articles on DEV Community by Phil Schalm (@pnomolos).</description>
    <link>https://dev.to/pnomolos</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F180800%2Feb2d34f9-ceea-45d1-ad85-0cf3d28e39a9.jpeg</url>
      <title>DEV Community: Phil Schalm</title>
      <link>https://dev.to/pnomolos</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pnomolos"/>
    <language>en</language>
    <item>
      <title>ActiveMerchant and PayPal Express Checkout</title>
      <dc:creator>Phil Schalm</dc:creator>
      <pubDate>Tue, 18 Feb 2020 05:02:32 +0000</pubDate>
      <link>https://dev.to/pnomolos/activemerchant-and-paypal-express-checkout-1304</link>
      <guid>https://dev.to/pnomolos/activemerchant-and-paypal-express-checkout-1304</guid>
      <description>&lt;p&gt;So that I don't forget how to do this in the future (I spent 3+ hours today smashing my head into my desk because good documentation on this is &lt;em&gt;hard&lt;/em&gt; to find).&lt;/p&gt;

&lt;p&gt;PayPal Express is a multi-step process.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Craft an initial request to PayPal, indicating that you wish to send a customer to them to purchase an item.  It includes various fields such as a list of items, order total, taxes, currency, return URLs, etc.  PayPal will respond with a token that you need to use in future requests.&lt;/li&gt;
&lt;li&gt;Send the user to PayPal along with the process token from the prior request.&lt;/li&gt;
&lt;li&gt;The user completes their purchase and are redirected back to your site (along with the process token).&lt;/li&gt;
&lt;li&gt;Look up the details for the token (another PayPal request) and verify that the PayPal process happened successfully.&lt;/li&gt;
&lt;li&gt;Run the actual purchase request to PayPal, again verifying that it succeeded.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In terms of Rails and ActiveMerchant, this would look something like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;checkout&lt;/span&gt;
  &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;valid?&lt;/span&gt;
    &lt;span class="c1"&gt;# Here's step 1&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;paypal_gateway&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setup_purchase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="vi"&gt;@order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;total_in_cents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;order_paypal_params&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@order&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="ss"&gt;return_url: &lt;/span&gt;&lt;span class="n"&gt;order_receipt_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Remember to use _url here and not _path (must be absolute)&lt;/span&gt;
        &lt;span class="ss"&gt;cancel_return_url: &lt;/span&gt;&lt;span class="n"&gt;order_cancel_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success?&lt;/span&gt;
      &lt;span class="vi"&gt;@order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="ss"&gt;paypal_correlation_id: &lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"CorrelationID"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="ss"&gt;paypal_token: &lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;token&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="c1"&gt;# Here's step 2&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="n"&gt;paypal_gateway&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;redirect_url_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;receipt&lt;/span&gt;
  &lt;span class="c1"&gt;# Here we're returning from step 3&lt;/span&gt;
  &lt;span class="vi"&gt;@order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;paypal_token: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:token&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

  &lt;span class="kp"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:failure&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;payment_processed&lt;/span&gt;
      &lt;span class="vi"&gt;@error_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"This order has already been paid for, no further action is necessary"&lt;/span&gt;
      &lt;span class="kp"&gt;throw&lt;/span&gt; &lt;span class="ss"&gt;:failure&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Here's step 4&lt;/span&gt;
    &lt;span class="n"&gt;purchase_details&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;paypal_gateway&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;details_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:token&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;purchase_details&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success?&lt;/span&gt;
      &lt;span class="vi"&gt;@error_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;purchase_details&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;
      &lt;span class="kp"&gt;throw&lt;/span&gt; &lt;span class="ss"&gt;:failure&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Finally, step 5&lt;/span&gt;
    &lt;span class="n"&gt;purchase_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;paypal_gateway&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;purchase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="vi"&gt;@order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;total_in_cents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;order_paypal_params&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@order&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="ss"&gt;token: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:token&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="ss"&gt;payer_id: &lt;/span&gt;&lt;span class="n"&gt;purchase_details&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;payer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;purchase_response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success?&lt;/span&gt;
      &lt;span class="vi"&gt;@error_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;purchase_details&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;
      &lt;span class="kp"&gt;throw&lt;/span&gt; &lt;span class="ss"&gt;:failure&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="vi"&gt;@order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="ss"&gt;payment_processed: &lt;/span&gt;&lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;amount_paid: &lt;/span&gt;&lt;span class="vi"&gt;@pack_order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="kp"&gt;private&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;order_paypal_params&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;items: &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;
      &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"An Awesome Shirt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;quantity: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;amount: &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;total_in_cents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;description: &lt;/span&gt;&lt;span class="s2"&gt;"This is the coolest shirt ever, woo!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="ss"&gt;ip: &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remote_ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;allow_guest_checkout: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;currency: &lt;/span&gt;&lt;span class="s2"&gt;"CAD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;invoice_id: &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# To make correlating easier later, if debugging&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;paypal_gateway&lt;/span&gt;
  &lt;span class="vi"&gt;@paypal_gateway&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="no"&gt;ActiveMerchant&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Billing&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PaypalExpressGateway&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="ss"&gt;login: &lt;/span&gt;&lt;span class="no"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;paypal_username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;password: &lt;/span&gt;&lt;span class="no"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;paypal_password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;signature: &lt;/span&gt;&lt;span class="no"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;paypal_signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Some things to note:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;All monetary values passed to PayPal are in cents (for USD and CAD.  I'm unsure of cases in currencies where the common monetary unit is non-decimal).&lt;/li&gt;
&lt;li&gt;The total that is passed in as the first parameter to both &lt;code&gt;setup_purchase&lt;/code&gt; and &lt;code&gt;purchase&lt;/code&gt; needs to match the array of items, plus taxes, shipping, etc.  If it doesn't match up perfectly you're in for a lot of headache.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;response&lt;/code&gt; object that you get back from ActiveMerchant - to be exact, an instance of &lt;code&gt;ActiveMerchant::Billing::PaypalExpressResponse&lt;/code&gt; - has a &lt;code&gt;error_code&lt;/code&gt; field that (at the time of writing) appears to &lt;strong&gt;always&lt;/strong&gt; filled out, even if you have a successful request.  You're going to want to check &lt;code&gt;response.success?&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Especially as you initially put something like this into production, make sure to &lt;em&gt;log, log, log&lt;/em&gt;.  Don't log anything sensitive, but having lots of information, such as a full trace of the PayPal requests, can be very helpful if you're trying to figure out why a certain purchase isn't going through.&lt;/li&gt;
&lt;li&gt;This is condensed into a single post as much as possible so &lt;strong&gt;I&lt;/strong&gt; don't forget this if I ever need it in the future.  Don't need to waste 3 hours again :)&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>rails</category>
      <category>activemerchat</category>
      <category>ruby</category>
      <category>paypal</category>
    </item>
    <item>
      <title>Advanced Bundler</title>
      <dc:creator>Phil Schalm</dc:creator>
      <pubDate>Fri, 14 Jun 2019 18:56:15 +0000</pubDate>
      <link>https://dev.to/pnomolos/advanced-bundler-4fbe</link>
      <guid>https://dev.to/pnomolos/advanced-bundler-4fbe</guid>
      <description>&lt;p&gt;The following will be a (hopefully often) updated article with tricks to help utilize Bundler to its fullest.&lt;/p&gt;

&lt;h3&gt;
  
  
  DRY multi-platform gemspecs (2019-06-14)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Note the &lt;code&gt;.dup&lt;/code&gt; call after loading the common specification.  This is important as Bundler actually loads all (&lt;code&gt;*.gemspec&lt;/code&gt;) files and Rubygems caches the results of &lt;code&gt;eval&lt;/code&gt;ing a &lt;code&gt;Gem::Specification.load&lt;/code&gt; call.  Without the &lt;code&gt;.dup&lt;/code&gt; this means you'll end up modifying the same spec instance for every custom gemspec you want to have.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  gemname.gemspec.common
&lt;/h5&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Gem&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Specification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;gem&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authors&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Phil Schalm"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"notmyrealemail@nowhere.com"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Sample"&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;summary&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Longer sample"&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;files&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;%w[gemname.gemspec gemname-java.gemspec gemname.gemspec.common Gemfile]&lt;/span&gt;

  &lt;span class="c1"&gt;# Common dependencies here&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h5&gt;
  
  
  gemname.gemspec
&lt;/h5&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Gem&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Specification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expand_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"gemname.gemspec.common"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;__dir__&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;dup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tap&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;gem&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance_exec&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"gemname"&lt;/span&gt;
    &lt;span class="c1"&gt;# 'Everything else' specific dependencies here&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h5&gt;
  
  
  gemname-java.gemspec
&lt;/h5&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Gem&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Specification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expand_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"gemname.gemspec.common"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;__dir__&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;dup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tap&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;gem&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance_exec&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"gemname-java"&lt;/span&gt;
    &lt;span class="c1"&gt;# Java specific dependencies here&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h5&gt;
  
  
  Gemfile
&lt;/h5&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="s1"&gt;'https://rubygems.org'&lt;/span&gt;

&lt;span class="n"&gt;gemspec&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="no"&gt;RUBY_PLATFORM&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"java"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;"gemname-java"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"gemname"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>ruby</category>
      <category>bundler</category>
      <category>jruby</category>
    </item>
  </channel>
</rss>
