From 6a95b90cdf5183389276f8097a23a895e07dcae3 Mon Sep 17 00:00:00 2001
From: "Xuefeng Ding (IHEP)" <dingxf@ihep.ac.cn>
Date: Thu, 5 Dec 2024 00:04:01 +0800
Subject: [PATCH] devcontainer almost ready

---
 .devcontainer/install_zsh.sh              | 206 ++++++++++++++++++++++
 .devcontainer/root-user/Dockerfile        |  32 ++++
 .devcontainer/root-user/devcontainer.json |   7 +
 .gitignore                                |   6 +-
 .pre-commit-config.yaml                   |   1 +
 .vscode/settings.json                     |   4 +-
 pyproject.toml                            |   1 -
 requirements-dev.txt                      |   5 +
 requirements.txt                          |   3 +
 setup_dev.sh                              |  24 +++
 10 files changed, 286 insertions(+), 3 deletions(-)
 create mode 100755 .devcontainer/install_zsh.sh
 create mode 100644 .devcontainer/root-user/Dockerfile
 create mode 100644 .devcontainer/root-user/devcontainer.json
 create mode 100644 requirements-dev.txt
 create mode 100644 requirements.txt
 create mode 100755 setup_dev.sh

diff --git a/.devcontainer/install_zsh.sh b/.devcontainer/install_zsh.sh
new file mode 100755
index 0000000..dd88d0a
--- /dev/null
+++ b/.devcontainer/install_zsh.sh
@@ -0,0 +1,206 @@
+#!/usr/bin/env bash
+#-------------------------------------------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
+#-------------------------------------------------------------------------------------------------------------
+#
+# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/common.md
+# Maintainer: The VS Code and Codespaces Teams
+#
+# Syntax: ./common-debian.sh [install zsh flag] [username] [user UID] [user GID] [upgrade packages flag] [install Oh My Zsh! flag] [Add non-free packages]
+
+set -e
+
+INSTALL_ZSH="true"
+USERNAME=$(whoami)
+INSTALL_OH_MYS="true"
+
+if [ "$(id -u)" -ne 0 ]; then
+    echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
+    exit 1
+fi
+
+# Add sudo support for non-root user
+if [ "${USERNAME}" != "root" ]; then
+    echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME
+    chmod 0440 /etc/sudoers.d/$USERNAME
+fi
+
+# ** Shell customization section **
+if [ "${USERNAME}" = "root" ]; then
+    user_rc_path="/root"
+else
+    user_rc_path="/home/${USERNAME}"
+fi
+
+# .bashrc/.zshrc snippet
+rc_snippet="$(cat << 'EOF'
+
+if [ -z "${USER}" ]; then export USER=$(whoami); fi
+if [[ "${PATH}" != *"$HOME/.local/bin"* ]]; then export PATH="${PATH}:$HOME/.local/bin"; fi
+
+# Display optional first run image specific notice if configured and terminal is interactive
+if [ -t 1 ] && [[ "${TERM_PROGRAM}" = "vscode" || "${TERM_PROGRAM}" = "codespaces" ]] && [ ! -f "$HOME/.config/vscode-dev-containers/first-run-notice-already-displayed" ]; then
+    if [ -f "/usr/local/etc/vscode-dev-containers/first-run-notice.txt" ]; then
+        cat "/usr/local/etc/vscode-dev-containers/first-run-notice.txt"
+    elif [ -f "/workspaces/.codespaces/shared/first-run-notice.txt" ]; then
+        cat "/workspaces/.codespaces/shared/first-run-notice.txt"
+    fi
+    mkdir -p "$HOME/.config/vscode-dev-containers"
+    # Mark first run notice as displayed after 10s to avoid problems with fast terminal refreshes hiding it
+    ((sleep 10s; touch "$HOME/.config/vscode-dev-containers/first-run-notice-already-displayed") &)
+fi
+
+# Set the default git editor if not already set
+if [ -z "$(git config --get core.editor)" ] && [ -z "${GIT_EDITOR}" ]; then
+    if  [ "${TERM_PROGRAM}" = "vscode" ]; then
+        if [[ -n $(command -v code-insiders) &&  -z $(command -v code) ]]; then
+            export GIT_EDITOR="code-insiders --wait"
+        else
+            export GIT_EDITOR="code --wait"
+        fi
+    fi
+fi
+
+EOF
+)"
+
+# code shim, it fallbacks to code-insiders if code is not available
+cat << 'EOF' > /usr/local/bin/code
+#!/bin/sh
+
+get_in_path_except_current() {
+    which -a "$1" | grep -A1 "$0" | grep -v "$0"
+}
+
+code="$(get_in_path_except_current code)"
+
+if [ -n "$code" ]; then
+    exec "$code" "$@"
+elif [ "$(command -v code-insiders)" ]; then
+    exec code-insiders "$@"
+else
+    echo "code or code-insiders is not installed" >&2
+    exit 127
+fi
+EOF
+chmod +x /usr/local/bin/code
+
+# systemctl shim - tells people to use 'service' if systemd is not running
+cat << 'EOF' > /usr/local/bin/systemctl
+#!/bin/sh
+set -e
+if [ -d "/run/systemd/system" ]; then
+    exec /bin/systemctl "$@"
+else
+    echo '\n"systemd" is not running in this container due to its overhead.\nUse the "service" command to start services instead. e.g.: \n\nservice --status-all'
+fi
+EOF
+chmod +x /usr/local/bin/systemctl
+
+# Codespaces bash and OMZ themes - partly inspired by https://github.com/ohmyzsh/ohmyzsh/blob/master/themes/robbyrussell.zsh-theme
+codespaces_bash="$(cat \
+<<'EOF'
+
+# Codespaces bash prompt theme
+__bash_prompt() {
+    local userpart='`export XIT=$? \
+        && [ ! -z "${GITHUB_USER}" ] && echo -n "\[\033[0;32m\]@${GITHUB_USER} " || echo -n "\[\033[0;32m\]\u " \
+        && [ "$XIT" -ne "0" ] && echo -n "\[\033[1;31m\]鉃�" || echo -n "\[\033[0m\]鉃�"`'
+    local gitbranch='`\
+        if [ "$(git config --get codespaces-theme.hide-status 2>/dev/null)" != 1 ]; then \
+            export BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null || git rev-parse --short HEAD 2>/dev/null); \
+            if [ "${BRANCH}" != "" ]; then \
+                echo -n "\[\033[0;36m\](\[\033[1;31m\]${BRANCH}" \
+                && if git ls-files --error-unmatch -m --directory --no-empty-directory -o --exclude-standard ":/*" > /dev/null 2>&1; then \
+                        echo -n " \[\033[1;33m\]鉁�"; \
+                fi \
+                && echo -n "\[\033[0;36m\]) "; \
+            fi; \
+        fi`'
+    local lightblue='\[\033[1;34m\]'
+    local removecolor='\[\033[0m\]'
+    PS1="${userpart} ${lightblue}\w ${gitbranch}${removecolor}\$ "
+    unset -f __bash_prompt
+}
+__bash_prompt
+
+EOF
+)"
+
+codespaces_zsh="$(cat \
+<<'EOF'
+# Codespaces zsh prompt theme
+__zsh_prompt() {
+    local prompt_username
+    if [ ! -z "${GITHUB_USER}" ]; then
+        prompt_username="@${GITHUB_USER}"
+    else
+        prompt_username="%n"
+    fi
+    PROMPT="%{$fg[green]%}${prompt_username} %(?:%{$reset_color%}鉃� :%{$fg_bold[red]%}鉃� )" # User/exit code arrow
+    PROMPT+='%{$fg_bold[blue]%}%(5~|%-1~/鈥�/%3~|%4~)%{$reset_color%} ' # cwd
+    PROMPT+='$([ "$(git config --get codespaces-theme.hide-status 2>/dev/null)" != 1 ] && git_prompt_info)' # Git status
+    PROMPT+='%{$fg[white]%}$ %{$reset_color%}'
+    unset -f __zsh_prompt
+}
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[cyan]%}(%{$fg_bold[red]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
+ZSH_THEME_GIT_PROMPT_DIRTY=" %{$fg_bold[yellow]%}鉁�%{$fg_bold[cyan]%})"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg_bold[cyan]%})"
+__zsh_prompt
+
+EOF
+)"
+
+# Add RC snippet and custom bash prompt
+if [ "${RC_SNIPPET_ALREADY_ADDED}" != "true" ]; then
+    echo "${rc_snippet}" >> /etc/bash.bashrc
+    echo "${codespaces_bash}" >> "${user_rc_path}/.bashrc"
+    echo 'export PROMPT_DIRTRIM=4' >> "${user_rc_path}/.bashrc"
+    if [ "${USERNAME}" != "root" ]; then
+        echo "${codespaces_bash}" >> "/root/.bashrc"
+        echo 'export PROMPT_DIRTRIM=4' >> "/root/.bashrc"
+    fi
+    chown ${USERNAME}:${group_name} "${user_rc_path}/.bashrc"
+    RC_SNIPPET_ALREADY_ADDED="true"
+fi
+
+# Optionally install and configure zsh and Oh My Zsh!
+if [ "${INSTALL_ZSH}" = "true" ]; then
+    if ! type zsh > /dev/null 2>&1; then
+        dnf install -y zsh
+    fi
+
+    # Adapted, simplified inline Oh My Zsh! install steps that adds, defaults to a codespaces theme.
+    # See https://github.com/ohmyzsh/ohmyzsh/blob/master/tools/install.sh for official script.
+    oh_my_install_dir="${user_rc_path}/.oh-my-zsh"
+    if [ ! -d "${oh_my_install_dir}" ] && [ "${INSTALL_OH_MYS}" = "true" ]; then
+        template_path="${oh_my_install_dir}/templates/zshrc.zsh-template"
+        user_rc_file="${user_rc_path}/.zshrc"
+        umask g-w,o-w
+        mkdir -p ${oh_my_install_dir}
+        git clone --depth=1 \
+            -c core.eol=lf \
+            -c core.autocrlf=false \
+            -c fsck.zeroPaddedFilemode=ignore \
+            -c fetch.fsck.zeroPaddedFilemode=ignore \
+            -c receive.fsck.zeroPaddedFilemode=ignore \
+            "https://mirrors.tuna.tsinghua.edu.cn/git/ohmyzsh.git" "${oh_my_install_dir}" 2>&1
+        echo -e "$(cat "${template_path}")\nDISABLE_AUTO_UPDATE=true\nDISABLE_UPDATE_PROMPT=true" > ${user_rc_file}
+        sed -i -e 's/ZSH_THEME=.*/ZSH_THEME="codespaces"/g' ${user_rc_file}
+
+        mkdir -p ${oh_my_install_dir}/custom/themes
+        echo "${codespaces_zsh}" > "${oh_my_install_dir}/custom/themes/codespaces.zsh-theme"
+        # Shrink git while still enabling updates
+        cd "${oh_my_install_dir}"
+        git repack -a -d -f --depth=1 --window=1
+        # Copy to non-root user if one is specified
+        if [ "${USERNAME}" != "root" ]; then
+            cp -rf "${user_rc_file}" "${oh_my_install_dir}" /root
+            chown -R ${USERNAME}:${group_name} "${user_rc_path}"
+        fi
+    fi
+fi
+
+echo "Done!"
diff --git a/.devcontainer/root-user/Dockerfile b/.devcontainer/root-user/Dockerfile
new file mode 100644
index 0000000..90088e2
--- /dev/null
+++ b/.devcontainer/root-user/Dockerfile
@@ -0,0 +1,32 @@
+# Use AlmaLinux 9 base image
+FROM almalinux:9
+
+# /vscode is the magic folder
+WORKDIR /vscode
+
+RUN dnf --best --assumeyes update \
+    && dnf -y install \
+    python3.11 \
+    python3.11-pip \
+    gcc \
+    make \
+    cmake \
+    git \
+    && dnf clean all
+
+RUN python3.11 -m venv /vscode/.venv
+
+COPY requirements.txt /vscode/requirements.txt
+COPY requirements-dev.txt /vscode/requirements-dev.txt
+COPY .devcontainer/install_zsh.sh /vscode/install_zsh.sh
+
+RUN /vscode/install_zsh.sh
+
+RUN echo 'source /vscode/.venv/bin/activate' > ~/.bash_profile \
+    && source /vscode/.venv/bin/activate \
+    && pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple \
+    && pip install --upgrade pip \
+    && pip install -r requirements-dev.txt
+
+
+RUN rm -rf /vscode/requirements.txt /vscode/requirements-dev.txt /vscode/install_zsh.sh
diff --git a/.devcontainer/root-user/devcontainer.json b/.devcontainer/root-user/devcontainer.json
new file mode 100644
index 0000000..7fef058
--- /dev/null
+++ b/.devcontainer/root-user/devcontainer.json
@@ -0,0 +1,7 @@
+{
+  "name": "AlmaLinux 9",
+  "build": {
+    "dockerfile": "./Dockerfile",
+    "context": "../.."
+  }
+}
diff --git a/.gitignore b/.gitignore
index ac2521c..b807799 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,9 @@
 __pycache__/
 build/
-.cache/
+.*cache/
 .venv/
 .coverage
+
+# dev container related
+.dotnet/
+.vscode-server/
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 233f5b2..63d6f3b 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -48,6 +48,7 @@ repos:
     rev: "v1.13.0"
     hooks:
       - id: mypy
+        args: ["--explicit-package-bases"]
 
   # - repo: https://github.com/PyCQA/pylint
   #   rev: "v3.3.1"
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 86d7a47..31a1f06 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -52,5 +52,7 @@
   "python.analysis.inlayHints.pytestParameters": true,
   "python.analysis.inlayHints.variableTypes": true,
   "python.analysis.typeCheckingMode": "strict",
-  "python.analysis.extraPaths": ["${workspaceFolder}/python"]
+  "python.analysis.extraPaths": ["${workspaceFolder}/python"],
+  // "docker.host": "unix:///run/user/1000/podman/podman.sock"
+  "dev.containers.dockerPath": "podman"
 }
diff --git a/pyproject.toml b/pyproject.toml
index 1745f2a..af70302 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -51,7 +51,6 @@ warn_unreachable = true
 enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
 disable_error_code = []
 disallow_untyped_decorators = false
-mypy_path = ["python/myproj/simulation"]
 
 [tool.ruff.lint]
 select = [
diff --git a/requirements-dev.txt b/requirements-dev.txt
new file mode 100644
index 0000000..f7d4e4a
--- /dev/null
+++ b/requirements-dev.txt
@@ -0,0 +1,5 @@
+-r requirements.txt
+nox
+pre-commit
+pytest
+pytest-cov
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..9964744
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,3 @@
+pip>=23
+pybind11
+scikit-build-core[pyproject]
diff --git a/setup_dev.sh b/setup_dev.sh
new file mode 100755
index 0000000..e49402d
--- /dev/null
+++ b/setup_dev.sh
@@ -0,0 +1,24 @@
+#############################################################################
+#  Author: Xuefeng Ding <dingxf@ihep.ac.cn> @ IHEP-CAS
+#
+#  Project: cpp-python-small
+#  Date: 2024 December 2nd
+#  Version: v1.0
+#  Description:
+#    Boilerplate for c++-python project.
+#    Can be installed with `pip install .`
+#
+#  Maintainer:
+#    Xuefeng Ding <dingxf@ihep.ac.cn>
+#
+#  All rights reserved. 2024 copyrighted.
+#############################################################################
+#!/bin/bash
+
+python3 -m venv .venv
+PIP=".venv/bin/pip"
+library_output_dir="$PWD/python/myproj/simulation/_csrc"
+$PIP install -r requirements-dev.txt
+$PIP install --no-build-isolation --check-build-dependencies -ve . \
+   -Ccmake.define.CMAKE_EXPORT_COMPILE_COMMANDS=1 \
+   -Cbuild-dir=build
-- 
GitLab