# List available recipes list: @just --list --justfile {{ source_file() }} fmt_flags := '--all' # Run formatter fmt *FLAGS: cargo +nightly fmt {{ fmt_flags }} {{ FLAGS }} check_flags := '--all-targets' v2_lints:= '-D warnings -Aunused -Aclippy::todo -Aclippy::diverging_sub_expression' alias c := check # Check compilation of Rust code and catch common mistakes # We cannot run --all-features because v1 and v2 are mutually exclusive features # Create a list of features by excluding certain features # redis_interface_backend: "redis-rs" (default) or "fred" clippy redis_interface_backend="redis-rs" *FLAGS: #! /usr/bin/env bash set -euo pipefail FEATURES="$(cargo metadata --all-features --format-version 1 --no-deps | \ jq -r ' [ ( .workspace_members | sort ) as $package_ids # Store workspace crate package IDs in `package_ids` array | .packages[] | select( IN(.id; $package_ids[]) ) | .features | keys[] ] | unique # Select all unique features from all workspace crates | del( .[] | select( any( . ; test("(([a-z_]+)_)?v2") ) ) ) # Exclude v2 features | del( .[] | select( . == ("default", "fred", "redis-rs") ) ) # Exclude default and both backend flags | join(",") # Construct a comma-separated string of features for passing to `cargo` ')" FEATURES="${FEATURES},{{ redis_interface_backend }}" set -x cargo clippy {{ check_flags }} --no-default-features --features "${FEATURES}" {{ FLAGS }} set +x # redis_interface_backend: "redis-rs" (default) or "fred" clippy_v2 redis_interface_backend="redis-rs" *FLAGS: #! /usr/bin/env bash set -euo pipefail FEATURES="$(cargo metadata --all-features --format-version 1 --no-deps | \ jq -r ' [ ( .workspace_members | sort ) as $package_ids # Store workspace crate package IDs in `package_ids` array | .packages[] | select( IN(.id; $package_ids[]) ) | .features | keys[] ] | unique # Select all unique features from all workspace crates | del( .[] | select( . == ("default", "v1", "deja", "fred", "redis-rs") ) ) # Exclude default, v1, deja (v1-only feature), and both backend flags | join(",") # Construct a comma-separated string of features for passing to `cargo` ')" FEATURES="${FEATURES},{{ redis_interface_backend }}" set -x cargo clippy {{ check_flags }} --no-default-features --features "${FEATURES}" -- {{ v2_lints }} {{ FLAGS }} set +x # redis_interface_backend: "redis-rs" (default) or "fred" check_v2 redis_interface_backend="redis-rs" *FLAGS: #! /usr/bin/env bash set -euo pipefail FEATURES="$(cargo metadata --all-features --format-version 1 --no-deps | \ jq -r ' [ ( .workspace_members | sort ) as $package_ids # Store workspace crate package IDs in `package_ids` array | .packages[] | select( IN(.id; $package_ids[]) ) | .features | keys[] ] | unique # Select all unique features from all workspace crates | del( .[] | select( . == ("default", "v1", "deja", "fred", "redis-rs") ) ) # Exclude default, v1, deja (v1-only feature), and both backend flags | join(",") # Construct a comma-separated string of features for passing to `cargo` ')" FEATURES="${FEATURES},{{ redis_interface_backend }}" set -x cargo check {{ check_flags }} --no-default-features --features "${FEATURES}" -- {{ FLAGS }} set +x # redis_interface_backend: "redis-rs" (default) or "fred" build_v2 redis_interface_backend="redis-rs" *FLAGS: #! /usr/bin/env bash set -euo pipefail FEATURES="$(cargo metadata --all-features --format-version 1 --no-deps | \ jq -r ' [ .packages[] | select(.name == "router") | .features | keys[] # Obtain features of `router` package | select( any( . ; test("(([a-z_]+)_)?v2") ) ) ] # Select v2 features | join(",") # Construct a comma-separated string of features for passing to `cargo` ')" FEATURES="${FEATURES},{{ redis_interface_backend }}" set -x cargo build --package router --bin router --no-default-features --features "${FEATURES}" {{ FLAGS }} set +x # redis_interface_backend: "redis-rs" (default) or "fred" run_v2 redis_interface_backend="redis-rs": #! /usr/bin/env bash set -euo pipefail FEATURES="$(cargo metadata --all-features --format-version 1 --no-deps | \ jq -r ' [ .packages[] | select(.name == "router") | .features | keys[] # Obtain features of `router` package | select( any( . ; test("(([a-z_]+)_)?v2") ) ) ] # Select v2 features | join(",") # Construct a comma-separated string of features for passing to `cargo` ')" FEATURES="${FEATURES},{{ redis_interface_backend }}" set -x cargo run --package router --no-default-features --features "${FEATURES}" set +x # redis_interface_backend: "redis-rs" (default) or "fred" check redis_interface_backend="redis-rs" *FLAGS: #! /usr/bin/env bash set -euo pipefail FEATURES="$(cargo metadata --all-features --format-version 1 --no-deps | \ jq -r ' [ ( .workspace_members | sort ) as $package_ids # Store workspace crate package IDs in `package_ids` array | .packages[] | select( IN(.id; $package_ids[]) ) | .features | keys[] ] | unique # Select all unique features from all workspace crates | del( .[] | select( any( . ; test("(([a-z_]+)_)?v2") ) ) ) # Exclude v2 features | del( .[] | select( . == ("default", "fred", "redis-rs") ) ) # Exclude default and both backend flags | join(",") # Construct a comma-separated string of features for passing to `cargo` ')" FEATURES="${FEATURES},{{ redis_interface_backend }}" set -x cargo check {{ check_flags }} --no-default-features --features "${FEATURES}" {{ FLAGS }} set +x alias cl := clippy # Build binaries build *FLAGS: cargo build {{ FLAGS }} alias b := build # Build release (optimized) binaries build-release *FLAGS: cargo build --release --features release {{ FLAGS }} alias br := build-release # Run server run *FLAGS: cargo run {{ FLAGS }} alias r := run doc_flags := '--all-features --all-targets --exclude-features "v2"' # Generate documentation doc *FLAGS: cargo doc {{ doc_flags }} {{ FLAGS }} alias d := doc # Build the `euclid_wasm` crate euclid-wasm features='dummy_connector': wasm-pack build \ --target web \ --out-dir {{ source_directory() }}/wasm \ --out-name euclid \ {{ source_directory() }}/crates/euclid_wasm \ --features '{{ features }}' # Build the `payment_link` crate as WASM # Usage: just payment-link-wasm [features=''] [version='v1'] [environment='development'] payment-link-wasm features='' version='v1' environment='development': ENVIRONMENT={{ environment }} ~/.cargo/bin/wasm-pack build \ --target web \ --out-dir {{ source_directory() }}/wasm_output \ --out-name payment_link \ {{ source_directory() }}/crates/payment_link \ -- --features wasm,{{ version }},{{ features }} # Run pre-commit checks precommit: fmt clippy # Run drainer with v1 features enabled drainer redis_interface_backend="redis-rs" *FLAGS: DRAINER__SERVER__PORT=8084 cargo run --package drainer --no-default-features --features "{{ redis_interface_backend }},v1" {{ FLAGS }} # Run drainer with v2 features enabled drainer_v2 redis_interface_backend="redis-rs" *FLAGS: DRAINER__SERVER__PORT=8084 cargo run --package drainer --no-default-features --features "{{ redis_interface_backend }},v2" {{ FLAGS }} # Use the env variables if present, or fallback to default values db_user := env_var_or_default('DB_USER', 'db_user') db_password := env_var_or_default('DB_PASSWORD', 'db_pass') db_host := env_var_or_default('DB_HOST', 'localhost') db_port := env_var_or_default('DB_PORT', '5432') db_name := env_var_or_default('DB_NAME', 'hyperswitch_db') default_db_url := 'postgresql://' + db_user + ':' + db_password + '@' + db_host + ':' + db_port / db_name database_url := env_var_or_default('DATABASE_URL', default_db_url) default_migration_params := '' v2_migration_dir := source_directory() / 'v2_migrations' v2_compatible_migrations := source_directory() / 'v2_compatible_migrations' v1_migration_dir := source_directory() / 'migrations' resultant_dir := source_directory() / 'final-migrations' # Copy migrations in {{dir_1}} and {{dir_2}} to a single directory {{resultant_dir}} after prefixing the subdirectories of {{dir_2}} with {{prefix}} [private] prefix_and_copy_migrations dir_1 dir_2 prefix resultant_dir: #! /usr/bin/env bash mkdir -p {{ resultant_dir }} cp -r {{ dir_1 }}/* {{ resultant_dir }}/ > /dev/null 2>&1 # Prefix v2 migrations with {{ prefix }} sh -c ' for dir in "{{ dir_2 }}"/*; do if [ -d "${dir}" ]; then base_name=$(basename "${dir}") new_name="{{ prefix }}${base_name}" cp -r "${dir}" "{{ resultant_dir }}/${new_name}" fi done ' echo "Created {{ resultant_dir }}" # Delete the newly created directory [private] delete_dir_if_exists dir=resultant_dir: @rm -rf {{ dir }} v1_config_file_dir := source_directory() / 'diesel.toml' default_operation := 'run' [private] run_migration operation=default_operation migration_dir=v1_migration_dir config_file_dir=v1_config_file_dir url=database_url *other_params=default_migration_params: diesel migration \ --database-url '{{ url }}' \ {{ operation }} \ --migration-dir '{{ migration_dir }}' \ --config-file '{{ config_file_dir }}' \ {{ other_params }} # Run database migrations for v1 migrate operation=default_operation *args='': (run_migration operation v1_migration_dir v1_config_file_dir database_url args) v2_config_file_dir := source_directory() / 'diesel_v2.toml' # Run database migrations for v2 migrate_v2 operation=default_operation *args='': #! /usr/bin/env bash set -euo pipefail EXIT_CODE=0 just prefix_and_copy_migrations {{ v1_migration_dir }} {{ v2_compatible_migrations }} 8 {{ resultant_dir }} just prefix_and_copy_migrations {{ resultant_dir }} {{ v2_migration_dir }} 9 {{ resultant_dir }} just run_migration {{ operation }} {{ resultant_dir }} {{ v2_config_file_dir }} {{ database_url }} {{ args }} || EXIT_CODE=$? just delete_dir_if_exists exit $EXIT_CODE # Run database migrations compatible with both v1 and v2 migrate_v2_compatible: #! /usr/bin/env bash set -euo pipefail EXIT_CODE=0 just prefix_and_copy_migrations {{ v1_migration_dir }} {{ v2_compatible_migrations }} 8 {{ resultant_dir }} # Run the compatible migrations just run_migration run {{ resultant_dir }} {{ database_url }} || EXIT_CODE=$? just delete_dir_if_exists exit $EXIT_CODE # Drop database if exists and then create a new 'hyperswitch_db' Database resurrect database_name=db_name: psql -U postgres -c 'DROP DATABASE IF EXISTS {{ database_name }}'; psql -U postgres -c 'CREATE DATABASE {{ database_name }}'; ci_hack: scripts/ci-checks.sh # Start superposition in docker (auto-detects docker or podman) superposition-up: #! /usr/bin/env bash set -euo pipefail # Detect container runtime if command -v docker &> /dev/null; then COMPOSE="docker-compose" elif command -v podman-compose &> /dev/null; then COMPOSE="podman-compose" else echo "Error: Neither docker-compose nor podman-compose found" exit 1 fi echo "Using $COMPOSE..." $COMPOSE -f docker-compose-development.yml up -d superposition echo "Waiting for superposition to be ready..." for i in {1..30}; do if curl -s http://localhost:8081/health > /dev/null 2>&1; then echo "Superposition is ready!" break fi echo "Waiting for superposition... ($i/30)" sleep 2 done # Stop superposition and dependencies superposition-down: #! /usr/bin/env bash set -euo pipefail if command -v docker &> /dev/null; then docker-compose -f docker-compose-development.yml down elif command -v podman-compose &> /dev/null; then podman-compose -f docker-compose-development.yml down fi # Seed Superposition with default dimensions and configs superposition-seed: #! /usr/bin/env bash set -euo pipefail if [ ! -f "./config/superposition_seed.toml" ]; then echo "Error: Seed file not found at ./config/superposition_seed.toml" exit 1 fi bash ./scripts/seed_superposition.sh