Skip to content

Instantly share code, notes, and snippets.

@kelvinst
Last active July 19, 2024 14:20
Show Gist options
  • Save kelvinst/d63d1bfb93d367089217 to your computer and use it in GitHub Desktop.
Save kelvinst/d63d1bfb93d367089217 to your computer and use it in GitHub Desktop.
Como criar uma gem ruby?

Como criar uma gem ruby?

Escolhi tratar sobre esse assunto hoje simplesmente porque foi uma das primeiras coisas que me perguntei "como eu faço isso?" no mundo ruby. Acredito que muita gente se pergunte a mesma coisa e espero que eu possa ajudar em algo para elas. 😀

O que é uma gem?

Bem, se você é um programador java, você chama sua gem de jar, se você é um programador C#, você chama de dll. Resumindo, é uma lib, uma biblioteca contendo códigos que você pode reaproveitar importando em outros projetos.

E usar gems no ruby é muito fácil, se você já deu uma brincada com rails por exemplo, é só você adicionar o código gem 'nome_da_gem' no arquivo Gemfile que está no root, depois executar o comando bundle install para baixar sua gem do repositório e pronto, só sair usando a biblioteca!

Para mais detalhes do que é e como funciona uma gem, veja os guias no site do rubygems, que é o repositório global de gems ruby! Aliás, nesses guides você encontra tudo o que vou falar, mas vou tentar falar de uma maneira mais resumida pra você mandar ver bem rápido!

Como criar uma gem?

Então, vou seguir uma linha de tutorial relâmpago para você criar uma gem, pulando vários steps que seriam interssantes, como testes com rspec ou coisas assim, mas vou deixar isso para um próximo post.

Mas primeiro vamos aos pré-requisitos né. Para esse "tutorial" você deve ter ao menos uma instalação básica do ruby, que consiste do ruby em si, do RubyGems e do Bundler. Todos estes vem instalados normalmente com os pacotes que você baixa por aí do ruby.

Tendo isto instalado, aqui vamos nós:

1. Criar diretório da gem

O primeiro passo claro é criar o diretório do projeto. Para isso o Bundler tem um helper que ajuda muito a seguir as boas práticas que são citadas nos guias do RubyGems. Apenas execute o comando:

PS.: Troque o kelvinst no commando pelo seu nickname se quiser postar a gem no repositório global! Lá o nome da sua gem deve ser único. 😁

$ bundle gem hello_kelvinst
      create  hello_kelvinst/Gemfile
      create  hello_kelvinst/Rakefile
      create  hello_kelvinst/.gitignore
      create  hello_kelvinst/hello_kelvinst.gemspec
      create  hello_kelvinst/lib/hello_kelvinst.rb
      create  hello_kelvinst/lib/hello_kelvinst/version.rb
Initializating git repo in /Users/kelvinst/hello_kelvinst

Pronto! 🎉 Você gerou um diretório para sua gem. Sinta-se livre para botar isso em um repositório no Github. 😉

2. Ajustar as especificações

Como você já deve ter percebido, foi criado um arquivo com a extensão .gemspec dentro do root do seu projeto. Esse arquivo contém basicamente as especificações da gem, nele você configura qual o nome da gem, um resuminho e tudo mais.

Se você abrir o arquivo, você vai ver que nele tem vários TODOs para alguns itens da especificação. Então vamos fazer o que ele está pedindo! Vamos atribuir as especificações!

Olha como ficou o meu:

# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'hello_kelvinst/version'

Gem::Specification.new do |spec|
  spec.name          = "hello_kelvinst"
  spec.version       = HelloKelvinst::VERSION
  spec.authors       = ["kelvinst"]
  spec.email         = ["[email protected]"]
  spec.summary       = "A hello gem to the ruby world"
  spec.description   = "I just created this gem to say hello for the ruby gems world, okay."
  spec.homepage      = ""
  spec.license       = "MIT"

  spec.files         = `git ls-files -z`.split("\x0")
  spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
  spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
  spec.require_paths = ["lib"]

  spec.add_development_dependency "bundler", "~> 1.7"
  spec.add_development_dependency "rake", "~> 10.0"
end

Se quiser copiar as descrições, está tudo bem, a licensa é MIT que é bem permissiva, hehehe. 😆

Você deve ter visto que tem um monte de coisa neste .gemspec que eu não falei né. Então, vou deixar isso para uma próxima, vou focar primeiro em como criar a gem e publicar ela pro mundo.

3. Escrever o código da gem

Agora ao que interessa! Uma gem só é uma gem se tiver algo que ela faça, e a nossa até agora não passa de uma mera especificação. Então vamos por a mão na massa de verdade.

Todo o código ruby de uma gem é por padrão colocado dentro da subpasta lib. Se você abrir ela verá que lá tem basicamente:

  • Uma pasta com o nome hello_kelvinst, que é a pasta onde você deve colocar todo e qualquer arquivo a mais que vá existir na sua gem. - Um arquivo com o nome hello_kelvinst.rb, que é o único arquivo que deve existir no root da lib. Isso porque a lib do sua gem vira o root de qualquer outro projeto que tenha importado ela, logo se você colocar arquivos na sua lib que conflite com nomes de arquivos que já existem, como por exemplo erb.rb, quando um usuário tentar executar um require 'erb' para carregar o arquivo da lib erb, ele estará carregando o seu arquivo, o que é um comportamento inesperado.

Agora voltando: vamos editar o arquivo hello_kelvinst.rb e colocar nele o código que a nossa gem deve ter! O meu eu fiz assim:

require "hello_kelvinst/version"

class Hello
  def say!
    puts 'hello'
  end
end

Simple enough! Nada mais nada menos, isso que eu ainda compliquei deixando em uma classe, mas tudo bem, assim vai.

4. Empacotar a gem

Bom, agora nosso projeto está terminado. Todo o código está pronto, só falta entregar (e testar, mas isso eu já disse que não vou fazer).

E pra empacotar sua gem é mais complicado, temos que executar o comando:

$ gem build hello_kelvinst.gemspec
WARNING:  no homepage specified
WARNING:  See http://guides.rubygems.org/specification-reference/ for help
  Successfully built RubyGem
  Name: hello_kelvinst
  Version: 0.0.1
  File: hello_kelvinst-0.0.1.gem

🎉🎉🎉

É, é só isso. 😁 Um arquivo .gem foi gerado no root do seu projeto, e essa é sua gem.

5. Usar a gem

Para usar a gem também é bem difícil! hehehe...

Primeiro tem que instalar ela:

$ gem install hello_kelvinst-0.0.1.gem
Successfully installed hello_kelvinst-0.0.1
Parsing documentation for hello_kelvinst-0.0.1
Installing ri documentation for hello_kelvinst-0.0.1
Done installing documentation for hello_kelvinst after 0 seconds
1 gem installed

E depois podemos usá-la na linha de comando interativa mesmo:

$ irb
2.1.3 :001 > require 'hello_kelvinst'
 => true
2.1.3 :002 > hello = Hello.new
 => #<Hello:0x00000001e49e30>
2.1.3 :003 > hello.say!
hello
 => nil

Viu que para usá-la você primeiro tem que dar require né? A não ser que você esteja importando ela pelo Bundler, que é assunto para outro post, mas basicamente, para importar a sua gem em um projeto rails, é necessário apenas colocar a linha gem 'hello_kelvinst' no Gemfile do seu projeto.

Aaaaah! Mas daí ele vai baixar a minha gem daonde quando eu rodar um bundle 'install'? Calma lá, é esse o último tópico!

6. Fazer upload para o Rubygems.org

O repositório global de gems é o rubygems.org, que eu já referenciei no post (lá estão os guides também). E para botar a sua gem lá é tão difícil quanto tudo o que já foi feito até agora!

Primeira coisa que você deve fazer, é acessar o site e se registrar. Depois de registrado é só executar o comando gem push hello_kelvinst-0.0.1.gem e informar o email e senha do rubygems.org:

$ gem push hello_kelvinst-0.0.1.gem
Enter your RubyGems.org credentials.
Don't have an account yet? Create one at https://rubygems.org/sign_up
   Email:   [email protected]
Password:

Signed in.
Pushing gem to https://rubygems.org...
Successfully registered gem: hello_kelvinst (0.0.1)

E pronto! Sua gem está no repositório global! Agora sempre que alguem quiser pode executar o comando gem install hello_kelvinst e vai baixar a sua gem! PS.: Só lembrando, a gem tem que ter um nome único para poder estar no repositório, logo hello_kelvinst já não dá mais.

Conclusão

Espero que tenha gostado do tutorial e que você se empolgue para montar mais e mais gems! O mundo ruby agradece!

O projeto com a gem hello_kelvinst que criei neste tutorial está publicado no github neste repositório. Se não quiser seguir o tutorial mas mesmo assim dar uma olhada em como é um diretório de uma gem, já vale a pena pra ter uma noção. 😉

Obrigado quem leu até aqui e até mais!

@arferreira
Copy link

Muito bom Kelvin!
Obrigado pelo gist

@frmichetti
Copy link

Funcionou certinho.
Valeu!

@naiieandrade
Copy link

O meu quando tento pushar, aparece essa mensagem 😕

Pushing gem to https://rubygems.org...
ERROR:  While executing gem ... (URI::InvalidURIError)
    bad URI(is not URI?): TODO: Set to 'http://mygemserver.com'

@naiieandrade
Copy link

Funcionou agora! Depois que comentei as outras linhas diferentes do seu .gemspec (:
Valeu!

@danielzanata
Copy link

Boa garoto! =D

@alexvirtualbr
Copy link

Olá Kevin, tenho um dúvida hahahaha mas antes de tudo, grato por este tuto!
Tenho uma pequena api com "rails new myapp --api" e quero saber se é uma boa estratégia torna-la uma gem e se sim, é copio todos os arquivos dela e jogo dentro da lib?
É que na verdade estou ainda pesquisando a melhor de outros applicativos consumi-la e acabei achando este teu material.

@Lavosierdq
Copy link

você poderia fazer um tutorial e explicando como fazer um gem usando Bundle e Rspec do link oficial? já li , fiz o processo e sempre dá erro. https://bundler.io/guides/bundler_2_upgrade.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment