diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 000000000000..ddc6dccc442e --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,82 @@ +# Use Debian Trixie (Debian 13) as the base image for development +FROM mcr.microsoft.com/devcontainers/base:debian-13 + +# Install system dependencies +RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ + && apt-get -y install --no-install-recommends \ + build-essential \ + pkg-config \ + m4 \ + unzip \ + curl \ + git \ + python3 \ + python3-pip \ + pipenv \ + python3-venv \ + libdw-dev \ + libunwind-dev \ + autoconf \ + libtool \ + wget \ + zlib1g-dev \ + libgmp-dev \ + patch \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + +# Install Node.js (needed for tree-sitter) +RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ + && apt-get install -y nodejs + +# Build PCRE 8.45 from source (Debian Trixie only has PCRE2) +RUN wget https://sourceforge.net/projects/pcre/files/pcre/8.45/pcre-8.45.tar.gz/download -O pcre-8.45.tar.gz \ + && tar -xzf pcre-8.45.tar.gz \ + && cd pcre-8.45 \ + && ./configure --prefix=/usr/local --enable-utf --enable-unicode-properties \ + && make -j$(nproc) \ + && make install \ + && cd .. \ + && rm -rf pcre-8.45 pcre-8.45.tar.gz + +# Build libev 4.33 from source +RUN wget http://dist.schmorp.de/libev/libev-4.33.tar.gz \ + && tar -xzf libev-4.33.tar.gz \ + && cd libev-4.33 \ + && ./configure --prefix=/usr/local \ + && make -j$(nproc) \ + && make install \ + && cd .. \ + && rm -rf libev-4.33 libev-4.33.tar.gz + +# Install Opam +RUN wget https://github.com/ocaml/opam/releases/download/2.3.0/opam-2.3.0-x86_64-linux -O /usr/local/bin/opam \ + && chmod +x /usr/local/bin/opam + +# Switch to the vscode user for remaining setup +USER vscode +WORKDIR /home/vscode + +# Initialize Opam and install OCaml 5.3.0 (semgrep's requirement) +RUN opam init --disabled-sandboxing --auto-setup --yes \ + && opam switch create 5.3.0 --yes \ + && eval $(opam env) + +# Pre-install some common OCaml dependencies to speed up the first build +RUN eval $(opam env) && opam install -y \ + dune \ + ocamlfind \ + menhir \ + atdgen \ + yaml \ + pcre \ + lwt \ + ocaml-migrate-parsetree \ + ppx_deriving \ + && opam clean + +# Set environment variables +ENV PATH="/home/vscode/.opam/5.3.0/bin:${PATH}" +ENV OCAML_TOPLEVEL_PATH="/home/vscode/.opam/5.3.0/lib/toplevel" + +# Default command to bash +CMD ["/bin/bash"] diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000000..34052a40bd83 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,34 @@ +{ + "name": "Semgrep Development", + "build": { + "dockerfile": "Dockerfile", + "context": ".." + }, + "customizations": { + "vscode": { + "extensions": [ + "ocamllabs.ocaml-platform", + "ms-python.python", + "ms-python.pipenv", + "dbaeumer.vscode-eslint" + ] + }, + "codespaces": { + "repositories": { + "NuGuardAI/semgrep": { + "permissions": { + "contents": "write", + "pull_requests": "write", + "metadata": "read" + } + } + } + } + }, + "containerEnv": { + "OPAMROOT": "/home/vscode/.opam" + }, + "runArgs": ["--env-file", ".devcontainer/.env"], + "remoteUser": "vscode", + "postCreateCommand": "bash .devcontainer/postCreate.sh" +} diff --git a/.devcontainer/postCreate.sh b/.devcontainer/postCreate.sh new file mode 100755 index 000000000000..784ec3013d0f --- /dev/null +++ b/.devcontainer/postCreate.sh @@ -0,0 +1,30 @@ +#!/bin/bash +set -e + +echo "Updating submodules..." +git submodule update --init --recursive + +echo "Setting up symlinks..." +./scripts/make-symlinks + +echo "Configuring Opam environment..." +eval $(opam env) + +echo "Configuring GitHub access..." +if [ -n "$GITHUB_TOKEN" ]; then + echo "Logging into GitHub CLI..." + echo "$GITHUB_TOKEN" | gh auth login --with-token + # Ensure git uses the token for these specific remotes if they exist + echo "Updating remote URLs..." + git remote set-url origin https://rangoel-nu:$GITHUB_TOKEN@github.com/NuGuardAI/semgrep.git || true +fi + +echo "Installing Semgrep dependencies..." +# We use --no-depexts because we manually installed PCRE and libev via Dockerfile +# to work around Debian Trixie availability issues. +make install-deps-for-semgrep-core OPAM_FLAGS="--no-depexts" + +echo "Installing Python dependencies for CLI..." +cd cli && pipenv install --dev + +echo "Setup complete! You can now run 'make core' to build semgrep-core." diff --git a/.gitignore b/.gitignore index 874d99874671..68d930259307 100644 --- a/.gitignore +++ b/.gitignore @@ -220,3 +220,4 @@ result .direnv # Personal symlink to semgrep-proprietary used by 'make pro' /semgrep-proprietary +.devcontainer/.env diff --git a/Makefile b/Makefile index 0a789b0b179c..dacd3021314c 100644 --- a/Makefile +++ b/Makefile @@ -281,8 +281,8 @@ install-opam-deps: pin-ocaml-fork$(OPTIONS) # we want to install our forked OCaml compiler, however this contradicts # the default 5.3.0 invariant of `ocaml-base-compiler = 5.3.0`. # --update-invariant does just that - OPAMSOLVERTIMEOUT=1500 LWT_DISCOVER_ARGUMENTS="--use-libev true" LIBRARY_PATH="$(HOMEBREW_PREFIX)/lib:$(LIBRARY_PATH)" opam install --update-invariant --confirm-level=unsafe-yes -y --depext-only $(REQUIRED_DEPS) - OPAMSOLVERTIMEOUT=1500 LWT_DISCOVER_ARGUMENTS="--use-libev true" LIBRARY_PATH="$(HOMEBREW_PREFIX)/lib:$(LIBRARY_PATH)" opam install --update-invariant --confirm-level=unsafe-yes -y --deps-only $(REQUIRED_DEPS) + OPAMSOLVERTIMEOUT=1500 LWT_DISCOVER_ARGUMENTS="--use-libev true" LIBRARY_PATH="$(HOMEBREW_PREFIX)/lib:$(LIBRARY_PATH)" opam install --update-invariant --confirm-level=unsafe-yes -y --no-depexts $(REQUIRED_DEPS) + OPAMSOLVERTIMEOUT=1500 LWT_DISCOVER_ARGUMENTS="--use-libev true" LIBRARY_PATH="$(HOMEBREW_PREFIX)/lib:$(LIBRARY_PATH)" opam install --update-invariant --confirm-level=unsafe-yes -y --no-depexts --deps-only $(REQUIRED_DEPS) # Validate that after installing deps the pinned compiler hasn't changed ./scripts/validate-compiler-sha.sh