dockerfile-rails 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +14 -2
- data/lib/generators/dockerfile_generator.rb +43 -3
- data/lib/generators/templates/Dockerfile.erb +23 -74
- data/lib/generators/templates/_apt_install.erb +10 -0
- data/lib/generators/templates/_install_node.erb +21 -0
- data/lib/generators/templates/_node_client.erb +13 -0
- data/lib/generators/templates/_npm_install.erb +17 -0
- data/lib/generators/templates/docker-entrypoint.erb +10 -0
- metadata +6 -3
- data/lib/erbtest.rb +0 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d84e3358f7afd8b5729d49e6b427e03f92eb6fe5da6a258689e933c09d721a2
|
4
|
+
data.tar.gz: 897d2a5f53c344c7162953e757b751ff646192ecd880f61cfb1754da5dfbb76d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd9b469a7c2c562c4cf137670c0d2fa177449c00ccb109e9aca65e0c48cb07d35b0a614c64daaaae699596eb2e191c7da4fcde1fc3da0566c3deed56e1b82494
|
7
|
+
data.tar.gz: 4ec4f71ecc02555da309027504872e137ccffa936b42ef42c935f2d0349b49cbccdfc39924f284653c952096bc3ea8014d9218eed92e7e71cfac15555e860705
|
data/README.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
-
##
|
1
|
+
## Overview
|
2
2
|
|
3
|
-
|
3
|
+
Provides Rails generators to produce Dockerfiles and related files. This is being proposed as the generator to be included in Rails 7.1, and a substantial number of pull requests along those lines have already been merged. This repository contains fixes and features beyond those pull requests. Highlights:
|
4
|
+
|
5
|
+
* Supports all [Rails supported releases](https://guides.rubyonrails.org/maintenance_policy.html), not just Rails 7.1, and likely works with a number of previous releases.
|
6
|
+
* Can be customized using flags on the `generate dockerfile` command, and rerun to produce a custom tailored dockerfile based on detecting the actual features used by your application.
|
7
|
+
* Can produce a `docker-compose.yml` file for locally testing your configuration before deploying.
|
4
8
|
|
5
9
|
## Usage
|
6
10
|
|
@@ -28,9 +32,17 @@ additional support may be needed:
|
|
28
32
|
* `--redis` - add redis libraries
|
29
33
|
* `--sqlite3` - add sqlite3 libraries
|
30
34
|
|
35
|
+
Optimizations:
|
36
|
+
|
37
|
+
* `--fullstaq` - use [fullstaq](https://fullstaqruby.org/) [images](https://github.com/evilmartians/fullstaq-ruby-docker) on [quay.io](https://quay.io/repository/evl.ms/fullstaq-ruby?tab=tags&tag=latest)
|
38
|
+
* `--jemalloc` - use [jemalloc](https://jemalloc.net/) memory allocator
|
39
|
+
* `--yjit` - enable [YJIT](https://github.com/ruby/ruby/blob/master/doc/yjit/yjit.md) optimizing compiler.
|
40
|
+
* `--swap=n` - allocate swap space. See [falloc options](https://man7.org/linux/man-pages/man1/fallocate.1.html#OPTIONS) for suffixes.
|
41
|
+
|
31
42
|
Links:
|
32
43
|
|
33
44
|
* [Demos](./DEMO.md)
|
34
45
|
* [Preparations for Rails 7.1](https://community.fly.io/t/preparations-for-rails-7-1/9512)
|
35
46
|
* [Rails Dockerfile futures](https://discuss.rubyonrails.org/t/rails-dockerfile-futures/82091/1)
|
36
47
|
* [Fly Cookbooks](https://fly.io/docs/rails/cookbooks/)
|
48
|
+
* [app/templates/Dockerfile.tt](https://github.com/rails/rails/blob/main/railties/lib/rails/generators/rails/app/templates/Dockerfile.tt)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
1
3
|
class DockerfileGenerator < Rails::Generators::Base
|
2
4
|
include DockerfileRails::Scanner
|
3
5
|
|
@@ -10,10 +12,13 @@ class DockerfileGenerator < Rails::Generators::Base
|
|
10
12
|
class_option :parallel, type: :boolean, default: false,
|
11
13
|
desc: 'use build stages to install gems and node modules in parallel'
|
12
14
|
|
15
|
+
class_option :swap, type: :string, default: nil,
|
16
|
+
desc: 'allocate swapspace'
|
17
|
+
|
13
18
|
class_option :compose, type: :boolean, default: false,
|
14
19
|
desc: 'generate a docker-compose.yml file'
|
15
20
|
|
16
|
-
class_option :
|
21
|
+
class_option :redis, type: :boolean, default: false,
|
17
22
|
desc: 'include redis libraries'
|
18
23
|
|
19
24
|
class_option :sqlite3, aliases: '--sqlite', type: :boolean, default: false,
|
@@ -52,6 +57,30 @@ class DockerfileGenerator < Rails::Generators::Base
|
|
52
57
|
|
53
58
|
private
|
54
59
|
|
60
|
+
def render(options)
|
61
|
+
scope = (Class.new do
|
62
|
+
def initialize(obj, locals)
|
63
|
+
@_obj = obj
|
64
|
+
@_locals = OpenStruct.new(locals)
|
65
|
+
end
|
66
|
+
|
67
|
+
def method_missing(method, *args, &block)
|
68
|
+
if @_locals.respond_to? method
|
69
|
+
@_locals.send method, *args, &block
|
70
|
+
else
|
71
|
+
@_obj.send method, *args, &block
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_binding
|
76
|
+
binding
|
77
|
+
end
|
78
|
+
end).new(self, options[:locals] || {})
|
79
|
+
|
80
|
+
template = IO.read(File.join(source_paths.last, "_#{options[:partial]}.erb"))
|
81
|
+
ERB.new(template, trim_mode: '-').result(scope.get_binding).strip
|
82
|
+
end
|
83
|
+
|
55
84
|
def using_node?
|
56
85
|
return @using_node if @using_node != nil
|
57
86
|
@using_node = File.exist? 'package.json'
|
@@ -61,6 +90,10 @@ private
|
|
61
90
|
options.redis? or @redis
|
62
91
|
end
|
63
92
|
|
93
|
+
def using_execjs?
|
94
|
+
@gemfile.include? 'execjs'
|
95
|
+
end
|
96
|
+
|
64
97
|
def parallel?
|
65
98
|
using_node? && options.parallel
|
66
99
|
end
|
@@ -88,9 +121,13 @@ private
|
|
88
121
|
# ActiveStorage preview support
|
89
122
|
packages << "libvips" if @gemfile.include? 'ruby-vips'
|
90
123
|
|
124
|
+
# Rmagick gem
|
125
|
+
packages += %w[pkg-config libmagickwand-dev] if @gemfile.include? 'rmagick'
|
126
|
+
|
91
127
|
# node support, including support for building native modules
|
92
128
|
if using_node?
|
93
|
-
packages += %w(
|
129
|
+
packages += %w(node-gyp pkg-config)
|
130
|
+
packages += %w(curl unzip) unless using_execjs?
|
94
131
|
|
95
132
|
# module build process depends on Python, and debian changed
|
96
133
|
# how python is installed with the bullseye release. Below
|
@@ -129,6 +166,9 @@ private
|
|
129
166
|
# ActiveStorage preview support
|
130
167
|
packages << "libvips" if @gemfile.include? 'ruby-vips'
|
131
168
|
|
169
|
+
# Rmagick gem
|
170
|
+
packages << 'imagemagick' if @gemfile.include? 'rmagick'
|
171
|
+
|
132
172
|
packages.sort
|
133
173
|
end
|
134
174
|
|
@@ -184,7 +224,7 @@ private
|
|
184
224
|
end
|
185
225
|
|
186
226
|
def depend_on_bootsnap?
|
187
|
-
@gemfile.include? '
|
227
|
+
@gemfile.include? 'bootsnap'
|
188
228
|
end
|
189
229
|
|
190
230
|
def api_only?
|
@@ -3,35 +3,7 @@
|
|
3
3
|
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
|
4
4
|
ARG RUBY_VERSION=<%= RUBY_VERSION %>
|
5
5
|
<% if api_client_dir -%>
|
6
|
-
|
7
|
-
|
8
|
-
FROM node:$NODE_VERSION-slim as client
|
9
|
-
|
10
|
-
WORKDIR /rails/<%= api_client_dir %>
|
11
|
-
|
12
|
-
ENV NODE_ENV=production
|
13
|
-
|
14
|
-
# Install node modules
|
15
|
-
COPY <%= api_client_files.join(' ') %> .
|
16
|
-
<% if api_client_files.join.include? 'yarn' -%>
|
17
|
-
<% if options.cache? -%>
|
18
|
-
RUN --mount=type=cache,id=bld-yarn-cache,target=/root/.yarn \
|
19
|
-
YARN_CACHE_FOLDER=/root/.yarn yarn install
|
20
|
-
<% else -%>
|
21
|
-
RUN yarn install
|
22
|
-
<% end -%>
|
23
|
-
<% else -%>
|
24
|
-
<% if options.cache? -%>
|
25
|
-
RUN --mount=type=cache,id=bld-yarn-cache,target=/root/.npm \
|
26
|
-
npm install
|
27
|
-
<% else -%>
|
28
|
-
RUN npm install
|
29
|
-
<% end -%>
|
30
|
-
<% end -%>
|
31
|
-
|
32
|
-
# build client application
|
33
|
-
COPY <%= api_client_dir %> .
|
34
|
-
RUN npm run build
|
6
|
+
<%= render partial: 'node_client' %>
|
35
7
|
|
36
8
|
|
37
9
|
<% end -%>
|
@@ -49,23 +21,24 @@ ENV RAILS_ENV="production" \
|
|
49
21
|
BUNDLE_PATH="vendor/bundle" \
|
50
22
|
BUNDLE_WITHOUT="<%= options.ci? ? 'test' : 'development:test' %>"
|
51
23
|
|
24
|
+
# Update gems and preinstall the desired version of bundler
|
52
25
|
ARG BUNDLER_VERSION=<%= Bundler::VERSION %>
|
53
26
|
RUN gem update --system --no-document && \
|
54
27
|
gem install -N bundler -v ${BUNDLER_VERSION}
|
55
28
|
|
29
|
+
<% if using_execjs? -%>
|
30
|
+
# Install packages needed to install nodejs
|
31
|
+
<%= render partial: 'apt_install', locals: {packages: %w(curl unzip), clean: true} %>
|
32
|
+
|
33
|
+
<%= render partial: 'install_node', locals: {yarn_version: nil} %>
|
34
|
+
|
35
|
+
<% end -%>
|
56
36
|
|
57
37
|
# Throw-away build stage<%= parallel? ? 's' : '' %> to reduce size of final image
|
58
38
|
FROM base as <%= parallel? ? 'pre' : '' %>build
|
59
39
|
|
60
|
-
# Install packages
|
61
|
-
|
62
|
-
RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
|
63
|
-
--mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
|
64
|
-
apt-get update -qq && \
|
65
|
-
<% else -%>
|
66
|
-
RUN apt-get update -qq && \
|
67
|
-
<% end -%>
|
68
|
-
apt-get install -y <%= build_packages.join(" ") %>
|
40
|
+
# Install packages needed to build gems<%= using_node? ? " and node modules" : "" %>
|
41
|
+
<%= render partial: 'apt_install', locals: {packages: build_packages, clean: false} %>
|
69
42
|
|
70
43
|
<% if parallel? -%>
|
71
44
|
|
@@ -73,24 +46,11 @@ FROM prebuild as node
|
|
73
46
|
|
74
47
|
<% end -%>
|
75
48
|
<% if using_node? -%>
|
76
|
-
|
77
|
-
ARG NODE_VERSION=<%= node_version %>
|
78
|
-
ARG YARN_VERSION=<%= yarn_version %>
|
79
|
-
RUN curl -fsSL https://fnm.vercel.app/install | bash && \
|
80
|
-
/root/.local/share/fnm/fnm install $NODE_VERSION
|
81
|
-
ENV PATH=/root/.local/share/fnm/aliases/default/bin/:$PATH
|
82
|
-
RUN npm install -g yarn@$YARN_VERSION
|
49
|
+
<%= render partial: 'install_node', locals: {node_version: using_execjs? ? nil : node_version} %>
|
83
50
|
|
84
51
|
<% end -%>
|
85
52
|
<% if parallel? -%>
|
86
|
-
|
87
|
-
COPY package.json yarn.lock ./
|
88
|
-
<% if options.cache? -%>
|
89
|
-
RUN --mount=type=cache,id=bld-yarn-cache,target=/root/.yarn \
|
90
|
-
YARN_CACHE_FOLDER=/root/.yarn yarn install
|
91
|
-
<% else -%>
|
92
|
-
RUN yarn install
|
93
|
-
<% end -%>
|
53
|
+
<%= render partial: 'npm_install', locals: {sources: %w(package.json yarn.lock)} %>
|
94
54
|
|
95
55
|
|
96
56
|
FROM prebuild as build
|
@@ -103,25 +63,23 @@ RUN --mount=type=cache,id=bld-gem-cache,sharing=locked,target=/srv/vendor \
|
|
103
63
|
bundle config set app_config .bundle && \
|
104
64
|
bundle config set path /srv/vendor && \
|
105
65
|
bundle _${BUNDLER_VERSION}_ install && \
|
66
|
+
<% if depend_on_bootsnap? -%> && \
|
67
|
+
bundle exec bootsnap precompile --gemfile && \
|
68
|
+
<% end -%>
|
106
69
|
bundle clean && \
|
107
70
|
mkdir -p vendor && \
|
108
71
|
bundle config set path vendor && \
|
109
72
|
cp -ar /srv/vendor .
|
110
73
|
<% else -%>
|
111
|
-
RUN bundle _${BUNDLER_VERSION}_ install
|
74
|
+
RUN bundle _${BUNDLER_VERSION}_ install<% if depend_on_bootsnap? -%> && \
|
75
|
+
bundle exec bootsnap precompile --gemfile
|
76
|
+
<% end -%>
|
112
77
|
<% end -%>
|
113
78
|
|
114
79
|
<% if parallel? -%>
|
115
80
|
asdf
|
116
81
|
<% elsif using_node? -%>
|
117
|
-
|
118
|
-
COPY package.json yarn.lock ./
|
119
|
-
<% if options.cache? -%>
|
120
|
-
RUN --mount=type=cache,id=bld-yarn-cache,target=/root/.yarn \
|
121
|
-
YARN_CACHE_FOLDER=/root/.yarn yarn install
|
122
|
-
<% else -%>
|
123
|
-
RUN yarn install
|
124
|
-
<% end -%>
|
82
|
+
<%= render partial: 'npm_install', locals: {sources: %w(package.json yarn.lock)} %>
|
125
83
|
|
126
84
|
<% end -%>
|
127
85
|
# Copy application code
|
@@ -129,7 +87,7 @@ COPY . .
|
|
129
87
|
|
130
88
|
<% if depend_on_bootsnap? -%>
|
131
89
|
# Precompile bootsnap code for faster boot times
|
132
|
-
RUN bundle exec bootsnap precompile
|
90
|
+
RUN bundle exec bootsnap precompile app/ lib/
|
133
91
|
|
134
92
|
<% end -%>
|
135
93
|
<% unless binfile_fixups.empty? -%>
|
@@ -147,17 +105,8 @@ RUN SECRET_KEY_BASE<%= Rails::VERSION::MAJOR<7 || Rails::VERSION::STRING.start_w
|
|
147
105
|
FROM base
|
148
106
|
<% unless deploy_packages.empty? -%>
|
149
107
|
|
150
|
-
# Install packages
|
151
|
-
|
152
|
-
RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
|
153
|
-
--mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
|
154
|
-
apt-get update -qq && \
|
155
|
-
apt-get install --no-install-recommends -y <%= deploy_packages.join(" ") %>
|
156
|
-
<% else -%>
|
157
|
-
RUN apt-get update -qq && \
|
158
|
-
apt-get install --no-install-recommends -y <%= deploy_packages.join(" ") %> && \
|
159
|
-
rm -rf /var/lib/apt/lists /var/cache/apt/archives
|
160
|
-
<% end -%>
|
108
|
+
# Install packages needed for deployment
|
109
|
+
<%= render partial: 'apt_install', locals: {packages: deploy_packages, clean: true} %>
|
161
110
|
<% end -%>
|
162
111
|
|
163
112
|
# Copy built application from previous stage
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<% if options.cache? -%>
|
2
|
+
RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
|
3
|
+
--mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
|
4
|
+
apt-get update -qq && \
|
5
|
+
apt-get install --no-install-recommends -y <%= packages.join(" ") %>
|
6
|
+
<% else -%>
|
7
|
+
RUN apt-get update -qq && \
|
8
|
+
apt-get install --no-install-recommends -y <%= packages.join(" ") %><% if clean %> && \
|
9
|
+
rm -rf /var/lib/apt/lists /var/cache/apt/archives<% end %>
|
10
|
+
<% end -%>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<% if node_version and yarn_version -%>
|
2
|
+
# Install JavaScript dependencies
|
3
|
+
<% elsif node_version -%>
|
4
|
+
# Install Node.js
|
5
|
+
<% elsif yarn_version -%>
|
6
|
+
# Install yarn
|
7
|
+
<% end -%>
|
8
|
+
<% if node_version -%>
|
9
|
+
ARG NODE_VERSION=<%= node_version %>
|
10
|
+
<% end -%>
|
11
|
+
<% if yarn_version -%>
|
12
|
+
ARG YARN_VERSION=<%= yarn_version %>
|
13
|
+
<% end -%>
|
14
|
+
<% if node_version -%>
|
15
|
+
RUN curl -fsSL https://fnm.vercel.app/install | bash && \
|
16
|
+
/root/.local/share/fnm/fnm install $NODE_VERSION
|
17
|
+
ENV PATH=/root/.local/share/fnm/aliases/default/bin/:$PATH
|
18
|
+
<% end -%>
|
19
|
+
<% if yarn_version -%>
|
20
|
+
RUN npm install -g yarn@$YARN_VERSION
|
21
|
+
<% end -%>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
ARG NODE_VERSION=<%= node_version %>
|
2
|
+
|
3
|
+
FROM node:$NODE_VERSION-slim as client
|
4
|
+
|
5
|
+
WORKDIR /rails/<%= api_client_dir %>
|
6
|
+
|
7
|
+
ENV NODE_ENV=production
|
8
|
+
|
9
|
+
<%= render partial: 'npm_install', locals: {sources: api_client_files} %>
|
10
|
+
|
11
|
+
# build client application
|
12
|
+
COPY <%= api_client_dir %> .
|
13
|
+
RUN npm run build
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Install node modules
|
2
|
+
COPY <%=sources.join(' ') %> .
|
3
|
+
<% if sources.join.include? 'yarn' -%>
|
4
|
+
<% if options.cache? -%>
|
5
|
+
RUN --mount=type=cache,id=bld-yarn-cache,target=/root/.yarn \
|
6
|
+
YARN_CACHE_FOLDER=/root/.yarn yarn install
|
7
|
+
<% else -%>
|
8
|
+
RUN yarn install
|
9
|
+
<% end -%>
|
10
|
+
<% else -%>
|
11
|
+
<% if options.cache? -%>
|
12
|
+
RUN --mount=type=cache,id=bld-npm-cache,target=/root/.npm \
|
13
|
+
npm install
|
14
|
+
<% else -%>
|
15
|
+
RUN npm install
|
16
|
+
<% end -%>
|
17
|
+
<% end -%>
|
@@ -1,5 +1,15 @@
|
|
1
1
|
#!/bin/bash
|
2
2
|
|
3
|
+
<% if options.swap -%>
|
4
|
+
# allocate swap space
|
5
|
+
fallocate -l <%= options.swap %> /swapfile
|
6
|
+
chmod 0600 /swapfile
|
7
|
+
mkswap /swapfile
|
8
|
+
echo 10 > /proc/sys/vm/swappiness
|
9
|
+
swapon /swapfile
|
10
|
+
echo 1 > /proc/sys/vm/overcommit_memory
|
11
|
+
|
12
|
+
<% end -%>
|
3
13
|
# If running the rails server then create or migrate existing database
|
4
14
|
if [ "${*}" == "./bin/rails server" ]; then
|
5
15
|
./bin/rails <%= dbprep_command %>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dockerfile-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Ruby
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-01-
|
11
|
+
date: 2023-01-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -36,9 +36,12 @@ files:
|
|
36
36
|
- Rakefile
|
37
37
|
- lib/dockerfile-rails.rb
|
38
38
|
- lib/dockerfile-rails/scanner.rb
|
39
|
-
- lib/erbtest.rb
|
40
39
|
- lib/generators/dockerfile_generator.rb
|
41
40
|
- lib/generators/templates/Dockerfile.erb
|
41
|
+
- lib/generators/templates/_apt_install.erb
|
42
|
+
- lib/generators/templates/_install_node.erb
|
43
|
+
- lib/generators/templates/_node_client.erb
|
44
|
+
- lib/generators/templates/_npm_install.erb
|
42
45
|
- lib/generators/templates/docker-compose.yml.erb
|
43
46
|
- lib/generators/templates/docker-entrypoint.erb
|
44
47
|
- lib/generators/templates/dockerignore.erb
|
data/lib/erbtest.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
TEMPLATE = <<-EOF
|
2
|
-
value is <%= five %>
|
3
|
-
other is <%= three %>
|
4
|
-
EOF
|
5
|
-
|
6
|
-
require 'delegate'
|
7
|
-
require 'forwardable'
|
8
|
-
class Scope < SimpleDelegator
|
9
|
-
end
|
10
|
-
|
11
|
-
require 'erb'
|
12
|
-
class ShoppingList
|
13
|
-
def five
|
14
|
-
'FiVe'
|
15
|
-
end
|
16
|
-
|
17
|
-
def initialize
|
18
|
-
renderer = ERB.new(TEMPLATE)
|
19
|
-
puts '***'
|
20
|
-
|
21
|
-
values = {one: 'One', three: 'tHrEe'}
|
22
|
-
|
23
|
-
scope = (Class.new(SimpleDelegator) do
|
24
|
-
extend Forwardable
|
25
|
-
def_delegators values, :one, :three
|
26
|
-
|
27
|
-
def three
|
28
|
-
3
|
29
|
-
end
|
30
|
-
end).new(self)
|
31
|
-
|
32
|
-
puts renderer.result(scope.get_binding)
|
33
|
-
end
|
34
|
-
|
35
|
-
def get_binding
|
36
|
-
binding
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
puts '?'
|
41
|
-
test = ShoppingList.new
|