Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Add dev container configuration #12306

Draft
wants to merge 66 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
edd8c9f
Add dev container configuration
hoechenberger Dec 18, 2023
54b159b
Change VNC password to "mne"
hoechenberger Dec 20, 2023
7d5c6a2
Fix bash support
hoechenberger Dec 20, 2023
533db90
Don't install git from PPA [ci skip]
hoechenberger Dec 20, 2023
88fb767
Git is actually already included in the base image, no need to add itโ€ฆ
hoechenberger Dec 21, 2023
c2ef194
Add more comments
hoechenberger Dec 21, 2023
4e7d48f
Use custom username
hoechenberger Dec 22, 2023
c9fb83a
Add git and pip zsh plugins
hoechenberger Dec 22, 2023
1d475dc
Merge branch 'main' into devcontainer
hoechenberger Dec 22, 2023
7732c1b
Better comments [ci skip]
hoechenberger Dec 22, 2023
c2da3f2
Add comment [ci skip]
hoechenberger Dec 22, 2023
42714c8
Simplify formatting rules and disbale format-on-type
hoechenberger Jan 17, 2024
f758f91
Add git blame ignore revs
hoechenberger Jan 17, 2024
c2ce81f
Merge branch 'main' of https://github.com/mne-tools/mne-python into dโ€ฆ
hoechenberger May 25, 2024
865484b
Merge branch 'main' into devcontainer
hoechenberger May 25, 2024
5b90440
Merge branch 'devcontainer' of https://github.com/hoechenberger/mne-pโ€ฆ
hoechenberger May 25, 2024
7f64bae
Iterate
hoechenberger May 27, 2024
78628b6
Update .gitignore
hoechenberger May 27, 2024
5727408
Create MNE data dir on the host if it doesn't exist
hoechenberger May 27, 2024
ae7afc8
Fix image spec
hoechenberger May 27, 2024
831fcfa
Add git settings
hoechenberger May 27, 2024
b736ab4
Use ruff from Python env
hoechenberger May 27, 2024
a911699
Reorder
hoechenberger May 27, 2024
436fa77
Mount host's MNE data dir
hoechenberger May 27, 2024
f74476c
Formatting
hoechenberger May 27, 2024
7fb00e4
Reorganiz
hoechenberger May 27, 2024
35d0ff2
pre-commit installation
hoechenberger May 27, 2024
77d33b8
pre-commit setup and passwordless VNC
hoechenberger May 27, 2024
b963171
We need VTK from conda-forge as well
hoechenberger May 27, 2024
90859fe
PySide6
hoechenberger May 27, 2024
09bba5c
Re-order and remove Mamba
hoechenberger May 28, 2024
92ab0e6
Newest desktop-lite includes my patches for passwordless login
hoechenberger May 30, 2024
e77ebb6
Install psutil and cftime from conda-forge (no wheels available)
hoechenberger May 30, 2024
7f23b05
No wheel yet for OpenMEEG
hoechenberger May 30, 2024
27f942d
Merge branch 'main' of https://github.com/mne-tools/mne-python into dโ€ฆ
hoechenberger May 30, 2024
74e3a1f
stashMore logging
hoechenberger May 30, 2024
ed0738a
Disable Ruff's Rust-based language server
hoechenberger May 30, 2024
91ae09e
Remove Resource Monitor extension
hoechenberger May 31, 2024
053f349
Add tasks and debug configuration
hoechenberger May 31, 2024
6c956e7
Linebreak
hoechenberger May 31, 2024
010f77e
Install nitime from conda, too
hoechenberger May 31, 2024
c8c190f
Download pre-commit environments when setting up hooks
hoechenberger May 31, 2024
be4b239
nitime is not on conda-forge
hoechenberger May 31, 2024
045dbeb
Better xmessage
hoechenberger May 31, 2024
f661923
Harmonize scripts
hoechenberger May 31, 2024
34e508c
Better task handling, install openmeeg from PyPI
hoechenberger Jun 3, 2024
17bfca4
Merge branch 'main' of https://github.com/mne-tools/mne-python into dโ€ฆ
hoechenberger Jun 5, 2024
a92aebf
Phrasing
hoechenberger Jun 6, 2024
b945edc
Use uv for installation
hoechenberger Jun 6, 2024
0d90a77
Merge branch 'main' of https://github.com/mne-tools/mne-python into dโ€ฆ
hoechenberger Jun 6, 2024
2e96695
Add spaces
hoechenberger Jun 6, 2024
0b7bd34
Merge branch 'main' into devcontainer
hoechenberger Jun 7, 2024
d317c0f
Keep terminals hidden and auto-close; this should remove any disturbaโ€ฆ
hoechenberger Jun 8, 2024
9043f31
Merge branch 'main' of https://github.com/mne-tools/mne-python into dโ€ฆ
hoechenberger Jun 8, 2024
0bee949
Some more details
hoechenberger Jun 9, 2024
1c75ac8
Insteall deps for doc building
hoechenberger Jun 9, 2024
d8f584d
Update comment
hoechenberger Jun 9, 2024
69e2c78
Enable extension signature check again
hoechenberger Jun 10, 2024
87e307f
Merge branch 'main' of https://github.com/mne-tools/mne-python into dโ€ฆ
hoechenberger Jun 10, 2024
9c7fd8c
Merge branch 'main' of https://github.com/mne-tools/mne-python into dโ€ฆ
hoechenberger Jun 11, 2024
4727fd8
Add empty problemMatchers
hoechenberger Jun 11, 2024
14ddd4c
Run pipx install uv
hoechenberger Jun 11, 2024
405b9a6
psutil now available for aarch64 from PyPI
hoechenberger Jun 21, 2024
98aa7ed
Merge branch 'main' of https://github.com/mne-tools/mne-python into dโ€ฆ
hoechenberger Jun 21, 2024
2ac5c68
Merge branch 'main' of https://github.com/mne-tools/mne-python into dโ€ฆ
hoechenberger Jun 23, 2024
3578193
We won't need Docker access inside the container
hoechenberger Jun 23, 2024
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
44 changes: 44 additions & 0 deletions .devcontainer/Welcome.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# ๐Ÿ‘‹ Welcome to the MNE-Python Dev Container!

It's so great to see you! ๐Ÿคฉ

This appears to be the first time you're starting up the container,
or you've restarted it after uninstalling MNE-Python.

In any case, **we're currently running the MNE-Python installation
procedure.** You can view progress by opening the terminal window
with the the spinning icon (or exclamation mark, in some cases!) in the bottom-right of
your screen!

Once installation is finished, that terminal window will close and your browser will
open to connect you to a VNC desktop. This is where interactive plots will appear.

Enjoy, have a great day, and: **Happy hacking!** ๐Ÿš€๐Ÿš€๐Ÿš€

### Some technical background

The Dev Container is based on Debian 12 ("bookworm") GNU/Linux.

Python is installed in a `conda` environment (named `base`), together with a few
dependencies that are currently not available from PyPI for all platforms:

- `h5py`
- `psutil`
- `pyside6`
- `vtk`

Everything else is pulled and installed from PyPI through `uv`. Specifically, the command
that is run to install MNE-Python is:

```shell
pipx run uv pip install -e ".[full-pyside6,dev,test_extra]
```
It is totally acceptable and safe to install or update dependencies via `pip` if you
wish.

All `git` pre-commit hooks are automatically installed.

The noVNC server (for connecting to the VNC desktop via a browser) is exposed on TCP
port 6080.

The host's `mne_data` directory is mounted at `~/mne_data` inside the container.
162 changes: 162 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
{
"name": "mne-dev",
// More info on the Debian base image we're using here:
// https://github.com/devcontainers/images/tree/main/src/base-debian
// All features listed in the repository's devcontainer configuration are actually
// built into the image.
"image": "mcr.microsoft.com/devcontainers/base:debian-12",
"containerEnv": {
"PYTHONNOUSERSITE": "true", // Make Python ignore the user's site-packages folder if it exists
"XDG_RUNTIME_DIR": "/home/mne-user/.cache/xdgr", // For VNC
"RUNNING_IN_DEV_CONTAINER": "true"
},
"features": {
// See https://containers.dev/features
// User & shell setup
"ghcr.io/devcontainers/features/common-utils:2": {
"username": "mne-user",
"configureZshAsDefaultShell": true
},
// Desktop and VNC access
"ghcr.io/devcontainers/features/desktop-lite:1": {
"password": "noPassword"
},
// Git
"ghcr.io/devcontainers/features/git:1": {
"version": "os-provided",
"ppa": "true"
hoechenberger marked this conversation as resolved.
Show resolved Hide resolved
},
// APT packages
// We need those for 3D rendering and building the docs.
"ghcr.io/rocker-org/devcontainer-features/apt-packages:1": {
"packages": "mesa-utils,libegl1,^libxcb.*-dev,libx11-xcb-dev,libglu1-mesa-dev,libxrender-dev,libxi-dev,libxkbcommon-dev,libxkbcommon-x11-dev,optipng,graphviz"
},
// Conda
"ghcr.io/mamba-org/devcontainer-features/micromamba:1": {
"channels": "conda-forge",
"packages": "conda python h5py vtk pyside6 pipx"
},
// Zsh plugins
"ghcr.io/devcontainers-contrib/features/zsh-plugins:0": {
"plugins": "git pip zsh-autosuggestions zsh-syntax-highlighting history-substring-search",
"omzPlugins": "https://github.com/zsh-users/zsh-autosuggestions https://github.com/zsh-users/zsh-syntax-highlighting"
}
},
// Configure tool-specific properties.
"customizations": {
// Configure properties specific to VS Code.
"vscode": {
"settings": {
Comment on lines +47 to +49
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like fertile ground for bikeshedding. Is there a way for the container to pick up the user's local settings? If not, then can you indicate which of these settings are truly necessary for the container to work, which are not necessary but clearly a good idea (e.g., don't restore port forwards?), and which are your preferences (perhaps "format on type" fits here)?

// Editor settings
"editor.formatOnSave": true,
"editor.formatOnSaveMode": "modificationsIfAvailable",
"editor.renderWhitespace": "trailing",
"editor.rulers": [88],
// General Python settings
"python.defaultInterpreterPath": "/opt/conda/bin/python",
"python.analysis.typeCheckingMode": "basic",
"python.testing.pytestEnabled": true,
"python.testing.pytestArgs": ["--color=yes"],
"ruff.nativeServer": false,
"ruff.importStrategy": "fromEnvironment",
"debugpy.debugJustMyCode": false,
// Python modules and scripts
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.codeActionsOnSave": {
"source.fixAll": "explicit",
"source.organizeImports": "explicit"
}
},
// Jupyter notebooks
"notebook.formatOnSave.enabled": true,
"notebook.codeActionsOnSave": {
"source.fixAll": "explicit",
"source.organizeImports": "explicit"
},
// JavaScript
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
// Git
"git.allowNoVerifyCommit": true, // Allow omitting pre-commit hooks
"git.allowForcePush": true,
// Screencast settings
"screencastMode.keyboardOverlayTimeout": 5000,
"screencastMode.mouseIndicatorSize": 50,
// Disable telemetry and experiments
"telemetry.telemetryLevel": "off",
"gitlens.telemetry.enabled": false,
"redhat.telemetry.enabled": false,
"workbench.enableExperiments": false, // Should not be necessary if telemetry is off, but let's make it explicit.
// Avoid accumulation of unused forwarded ports.
"remote.restoreForwardedPorts": false,
// Always open Markdown files in the preview (i.e., rendered); double-clicking on a line openes the editor.
"workbench.editorAssociations": {
"*.md": "vscode.markdown.preview.editor"
}
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
// Python Development
"ms-python.python",
"ms-toolsai.jupyter",
"charliermarsh.ruff",
"samuelcolvin.jinjahtml",
// MNE-Python snippets
"hoechenberger.mne-python-extension",
// JavaScript & TypeScript Development
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
// Git
"GitHub.vscode-pull-request-github",
"eamodio.gitlens",
// TOML
"tamasfe.even-better-toml",
// YAML
"redhat.vscode-yaml",
// Spell checking
"streetsidesoftware.code-spell-checker",
// Path / filename autocomplete
"ionutvmi.path-autocomplete"
]
}
},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [6080],
"portsAttributes": {
"6080": {
"label": "Web VNC"
}
},
// Set `remoteUser` to `root` to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "mne-user",
"initializeCommand": {
// These commands are run on the host.
//
// We will mount the mne_data directory from the host inside the container to avoid having
// to dowload testing and sample data on container (re)creation.
// Note: On Windows, the .ps1 suffix will be appended automatically to the script name.
"create-mne-data-dir": ".devcontainer/scripts/create-data-dir"
},
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": {
// Initialize shells to use conda and mamba
"init-conda-shell": "conda init --quiet zsh bash",
// Force pip to always install "globally": This will work in a virtual environment, but fail with the system Python, which is
// precisely what we want: prevent users from accidentally cluttering their user site-packages folder
"disable-pip-user-installs": "pip config set install.system true",
// Create XDG_RUNTIME_DIR
"create-xdg-runtime-dir": "mkdir -p -m 0700 $XDG_RUNTIME_DIR"
},
"postStartCommand": {
// These commands are run inside the container.
//
// Do all git-config-related things here, otherwise we may run into problems; see:
// https://github.com/microsoft/vscode-remote-release/issues/6810
"configure-git": "${containerWorkspaceFolder}/.devcontainer/scripts/configure-git.sh"
},
"mounts": [
"source=${localEnv:HOME}${localEnv:USERPROFILE}/mne_data,target=/home/mne-user/mne_data,type=bind"
]
}
23 changes: 23 additions & 0 deletions .devcontainer/scripts/configure-git.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash

set -ex

# Set git default branch name
git config --global init.defaultBranch main

# Work around "dubious ownership in repository" error
git config --global --add safe.directory /workspaces/*

# Use VS Code as default git editor, diff, and merge tool
git config --global core.editor 'code --wait --reuse-window'
git config --global --replace-all difftool.default-difftool.cmd 'code --wait --diff $LOCAL $REMOTE'
git config --global --replace-all diff.tool default-difftool
git config --global --replace-all mergetool.code.cmd 'code --wait --merge $REMOTE $LOCAL $BASE $MERGED'
git config --global --replace-all merge.tool code

# Show indicator for "dirty" git repositories in the shell prompt.
# This can be slow on large repositories and should be disabled in that case.
git config --global --replace-all devcontainers-theme.show-dirty 1

# Make "git blame" ignore certain commits
git config --local blame.ignoreRevsFile .git-blame-ignore-revs
21 changes: 21 additions & 0 deletions .devcontainer/scripts/create-data-dir
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env bash

set -eu

# Path to the directory you want to create
DIR=~/mne_data

# Check if the directory already exists
if [ -d "$DIR" ]; then
echo "Found existing MNE data directory: $DIR"
else
# Create the directory since it does not exist
mkdir -p "$DIR"
# Check if the directory creation was successful
if [ $? -eq 0 ]; then
echo "MNE data directory created: $DIR"
else
echo "Failed to create MNE data directory: $DIR"
exit 1
fi
fi
25 changes: 25 additions & 0 deletions .devcontainer/scripts/create-data-dir.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Get the path to the user's USERPROFILE folder
$userProfilePath = [System.Environment]::GetFolderPath("UserProfile")

# Define the path to the new directory
$newDirectoryPath = "$userProfilePath\mne_data"

# Check if the directory already exists
if (Test-Path -Path $newDirectoryPath) {
Write-Output "Found existing MNE data directory: $newDirectoryPath"
} else {
# Create the directory since it does not exist
try {
New-Item -ItemType Directory -Path $newDirectoryPath -Force
# Verify if the directory was created successfully
if (Test-Path -Path $newDirectoryPath) {
Write-Output "MNE data directory created: $newDirectoryPath"
} else {
Write-Output "Failed to create directory: $newDirectoryPath"
exit 1
}
} catch {
Write-Output "Error creating MNE data directory: $_"
exit 1
}
}
35 changes: 35 additions & 0 deletions .devcontainer/scripts/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env bash

set -eu

# Exit immediately if not running inside a Dev Container
if [ -z "${RUNNING_IN_DEV_CONTAINER+x}" ]; then
echo -e "๐Ÿ‘‹ Not running in dev container, not installing MNE-Python (dev).\n"
exit
fi

package_name="MNE-Python (dev)"
import_name="mne"

# Run the import test outside of the repository, so we don't accidentally import the
# `mne` directory from there. This is an annoyance caused by MNE-Python's not using a
# src/ layout.
orig_dir=$(pwd)
cd ~
if python -c "import $import_name" &> /dev/null; then
echo -e "โœ… $package_name is already installed.\n"
cd "${orig_dir}"
exit
else
cd "${orig_dir}"
code .devcontainer/Welcome.md
echo -e "๐Ÿ’ก $package_name is not installed. Installing now โ€ฆ\n"
pipx install uv
uv pip install -e ".[full-pyside6,dev,test_extra]"
echo -e "\nโœ… $package_name has been installed.\n"
echo -e "๐Ÿ’ก Installing pre-commit hooks โ€ฆ"
pre-commit install --install-hooks
echo -e "โœ… pre-commit hooks installed.\n"
fi

echo -e "\n๐Ÿš€ You're all set. Happy hacking!\n"
13 changes: 13 additions & 0 deletions .devcontainer/scripts/open-vnc-browser.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash

set -eu

# Exit immediately if not running inside a Dev Container
if [ -z "${RUNNING_IN_DEV_CONTAINER+x}" ]; then
echo -e "๐Ÿ‘‹ Not running in dev container, not opening web browser.\n"
exit
fi

echo -e "๐ŸŒ Opening VNC desktop in web browser โ€ฆ\n"
xdg-open 'http://localhost:6080?autoconnect=true'
echo -e "Welcome to the MNE-Python Dev Container!\nCreate a plot in VS Code and it will show up here." | xmessage -center -timeout 30 -title "Welcome to MNE-Python!" -file -
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ cover
.venv/
venv/
*.json
!/.devcontainer/**/*
!codemeta.json
.hypothesis/
.ruff_cache/
Expand Down
17 changes: 17 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Current File",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"justMyCode": false,
"jinja": true
}
]
}
36 changes: 36 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Install MNE-Python (dev)",
"type": "shell",
"command": ".devcontainer/scripts/install.sh",
"runOptions": {
"runOn": "folderOpen"
},
"presentation": {
"showReuseMessage": false,
"reveal": "silent",
"close": true
},
"problemMatcher": []
},
{
"label": "Open VNC Desktop in Browser",
"type": "shell",
"command": ".devcontainer/scripts/open-vnc-browser.sh",
"runOptions": {
"runOn": "folderOpen"
},
"dependsOn": ["Install MNE-Python (dev)"],
"presentation": {
"showReuseMessage": false,
"reveal": "silent",
"close": true
},
"problemMatcher": []
}
]
}
Loading