Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ Gemfile.lock
*.swp
examples/make_example/build
examples/temp_sensor/build
docker/.env
30 changes: 30 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# CMock Docker environment for development

A Docker-based virtual development environment based on Arch. The container uses SSH keys from the host OS, loaded as Read-only when starting the container (executing `./run.sh`), allowing to use host OS SSH authentication. Keys are not persistent in the image, and are only injected when starting the container. The only persistent things in the image is the workspace and the configuration scripts placed inside the image during building. The environment comes with pre-configured Vim with Clangd support. The `run.sh` is configured to clean up the container when you call `exit` from inside, to avoid any hanging running containers. The container does not affect any files or settings on your host OS.

# Instruction

1. Install Docker for your host OS;

2. Generate your SSH keys on the host OS if you don't have any yet, and add them in your GitHub account settings to be able to contribute;

3. Fork the CMock repository, so that the Docker environment can resolve it from your GitHub and clone the fork into the workspace during first run.

4. Create `.env` file locally in your cloned repository, with `GIT_USER_NAME` and `GIT_USER_EMAIL` variables set;
Example:
```
// .env
GIT_USER_NAME=TheJourneymansGuide
GIT_USER_EMAIL=k.woj.coding@gmail.com
```
This allows `git` inside the container to resolve your fork of the CMock repo, and to know what user name and e-mail to use when you commit something;

5. Run `./setup.sh` - this will create a docker volume for workspace persistance on your local machine, and will create the environment image;

6. Run `./run.sh` - this will start the image. If the CMock repository is not present in workspace, it will automatically get cloned during the first start.

7. \* If you would like to attach to the container with a second terminal, the `attach.sh` script will automatically resolve your current cmock-dev-arch instance and connect to it (executed as: `./attach.sh`);

> __IMPORTANT__: Be careful when you run multiple terminals in the same container. If you close the 'root' terminal that started the container, it will kill the container and subsequently disconnect all the other terminals from it.

> __NOTE__: Make sure you have Unicode-compliant font to enable the fish terminal to display symbols instead of rectangles. Example fonts are `Fira Code` and `Cascadia Code`.
119 changes: 119 additions & 0 deletions docker/Resources/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#syntax=docker/dockerfile:1.6

FROM archlinux:latest

ARG GIT_USER_NAME="ThrowTheSwitch"
ENV GIT_USER_NAME=${GIT_USER_NAME}

# Set the locale
ENV TERM=xterm-256color
ENV STARSHIP_CONFIG=/etc/starship/starship.toml

# Install basic dependencies for the system
RUN pacman -Syu --noconfirm && \
pacman -S --noconfirm \
glibc \
base \
base-devel \
sudo \
bash \
less

ENV PATH="/usr/bin:$PATH"

RUN pacman -Syu --noconfirm \
git \
curl \
wget

RUN pacman -Syu --noconfirm \
openssh \
ca-certificates \
zip \
unzip \
vim \
tree

RUN pacman -Syu --noconfirm \
fish \
starship \
noto-fonts \
noto-fonts-emoji \
fzf \
ripgrep \
fd \
universal-ctags

# Create dev user
ARG USERNAME=Dev
ARG UID=1000
ARG GID=1000

RUN groupadd -g ${GID} ${USERNAME} && \
useradd -m -u ${UID} -g ${GID} -s /usr/bin/fish ${USERNAME}

RUN echo "${USERNAME} ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/${USERNAME} && \
chmod 0440 /etc/sudoers.d/${USERNAME}

# Install development dependencies
RUN pacman -Syu --noconfirm \
make \
cmake \
ninja

RUN pacman -Syu --noconfirm \
bash-language-server \
fzf

RUN pacman -Syu --noconfirm \
llvm \
clang \
clang-tools-extra

RUN pacman -Syu --noconfirm \
gdb \
valgrind \
gtest


RUN pacman -Syu --noconfirm \
ruby \
ruby-irb \
ruby-rake \
ruby-bundler

# Seed the Docker image with CMock repository and its dependencies
RUN git clone "https://github.com/${GIT_USER_NAME}/CMock.git" /opt/CMock && \
cd /opt/CMock && \
bundle install && \
chown -R Dev:Dev /opt/CMock

USER ${USERNAME}
ENV HOME=/home/Dev

# Install Vim cofiguration
RUN sudo mkdir -p /usr/share/vim/vimfiles/autoload && \
sudo curl -fLo /usr/share/vim/vimfiles/autoload/plug.vim \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

COPY Resources/vim /home/Dev/.vim
COPY Resources/vim/.vimrc /home/Dev/.vimrc
RUN vim +'PlugInstall --sync' +qa

# Copy and execute configuration scripts
RUN sudo mkdir -p /etc/fish/conf.d
RUN sudo mkdir -p /opt/container-scripts

ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8

COPY Resources/init.sh /opt/container-scripts/init.sh
COPY Resources/logging.sh /opt/container-scripts/logging.sh
COPY Resources/fish-starship.fish /etc/fish/conf.d/starship.fish
COPY Resources/starship.toml /etc/starship/starship.toml

RUN sudo chmod +x /opt/container-scripts/init.sh

# Configure the entrypoint
WORKDIR /workspace
ENTRYPOINT ["/usr/bin/fish", "-lc", "/opt/container-scripts/init.sh; exec fish"]
9 changes: 9 additions & 0 deletions docker/Resources/fish-starship.fish
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
if status --is-interactive
starship init fish | source
end

set -gx STARSHIP_LOG error
set -gx EDITOR nvim

set -gx LANG C.UTF-8
set -gx LC_ALL C.UTF-8
38 changes: 38 additions & 0 deletions docker/Resources/init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/usr/bin/env bash

set -e

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
source "$SCRIPT_DIR/logging.sh"

section "Running container initialization.."

if [[ -n "${GIT_USER_NAME:-}" ]]; then
git config --global user.name "$GIT_USER_NAME"
fi

if [[ -n "${GIT_USER_EMAIL:-}" ]]; then
git config --global user.email "$GIT_USER_EMAIL"
fi

git config --global credential.helper 'cache --timeout=36000'

section "Git config inside container:"
log "User name: $(git config --global --get user.name || "(user.name not set)")"
log "User email: $(git config --global --get user.email || "(user.email not set)")"

section "Searching for CMock forked repository"

CMOCK_REPO="/workspace/CMock"
CMOCK_REFERENCE="/opt/CMock"

if [[ ! -d "$CMOCK_REPO/.git" ]]; then
log "CMock repository not found in workspace. Seeding CMock into workspace volume"
cp -a "$CMOCK_REFERENCE" "$CMOCK_REPO"
cd $CMOCK_REPO && git remote set-url origin git@github.com:$GIT_USER_NAME/CMock.git
success "CMock seeded successfully"
else
success "CMock repository found in workspace"
fi

echo;
49 changes: 49 additions & 0 deletions docker/Resources/logging.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/env bash

[[ -n "${__LOGGING_SH_LOADED:-}" ]] && return
__LOGGING_SH_LOADED=1

set -o pipefail

if [[ -t 1 ]]; then
RED='\033[0;31m'
GREEN='\033[0;92m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
MAGENTA='\033[0;35m'
LIGHT_RED='\033[0;91m'
CYAN='\033[0;36m'
BOLD='\033[1m'
DIM='\033[2m'
RESET='\033[0m'
LIGHT_CYAN='\033[0;96m'
LIGHT_YELLOW='\033[0;93m'
else
RED=''
GREEN=''
YELLOW=''
BLUE=''
MAGENTA=''
LIGHT_RED=''
CYAN=''
BOLD=''
DIM=''
RESET=''
LIGHT_CYAN=''
LIGHT_YELL0W=''
fi

section() { echo -e "${BOLD}${LIGHT_RED} ==> ${RESET}$*"; }
log() { echo -e "${LIGHT_CYAN} [\u2139]${RESET} $*"; }
success() { echo -e "${LIGHT_CYAN} [\u2714]${RESET} $*\n"; }
warn() { echo -e "${YELLOW} [\u26A0]${RESET} $*"; }
error() { echo -e "${RED} [\u2716]${RESET} $*" >&2; }

run() {
log "$*"
"$0"
}

if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
trap 'error "Command failed at line ${BASH_LINENO[0]}"' ERR
fi
28 changes: 28 additions & 0 deletions docker/Resources/starship.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
add_newline = true

[username]
format = " [\\u256D\\u2500$user]($style)@"
style_user = "bold red"
show_always = true

[hostname]
format = "[$hostname]($style) in "
style = "bold dimmed red"

[directory]
style = "purple"
truncate_to_repo = true

[git_branch]
style = "bold cyan"

[git_status]
style = "white"

[cmd_duration]
format = " took [$duration]($style)"

[character]
success_symbol = " [\\u2570\\u2500\\u03BB](bold red)"
error_symbol = " [\\u0D7](bold red)"
use_symbol_for_status = true
4 changes: 4 additions & 0 deletions docker/Resources/vim/.vimrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source ~/.vim/plugins.vim
source ~/.vim/ui.vim
source ~/.vim/mappings.vim
source ~/.vim/lsp.vim
12 changes: 12 additions & 0 deletions docker/Resources/vim/lsp.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
if executable('clangd')
au User lsp_setup call lsp#register_server({
\ 'name': 'clangd'
\ 'cmd': {server_info->['clangd']},
\ 'whitelist': ['c', 'cpp'],
\ })
endif

nnoremap gd :LspDefinition<CR>
nnoremap gr :LspReferences<CR>
nnoremap gi :LspImplementation<CR>
nnoremap K :LspHover<CR>
6 changes: 6 additions & 0 deletions docker/Resources/vim/mappings.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
nnoremap <C-p> :Files<CR>
nnoremap <C-b> :Buffers<CR>

if executable($SHELL)
nnoremap <leader>t :vsplit | terminal fish<CR>
endif
13 changes: 13 additions & 0 deletions docker/Resources/vim/plugins.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
call plug#begin('/home/Dev/.vim/plugged')

" LSP
Plug 'prabirshrestha/vim-lsp'
Plug 'mattn/vim-lsp-settings'

" Fuzzy finder
Plug 'junegunn/fzf.vim'

" Language support
Plug 'sheerun/vim-polyglot'

call plug#end()
14 changes: 14 additions & 0 deletions docker/Resources/vim/ui.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
set number
set relativenumber
set colorcolumn=120
set signcolumn=yes
set cursorline

syntax on
set background=dark

if has("termguicolors")
set termguicolors
endif

hi Normal ctermbg=NONE guibg=NONE
18 changes: 18 additions & 0 deletions docker/attach.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
set -e

IMAGE_NAME="cmock-dev-arch"
CONTAINER_WORKDIR="/workspace"

export MSYS_NO_PATHCONV=1

CONTAINER_ID=$(docker ps --filter "ancestor=$IMAGE_NAME" --format "{{.ID}}" | head -n 1)

if [ -z "$CONTAINER_ID" ]; then
error "No running container found for image '$IMAGE_NAME';"
exit 1
fi

success "Attaching to container $CONTAINER_ID..."

docker exec -it -w "$CONTAINER_WORKDIR" "$CONTAINER_ID" fish
40 changes: 40 additions & 0 deletions docker/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#! /usr/bin/env bash
set -e

IMAGE_NAME="cmock-dev-arch"
VOLUME_NAME="cmock-dev-workspace"
CONTAINER_WORKDIR="/workspace"

export MSYS_NO_PATHCONV=1

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
source "$SCRIPT_DIR/Resources/logging.sh"

if [[ ! -f "$SCRIPT_DIR/.env" ]]; then
error "No .env file present. Please create it and set GIT_USER_NAME and GIT_USER_EMAIL before proceeding"
exit 1
fi

SSH_KEYS=()

if [[ -f ${HOME}/.ssh/id_ed25519 ]]; then
SSH_KEYS+=("-v" "${HOME}/.ssh/id_ed25519:/home/Dev/.ssh/id_ed25519:ro")
SSH_KEYS+=("-v" "${HOME}/.ssh/id_ed25519.pub:/home/Dev/.ssh/id_ed25519.pub:ro")
fi

if [[ -f ${HOME}/.ssh/id_rsa ]]; then
SSH_KEYS+=("-v" "${HOME}/.ssh/id_rsa:/home/Dev/.ssh/id_rsa:ro")
SSH_KEYS+=("-v" "${HOME}/.ssh/id_rsa.pub:/home/Dev/.ssh/id_rsa.pub:ro")
fi

OS_TYPE="$(uname -s)"

DOCKER_RUN_ARGS=(
-it
--rm
-v "${VOLUME_NAME}:${CONTAINER_WORKDIR}"
-w "${CONTAINER_WORKDIR}"
${SSH_KEYS[@]}
)

docker run --env-file .env ${DOCKER_RUN_ARGS[@]} "$IMAGE_NAME"
Loading