Skip to content

add ruby sdk#9026

Closed
eunomie wants to merge 4 commits into
dagger:mainfrom
eunomie:sdk-ruby
Closed

add ruby sdk#9026
eunomie wants to merge 4 commits into
dagger:mainfrom
eunomie:sdk-ruby

Conversation

@eunomie
Copy link
Copy Markdown
Member

@eunomie eunomie commented Nov 21, 2024

Start implementing a ruby sdk.

Warning

This is work in progress

Ruby SDK

A generated ruby client can be found in /sdk/ruby. The code generation is working, and a Go runtime is provided.

To generate a new module using ruby:

$ dagger init --sdk=ruby testruby
$ cd testruby
$ dagger run -q ruby main.rb hello-world Dagger
hello Dagger

ToDo:

  • complete .dagger/sdk_ruby to be able to test/publish/bump (see next about Gem)
  • moar tests
  • telemetry

The ruby code generation is quite basic:

  • no library is used for GraphQL client, it's a plain old HTTP client.
  • required and optional parameters are handled the same way:
    In Go we would have something like
    dag.
        Container().
        WithDirectory("/src", source, dagger.ContainerWithDirectoryOpts{
            Include: []string{"..."},
        })
    In ruby we have currently
    @dag
      .container
      .with_directory(path: "/src", directory: source, include: ['...'])
    That means all parameters are named, and all optional ones default to nil.
    It could have been a solution to create specific optional types, but that would have been a bit heavier.

A default ruby file could be:

require 'bundler/setup'

require 'dagger'
require_relative './dagger'

class Rubytest
  def hello_world(str)
    @dag
      .container
      .from(address: "alpine:latest")
      .with_exec(args: ["echo", "hello #{str}"])
      .stdout
    end
end

Ruby Gem

Gem is called 'dagger-sdk' because 'dagger' and 'ruby-dagger' already exist.

To test:

  • generate ruby code:
    dagger -m .dagger call sdk ruby generate -o .
    
  • build the gem:
    cd sdk/ruby
    gem build dagger.gemspec
    
  • install it locally:
    gem install dagger-sdk-0.0.0.gem
    

This will allow to have a local version of the gem, without the need to
deploy it. Once done, you can follow all the steps detailed in the sdk/ruby/README.md

ToDo:

  • allow to publish the Gem

Ruby Module

Warning

WIP

A module is in creation to be able to call it using dagger call for instance. See the third commit.
For now it's not working.

main.rb might probably be completely replaced by the entrypoint.rb. That way the user code is limited to what the user really needs and not the boilerplate, like for Go modules for instance.

@eunomie eunomie force-pushed the sdk-ruby branch 4 times, most recently from 77726e4 to 2b6db41 Compare November 21, 2024 17:02
Start implementing a ruby sdk.

This is work in progress, it's not yet finished.

A generated ruby client can be found in /sdk/ruby
The code generation is working, and a Go runtime is provided.

To generate a new module using ruby:

    $ dagger init --sdk=ruby testruby
    $ cd testruby
    $ dagger run -q ruby main.rb hello-world Dagger
    hello Dagger

ToDo:
- provide a real runtime so that dagger call is handled
- complete .dagger/sdk_ruby to be able to test/publish/bump
- moar tests

The ruby code generation is quite basic:
- no library is used for GraphQL client, it's a plain old HTTP client.
- required and optional parameters are handled the same way:
  In Go we would have something like
    dag.
      Container().
      WithDirectory("/src", source, dagger.ContainerWithDirectoryOpts{
        Include: []string{"..."},
      })
  In ruby we have currently
    @dag
      .container
      .with_directory(path: "/src", directory: source, include: ['...'])
  That means all parameters are named, and all optional ones default to nil.

  It could have been a solution to create specific optional types, but that
  would have been a bit heavier.

A default ruby file could be:

require 'bundler/setup'

require 'dagger'
require_relative './dagger'

class Rubytest
  def hello_world(str)
    @dag
      .container
      .from(address: "alpine:latest")
      .with_exec(args: ["echo", "hello #{str}"])
      .stdout
  end
end

Signed-off-by: Yves Brissaud <yves.brissaud@gmail.com>
allow to create a real gem so that it can be used with a dagger run

Gem is called 'dagger-sdk' because 'dagger' and 'ruby-dagger' already
exist.

To test:

- generate ruby code:
  - dagger -m .dagger call sdk ruby generate -o .
- build the gem:
  - cd sdk/ruby; gem build dagger.gemspec
- install it locally:
  - gem install dagger-sdk-0.0.0.gem

This will allow to have a local version of the gem, without the need to
deploy it.
Once done, you can follow all the steps detailed in the sdk/ruby/README.md

Signed-off-by: Yves Brissaud <yves.brissaud@gmail.com>
@levlaz
Copy link
Copy Markdown
Contributor

levlaz commented Nov 21, 2024

For modules, in order to get this to work nicely with the other SDKs I think we're going to need to enforce typing in Ruby. @jpadams and I went to a ruby meetup a few months ago in SF where we discussed looking into something like Sorbet for this. I am curious if you have any opinions.

https://sorbet.org/

@eunomie
Copy link
Copy Markdown
Member Author

eunomie commented Nov 21, 2024

I haven't tried yet Sorbet, that looks interesting.
But I've used in the past a lot (several years) contracts.ruby (https://github.com/egonSchiele/contracts.ruby) in the past. It's more than types, but that was really nice to use.

For now I'm just using the comments that at least allows my IDE (rubymine) to check types. It's just at IDE level but that's a start.

With proper types it means we can also define the *Opts equivalents, that could be interesting.

I'll give a try to Sorbet and see if that's good.

Comment thread .dagger/sdk_ruby.go Outdated
// +optional
dryRun bool,
// +optional
npmToken *dagger.Secret,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not related to Ruby?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not yet, the TestPublish, Publish and Bump have not been implemented for ruby.
So it's just copy/paste from typescript code.
I'll work on those once the rest has been improved.

@eunomie
Copy link
Copy Markdown
Member Author

eunomie commented Nov 22, 2024

@levlaz It's not finished, but I added a new commit with a first pass using Sorbet.
I think that could be a good solution.
Still some work needed to cover everything.

@eunomie eunomie force-pushed the sdk-ruby branch 2 times, most recently from c6b11ab to 91de7ba Compare November 26, 2024 16:20
@eunomie
Copy link
Copy Markdown
Member Author

eunomie commented Nov 26, 2024

Generated code is now fully typed using Sorbet.
It also deals with order of declaration (basically pre-declaration of some types) so everything is working as expected.

I also moved, like for other SDKs, the optional parameters under a opts field. That way the *Opts objects are also typed.

There's still some improvements to make, and the linter is not yet enabled (I mean sorbet as a linter) but I'll work on that.

And still the module part that needs to be completed.

Signed-off-by: Yves Brissaud <yves.brissaud@gmail.com>
Type all the Gem/SDK ruby code using https://sorbet.org/

Signed-off-by: Yves Brissaud <yves.brissaud@gmail.com>
@github-actions
Copy link
Copy Markdown
Contributor

This PR is stale because it has been open 14 days with no activity. Remove stale label or comment or this will be closed in 7 days.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jan 8, 2025

This PR was closed because it has been stalled for 7 days with no activity.

@github-actions github-actions Bot closed this Jan 8, 2025
@eunomie eunomie mentioned this pull request Apr 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants