diff --git a/.envrc b/.envrc new file mode 100644 index 000000000..6bc8abe38 --- /dev/null +++ b/.envrc @@ -0,0 +1,11 @@ +# Hyperloop H10 Development Environment +# +# This file is used by direnv to automatically load the development environment +# when you enter this directory. +# +# To use: +# 1. Install direnv: https://direnv.net/ +# 2. Run: direnv allow +# +# For pure shell (default): +use nix diff --git a/.starship.toml b/.starship.toml new file mode 100644 index 000000000..74b0b59b7 --- /dev/null +++ b/.starship.toml @@ -0,0 +1,90 @@ +# Hyperloop H10 Starship Prompt Configuration + +format = """ +[┌─](bold white) \ +$username\ +$hostname\ +$directory\ +$git_branch\ +$git_status\ +$golang\ +$nodejs\ +$python\ +$env_var\ +$custom\ +$cmd_duration\ +$line_break\ +[└─](bold white) $character""" + +[directory] +truncation_length = 3 +truncate_to_repo = true +style = "bold cyan" +read_only = " 🔒" + +[character] +success_symbol = "[🚄❯](bold green)" +error_symbol = "[🚄❯](bold red)" +vicmd_symbol = "[🚄❮](bold green)" + +[git_branch] +symbol = " " +style = "bold purple" +format = "on [$symbol$branch]($style) " + +[git_status] +style = "bold red" +format = '([\[$all_status$ahead_behind\]]($style) )' +conflicted = "⚔️ " +ahead = "⇡${count}" +behind = "⇣${count}" +diverged = "⇕⇡${ahead_count}⇣${behind_count}" +untracked = "?${count}" +stashed = "📦${count}" +modified = "!${count}" +staged = "+${count}" +renamed = "»${count}" +deleted = "✘${count}" + +[golang] +symbol = " " +style = "bold blue" +format = "via [$symbol($version )]($style)" + +[nodejs] +symbol = " " +style = "bold green" +format = "via [$symbol($version )]($style)" + +[python] +symbol = " " +style = "bold yellow" +format = "via [$symbol($version )]($style)" + +[cmd_duration] +min_time = 3_000 +format = "took [$duration]($style) " +style = "bold yellow" + +[env_var.NIX_SHELL] +symbol = "❄️ " +style = "bold blue" +format = "[$symbol]($style)" + +[custom.hyperloop] +command = "echo 🚄" +when = """ test "$REPO_ROOT" != "" """ +format = "[$output]($style) " +style = "bold" + +[hostname] +ssh_only = false +format = "on [$hostname](bold red) " +disabled = false + +[username] +style_user = "white bold" +style_root = "red bold" +format = "[$user]($style) " +disabled = false +show_always = false \ No newline at end of file diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 000000000..cec7f2738 --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,129 @@ +# Development Setup + +This guide provides multiple ways to set up your development environment for the Hyperloop H10 project. + +## Quick Start (Recommended) + +### Option 1: Using the Development Script (Standard) + +```bash +# Install dependencies and setup +./scripts/dev.sh setup + +# Run individual services +./scripts/dev.sh backend # Run backend server +./scripts/dev.sh ethernet # Run ethernet-view +./scripts/dev.sh control # Run control-station +./scripts/dev.sh packet # Run packet-sender + +# Run all services in tmux +./scripts/dev.sh all +``` + +### Option 2: Using Docker Compose + +```bash +# Run all services +docker-compose -f docker-compose.dev.yml up + +# Run specific service +docker-compose -f docker-compose.dev.yml up backend +``` + +### Option 3: Manual Setup + +```bash +# 1. Build common-front first (required) +cd common-front +npm install +npm run build + +# 2. Install frontend dependencies +cd ../ethernet-view +npm install + +cd ../control-station +npm install + +# 3. Run services +cd backend/cmd && go run . # Terminal 1 +cd ethernet-view && npm run dev # Terminal 2 +cd control-station && npm run dev # Terminal 3 +cd packet-sender && go run . # Terminal 4 +``` + +### Option 4: Using Nix (Advanced) + +For developers who prefer Nix for reproducible environments: + +```bash +# Pure shell with Fish +nix-shell + +# Or with your existing shell config +nix-shell -A impure +``` + +This provides a fully reproducible development environment with all dependencies. + +## Prerequisites + +- Go 1.21+ +- Node.js 18+ +- npm +- libpcap (for packet capture) + - macOS: `brew install libpcap` + - Ubuntu: `sudo apt-get install libpcap-dev` + - Windows: Install WinPcap or Npcap + +## Service Ports + +- Backend: 8080 +- Control Station: 5173 +- Ethernet View: 5174 + +## Common Tasks + +### Run Tests +```bash +./scripts/dev.sh test +# or manually: +cd backend && go test -v ./... +``` + +### Build All Components +```bash +make all +``` + +### Update Dependencies +```bash +# Go dependencies +cd backend && go mod tidy + +# Node dependencies +cd common-front && npm update +cd control-station && npm update +cd ethernet-view && npm update +``` + +## Troubleshooting + +1. **Permission denied on macOS/Linux for packet capture**: + ```bash + sudo setcap cap_net_raw+ep $(which go) + ``` + +2. **Common-front not found errors**: + Make sure to build common-front first: + ```bash + cd common-front && npm install && npm run build + ``` + +3. **Port already in use**: + Check and kill processes using the ports: + ```bash + lsof -i :8080 # backend + lsof -i :5173 # control-station + lsof -i :5174 # ethernet-view + ``` \ No newline at end of file diff --git a/README.md b/README.md index 35c0aeffe..5c9ba5ea2 100644 --- a/README.md +++ b/README.md @@ -6,25 +6,33 @@ Hyperloop UPV's Control Station is a unified software solution for real-time monitoring and commanding of the pod. It combines a back-end (Go) that ingests and interprets sensor data–defined via the JSON-based "ADJ" specifications–and a front-end (Typescript/React) that displays metrics, logs, and diagnostics to operators. With features like packet parsing, logging, and live dashboards, it acts as the central hub to safely interface the pod, making it easier for team members to oversee performance, detect faults, and send precise orders to the vehicle. -### Installation - user +## Quick Start -Download the last release, unzip it and leave the executable compatible with your OS in the folder. +### For Users -### Installation - dev +Download the latest release, unzip it and run the executable compatible with your OS. -Clone the repository, execute `npm i` at `ethernet-view`, `control-station` and `common-front`. Then run `npm run build` in `common-front`. +### For Developers -### Usage +See [DEVELOPMENT.md](./DEVELOPMENT.md) for detailed setup instructions. Quick start: -When using the Control Station make sure that you have configured your IP as the one specified in the ADJ—usually `192.168.0.9`. Then make sure to configure the boards you'll be making use of in the `config.toml` (at the top of the file you'll be able to see the `vehicle/boards` option, just add or remove the boards as needed following the format specified in the ADJ. +```bash +# Clone and setup +git clone https://github.com/HyperloopUPV-H8/software.git +cd software +./scripts/dev.sh setup -To change the ADJ branch from `main`, change the option `adj/branch` at the end of the `config.toml` with the name of the branch you want to use or leave it blank if you'll be making use of a custom ADJ. +# Run services +./scripts/dev.sh backend # Backend server +./scripts/dev.sh ethernet # Ethernet view +./scripts/dev.sh control # Control station +``` -### Developing +## Configuration -The main project file is inside `backend/cmd`. Ensure you have the proper `config.toml` configuration and are in the `develop` branch. To build the project, just run `go build` inside the folder. With everything set up, execute the `cmd` executable, then move to `ethernet-view` and run `npm run dev`, then to the `control-station` and do the same. +When using the Control Station make sure that you have configured your IP as the one specified in the ADJ—usually `192.168.0.9`. Then make sure to configure the boards you'll be making use of in the `config.toml` (at the top of the file you'll be able to see the `vehicle/boards` option, just add or remove the boards as needed following the format specified in the ADJ. -If you want to test the app in your local enviorement make use of the locahost—make sure to configure the full range of `127.0.0.X`. The `software` ADJ branch is recommended but you can create your own or use a local branch, in such case make sure to leave blank the `adj/branch` option in the `config.toml`. +To change the ADJ branch from `main`, change the option `adj/branch` at the end of the `config.toml` with the name of the branch you want to use or leave it blank if you'll be making use of a custom ADJ. ### Contributing diff --git a/backend/Dockerfile.dev b/backend/Dockerfile.dev new file mode 100644 index 000000000..7c86595f5 --- /dev/null +++ b/backend/Dockerfile.dev @@ -0,0 +1,14 @@ +FROM golang:1.21-alpine + +RUN apk add --no-cache gcc musl-dev libpcap-dev pkgconfig + +WORKDIR /app + +COPY go.mod go.sum ./ +RUN go mod download + +COPY . . + +EXPOSE 8080 + +CMD ["sh", "-c", "cd cmd && go run ."] \ No newline at end of file diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 000000000..cd795342e --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,46 @@ +version: '3.8' + +services: + # Backend service + backend: + build: + context: ./backend + dockerfile: Dockerfile.dev + volumes: + - ./backend:/app + - ./adj:/app/adj + ports: + - "8080:8080" + environment: + - CGO_ENABLED=1 + command: sh -c "cd cmd && go run ." + + # Ethernet View + ethernet-view: + image: node:18-alpine + working_dir: /app + volumes: + - ./ethernet-view:/app + - ./common-front:/common-front + ports: + - "5174:5174" + command: sh -c "npm install && npm run dev -- --host" + + # Control Station + control-station: + image: node:18-alpine + working_dir: /app + volumes: + - ./control-station:/app + - ./common-front:/common-front + ports: + - "5173:5173" + command: sh -c "npm install && npm run dev -- --host" + + # Common front (for building) + common-front: + image: node:18-alpine + working_dir: /app + volumes: + - ./common-front:/app + command: sh -c "npm install && npm run build && npm run dev" \ No newline at end of file diff --git a/go.work.sum b/go.work.sum index 66ea8e657..e8c6873e3 100644 --- a/go.work.sum +++ b/go.work.sum @@ -275,6 +275,7 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= diff --git a/scripts/dev.sh b/scripts/dev.sh new file mode 100755 index 000000000..0ed638c94 --- /dev/null +++ b/scripts/dev.sh @@ -0,0 +1,178 @@ +#!/bin/bash +# Development environment setup script + +set -e + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +print_header() { + echo -e "${GREEN}🚄 Hyperloop H10 Development Environment${NC}" + echo -e "${GREEN}=====================================>${NC}" +} + +print_usage() { + echo "Usage: $0 [command]" + echo "" + echo "Commands:" + echo " setup - Install all dependencies" + echo " backend - Run backend server" + echo " ethernet - Run ethernet-view dev server" + echo " control - Run control-station dev server" + echo " packet - Run packet-sender" + echo " all - Run all services (requires tmux)" + echo " test - Run all tests" + echo " build - Build all components" + echo "" +} + +check_dependencies() { + local missing=() + + command -v go >/dev/null 2>&1 || missing+=("go") + command -v node >/dev/null 2>&1 || missing+=("node") + command -v npm >/dev/null 2>&1 || missing+=("npm") + + if [ ${#missing[@]} -ne 0 ]; then + echo -e "${RED}Error: Missing required dependencies: ${missing[*]}${NC}" + echo "Please install them before continuing." + exit 1 + fi +} + +setup_project() { + echo -e "${YELLOW}Setting up project dependencies...${NC}" + + cd "$PROJECT_ROOT" + + # Build common-front first + echo "📦 Building common-front..." + cd common-front + npm install + npm run build + + # Install ethernet-view dependencies + echo "📦 Installing ethernet-view dependencies..." + cd ../ethernet-view + npm install + + # Install control-station dependencies + echo "📦 Installing control-station dependencies..." + cd ../control-station + npm install + + # Download Go dependencies + echo "📦 Downloading Go dependencies..." + cd ../backend + go mod download + + cd ../packet-sender + go mod download + + echo -e "${GREEN}✅ Setup complete!${NC}" +} + +run_backend() { + cd "$PROJECT_ROOT/backend/cmd" + echo -e "${YELLOW}Starting backend server...${NC}" + go run . +} + +run_ethernet_view() { + cd "$PROJECT_ROOT/ethernet-view" + echo -e "${YELLOW}Starting ethernet-view dev server...${NC}" + npm run dev +} + +run_control_station() { + cd "$PROJECT_ROOT/control-station" + echo -e "${YELLOW}Starting control-station dev server...${NC}" + npm run dev +} + +run_packet_sender() { + cd "$PROJECT_ROOT/packet-sender" + echo -e "${YELLOW}Starting packet-sender...${NC}" + go run . +} + +run_all_tmux() { + if ! command -v tmux >/dev/null 2>&1; then + echo -e "${RED}Error: tmux is required to run all services${NC}" + exit 1 + fi + + SESSION="hyperloop-dev" + + # Kill existing session if it exists + tmux kill-session -t $SESSION 2>/dev/null || true + + # Create new session with backend + tmux new-session -d -s $SESSION -n backend "cd $PROJECT_ROOT/backend/cmd && go run ." + + # Create windows for other services + tmux new-window -t $SESSION -n ethernet-view "cd $PROJECT_ROOT/ethernet-view && npm run dev" + tmux new-window -t $SESSION -n control-station "cd $PROJECT_ROOT/control-station && npm run dev" + tmux new-window -t $SESSION -n packet-sender "cd $PROJECT_ROOT/packet-sender && go run ." + + # Attach to session + echo -e "${GREEN}Starting all services in tmux session '$SESSION'${NC}" + tmux attach-session -t $SESSION +} + +run_tests() { + echo -e "${YELLOW}Running tests...${NC}" + + cd "$PROJECT_ROOT/backend" + echo "🧪 Running backend tests..." + go test -v ./... + + # Add more test commands as needed +} + +build_all() { + cd "$PROJECT_ROOT" + echo -e "${YELLOW}Building all components...${NC}" + make all +} + +# Main script logic +print_header +check_dependencies + +case "${1}" in + setup) + setup_project + ;; + backend) + run_backend + ;; + ethernet) + run_ethernet_view + ;; + control) + run_control_station + ;; + packet) + run_packet_sender + ;; + all) + run_all_tmux + ;; + test) + run_tests + ;; + build) + build_all + ;; + *) + print_usage + exit 1 + ;; +esac diff --git a/shell.nix b/shell.nix new file mode 100644 index 000000000..be513d83a --- /dev/null +++ b/shell.nix @@ -0,0 +1,85 @@ +{ pkgs ? import {} }: + +pkgs.mkShell { + name = "hyperloop-h10-dev"; + + buildInputs = with pkgs; [ + # Go development + go + gotools + gopls + + # Node.js development + nodejs + nodePackages.npm + nodePackages.typescript + + # Python for testadj + python3 + + # System dependencies + libpcap + pkg-config + + # Build tools + gnumake + gcc + + # Utilities + git + ripgrep + jq + curl + wget + + # Shell enhancements + starship + eza + bat + fzf + ]; + + shellHook = '' + echo "🚄 Hyperloop H10 Development Environment" + echo "📁 Repository root: $(pwd)" + echo "" + echo "Available commands:" + echo " make all - Build all components" + echo " make backend - Build Go backend" + echo " make common-front - Build shared component library" + echo " make control-station - Build main control interface" + echo " make ethernet-view - Build network monitoring interface" + echo "" + echo "Development servers:" + echo " cd backend/cmd && ./backend - Run backend (after building)" + echo " cd control-station && npm run dev - Run control station" + echo " cd ethernet-view && npm run dev - Run ethernet view" + echo " cd packet-sender && go run . - Run packet sender" + echo "" + + # Setup Node modules if needed + if [ ! -d "common-front/node_modules" ]; then + echo "📦 Installing common-front dependencies..." + (cd common-front && npm install) + fi + + if [ ! -d "ethernet-view/node_modules" ]; then + echo "📦 Installing ethernet-view dependencies..." + (cd ethernet-view && npm install) + fi + + if [ ! -d "control-station/node_modules" ]; then + echo "📦 Installing control-station dependencies..." + (cd control-station && npm install) + fi + + # Set up starship prompt if available + if command -v starship >/dev/null 2>&1; then + eval "$(starship init bash)" + fi + ''; + + # Environment variables + GOPATH = "$HOME/go"; + NODE_ENV = "development"; +} \ No newline at end of file