Skip to content

Instantly share code, notes, and snippets.

@nacyot
Created August 19, 2014 05:48
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save nacyot/227495f2ba6164c9648b to your computer and use it in GitHub Desktop.
Save nacyot/227495f2ba6164c9648b to your computer and use it in GitHub Desktop.

Bundler 사용법 & Gem 만들기

루비 프로젝트 구조

  • Summer

핵심 디렉터리 구조

.
├── bin                   # 실행 파일
├── lib                   # 프로그램 코드
└── spec                  # 테스트 코드(spec)

일반적인 프로젝트 구조

.
├── bin                   # 실행 파일
├── config                # 설정 파일 
├── lib                   # 프로그램 코드
│   └─  summer 
├── spec                  # 테스트 코드(spec)
├── tmp                   # 임시 파일
└── vendor                # 써드파티 코드

프로젝트 Root 파일들

├── .yardopts             # 문서화 툴 yard 옵션 파일
├── .rspec                # 테스트 툴 rspce 옵션 파일
├── .gitignore            # git에서 무시할 파일 정의
├── .rubocop.yml          # 루비 코드 규칙 강제 파일
├── CHANGELOG.md          # 중요한 변경 사항 정리
├── Gemfile               # 의존성 선언 파일
├── Guardfile             # Watch 대상 정의 파일
├── Rakefile              # Rake Task 정의 파일
├── circle.yml            # Circle CI 빌드 프로세스 정의 파일
├── summer.gemspec        # gemspec 정의 파일
└── README.md             # 프로젝트 개요 파일

Bundler

  • 루비 의존성 선언 및 의존성 분리 도구

Bundler 설치

$ gem install bundler
$ bundle --version
Bundler version 1.7.0

Gemfile

  • 의존성 선언 파일
  • 자체 DSL로 작성
source 'https://rubygems.org'
gem 'nokogiri'
gem 'rack', '~>1.1'
gem 'rspec', '~>2', :require => 'rspec'

source 지시자

  • Gem을 받아오는 서버 정의
source 'https://rubygems.org'
  • 자체 서버 운용 가능
source 'https://rubygems.org'
source 'https://gems.lee-vi.co.kr'

gem 지시자(1)

  • 다른 의존성을 고려해 최신버전의 nokogiri 사용
gem 'nokogiri'

gem 지시자(2)

  • 다른 의존성을 고려해 rack 1.* 버전을 사용(버전의 명시적 지정)
gem 'rack', '~>1.1'

gem 지시자(3)

  • Bundle 전체 로드를 하면 기본적으로 인자의 이름으로 require를 시도
  • 라이브러리의 이름이 다를 경우 명시적으로 지정 가능
gem 'rspec', '~>2', require: 'rspec'
  • 직접 로드하는 경우 false를 사용할 수 있음
gem 'rspec', require: false

의존성 설치

$ bundle install
bundle install
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...
Using diff-lcs 1.2.5
Using mini_portile 0.6.0
Installing nokogiri 1.6.3.1
Using rack 1.5.2
Using rspec-core 2.14.8 (was 3.0.4)
Using rspec-expectations 2.14.5 (was 3.0.4)
Using rspec-mocks 2.14.6 (was 3.0.4)
Using rspec 2.14.1 (was 3.0.0)
Using bundler 1.7.0
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.

Gemfile.lock

  • 자동으로 사용가능 의존성 충돌이 일어나지 않는 버전들을 찾아줌
GEM
  remote: https://rubygems.org/
  specs:
    diff-lcs (1.2.5)
    mini_portile (0.6.0)
    nokogiri (1.6.3.1)
      mini_portile (= 0.6.0)
    ...
    rspec-mocks (2.14.6)

PLATFORMS
  ruby

DEPENDENCIES
  nokogiri
  rack (~> 1.1)
  rspec (~> 2)

의존성 분리

  • 의존성 분리를 사용하지 않는 경우
$ rspec --version
3.0.4
  • 의존성 분리 환경 안에서 실행
$ bundle exec rspec --version
2.14.8
# Gemfile에 의존적
$ mv Gemfile Gemfile.old
$ bundle exec rspec --version    
/home/nacyot/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/bundl...
        from /home/nacyot/.rbenv/versions/2.1.2/bin/rspec:22:in `<main>'

라이브러리에서 사용하기

Bundler.require

# bin/run.rb
require 'rubygems'
require 'bundler/setup'
Bundler.require

puts Nokogiri
$ run ./bin/run.rb
Nokogiri

Bundler.require(cont.)

Bundler.require
# 표현식은 Gemfile에 정의된 아래의 라이브러리를 require한다.
# require 'nokogiri'
# require 'rack'
# require 'rspec'

남용해서는 안 됨.

Bundler.setup

require 'rubygems'
require 'bundler/setup'
# 아래 라인은 없어도 암묵적으로 사용됨. 그룹 지정 시에 명시적으로 사용.
Bundler.setup(:default) 

puts Nokogiri
$ run ./bin/run.rb
./bin/run.rb:5:in `<main>': uninitialized constant Nokogiri (NameError)

Bundler.setup (cont.)

require 'rubygems'
require 'bundler/setup'
Bundler.setup(:default) 
# 정확히 Gemfile.lock에 정의된 버전을 로드한다.
require 'nokogiri'

puts Nokogiri
$ run ./bin/run.rb
Nokogiri

Bundler

Gemfile vs gemspec

/lib/summer.rb

module Summer

end

Gemfile

source "http://rubygems.org"
gemspec

summer.gemspec

Gem::Specification.new do |s|
  # 프로젝트 정보
  s.name = "summer"
  s.version     = '0.1'
  s.licenses    = "copyright 2014- Daekwon Kim"
  s.summary     = "summer library"
  s.description = "library related with"
  s.authors     = ["Daekwon Kim"]
  s.email       = 'naycot@leevi.co.kr'
  s.files       = ["lib/summer.rb"]
  s.homepage    = 'https://github.com/nacyot/summer'

  # 의존성 선언
  s.add_dependency('nokogiri', '>0')
  s.add_dependency('rack', '~>1.1')
  s.add_dependency('rspec', '~>2')
end

의존성 설치

$ bundle install

Gem 생성

$ gem build summer.gemspec
  Successfully built RubyGem
  Name: summer
  Version: 0.1
  File: summer-0.1.gem
$ ls summer-0.1.gem
summer-0.1.gem

Gem 설치하기

gem install --local summer-0.1.gem
Successfully installed summer-0.1
Parsing documentation for summer-0.1
Installing ri documentation for summer-0.1
Done installing documentation for summer after 0 seconds
1 gem installed

Gemfile에서 사용하기

# gemspec이 있는 디렉터리를 지정
gem 'summer', path: "/path/to/summer"

다른 프로젝트 Gemfile

source 'https://rubygems.org'

gem 'summer', path: "/path/to/summer"

다른 프로젝트 run.rb

require 'rubygems'
require 'bundler/setup'
Bundler.setup(:default)
require 'summer'

puts Summer
$ ruby ./bin/run.rb
Summer

Gem Server

gem server

$ gem server
Server started at http://0.0.0.0:8808
Server started at http://[::]:8808

http://i.imgur.com/5Cl3THk.png

Gemfile

source 'https://0.0.0.0:8808'

gem 'summer'

Gemfile on Bundler 1.7

source 'https://rubygems.org'

source 'https://0.0.0.0:8808' do 
  gem 'summer'
end

bundle install

$ bundle install
Fetching source index from http://0.0.0.0:8808/
Resolving dependencies...
Using diff-lcs 1.2.5
Using mini_portile 0.6.0
Using nokogiri 1.6.3.1
Using rack 1.5.2
Using rspec-core 2.99.1
Using rspec-expectations 2.99.2
Using rspec-mocks 2.99.2
Using rspec 2.99.0
Using summer 0.1
Using bundler 1.7.0
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment