Skip to content

Commit a3e5eb5

Browse files
committed
Add basic-ruby devcontainer template
This provides basic scaffolding for a simple Ruby application with some minimal VS Code extensions and gems set up, and a trivial code structure.
1 parent d5be31e commit a3e5eb5

File tree

9 files changed

+124
-0
lines changed

9 files changed

+124
-0
lines changed
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
FROM ruby:${templateOption:imageVariant}
2+
3+
ARG USERNAME=devcontainer
4+
ARG USER_UID=1000
5+
ARG USER_GID=$USER_UID
6+
7+
# Install basic development tools
8+
RUN apt update && apt install -y less man-db sudo
9+
10+
# Set up unprivileged local user
11+
#
12+
# NOTE: The Ruby images will eventually be available with Ubuntu 24.04 (`noble`), the base images of
13+
# which already have a default `ubuntu` user configured. You will need to remove the creation of the
14+
# user and group when you upgrade the Ruby images.
15+
RUN groupadd --gid $USER_GID $USERNAME \
16+
&& groupadd bundler \
17+
&& useradd --uid $USER_UID --gid $USER_GID -m $USERNAME --shell /bin/bash --groups bundler \
18+
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
19+
&& chmod 0440 /etc/sudoers.d/$USERNAME
20+
21+
# Set unprivileged user as default user
22+
USER $USERNAME
23+
24+
# Set `DEVCONTAINER` environment variable to help with orientation
25+
ENV DEVCONTAINER=true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// See https://containers.dev/implementors/json_reference/ for configuration reference
2+
{
3+
"name": "New Ruby project",
4+
"build": {
5+
"dockerfile": "Dockerfile"
6+
},
7+
"remoteUser": "devcontainer",
8+
"postCreateCommand": "bundle install",
9+
"customizations": {
10+
"vscode": {
11+
"extensions": [
12+
"Shopify.ruby-lsp",
13+
"KoichiSasada.vscode-rdbg"
14+
],
15+
"settings": {
16+
"rubyLsp.rubyVersionManager": {
17+
"identifier": "none" // Force native container Ruby
18+
},
19+
"[ruby]": {
20+
"editor.defaultFormatter": "Shopify.ruby-lsp",
21+
"editor.formatOnSave": true
22+
}
23+
}
24+
}
25+
},
26+
}

src/basic-ruby/Gemfile

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# frozen_string_literal: true
2+
3+
source 'https://rubygems.org'
4+
5+
group :development, :test do
6+
gem 'minitest'
7+
gem 'rubocop'
8+
end

src/basic-ruby/Rakefile

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# frozen_string_literal: true
2+
3+
require 'minitest/test_task'
4+
5+
Minitest::TestTask.create
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"id": "basic-ruby",
3+
"version": "1.0.0",
4+
"name": "Basic Ruby application",
5+
"description": "A devcontainer for basic Ruby applications",
6+
"publisher": "Christian Sutter",
7+
"documentationURL": "https://github.com/csutter/devcontainer-templates",
8+
"licenseURL": "https://github.com/csutter/devcontainer-templates/blob/main/LICENSE",
9+
"options": {
10+
"imageVariant": {
11+
"type": "string",
12+
"description": "Upstream 'ruby' image tag (see hub.docker.com):",
13+
"proposals": [
14+
"3.3"
15+
],
16+
"default": "3.3"
17+
}
18+
},
19+
"platforms": ["Ruby"]
20+
}

src/basic-ruby/lib/hello.rb

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# frozen_string_literal: true
2+
3+
# An example class
4+
class Hello
5+
def message
6+
'Hello, World!'
7+
end
8+
end

src/basic-ruby/test/test_hello.rb

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# frozen_string_literal: true
2+
3+
require 'minitest/autorun'
4+
5+
require 'hello'
6+
7+
class TestHello < Minitest::Test
8+
def setup
9+
@hello = Hello.new
10+
end
11+
12+
def test_hello
13+
assert_equal 'Hello, World!', @hello.message
14+
end
15+
end

test/basic-ruby/test.sh

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
source "$(dirname "$0")/../harness.sh"
4+
5+
setup "basic-ruby" "3.3.4"
6+
7+
run_test "Ruby version is correct" "ruby -v" "$IMAGE_TAG"
8+
run_test "Container defaults to non-root user" "whoami" "devcontainer"
9+
run_test "Non-root user is able to sudo" "sudo whoami" "root"
10+
11+
run_test "The bundle is installed after creation" "bundle check" \
12+
"The Gemfile's dependencies are satisfied"
13+
run_test "The template code satisfies Rubocop" "rubocop" "no offenses detected"
14+
run_test "The example test runs" "rake test" "1 runs, 1 assertions, 0 failures, 0 errors, 0 skips"

test/harness.sh

+3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ setup() {
2626
cp -R "$SRC_DIR"/../../src/"$TEMPLATE" $TEST_ROOT/
2727
cp -R "$SRC_DIR"/../../test/"$TEMPLATE" $TEST_ROOT/
2828

29+
# Ensure temporary directory is writable by the container
30+
chmod -R 777 $TEST_ROOT
31+
2932
# Validate template is valid JSON before doing anything else and getting into a weird place
3033
jq . "$TEST_DIR"/devcontainer-template.json > /dev/null
3134

0 commit comments

Comments
 (0)