|
#!/bin/bash |
|
set -e |
|
|
|
# Start timing the script execution |
|
SCRIPT_START_TIME=$(date +%s) |
|
MAX_EXECUTION_TIME=300 # 5 minutes in seconds |
|
|
|
# Script to set up Flutter environment on Codex. |
|
# This script installs Flutter, sets up the environment, configures necessary dependencies, pulls relevant documentation, |
|
# and populates `AGENTS.md` |
|
# NB! Note that Codex cuts the internet after this script completes. |
|
|
|
# Usage: "Environments" -> Create environment or select existing -> "Edit" -> "Advanced" -> "Setup script" |
|
# -> Paste the contents of this script -> "Save environment" |
|
|
|
# Version of this script |
|
SCRIPT_VERSION="1.3.1" |
|
|
|
# Auto-update the setup script if a new version is available |
|
AUTO_UPDATE_SCRIPT=${AUTO_UPDATE_SCRIPT:-false} |
|
# Flag to prevent recursive auto-update loops |
|
SKIP_RECURSIVE_UPDATE=${SKIP_RECURSIVE_UPDATE:-false} |
|
|
|
# Whether to run certain operations in parallel |
|
PARALLEL_EXECUTION=${PARALLEL_EXECUTION:-true} |
|
# Maximum number of parallel jobs based on CPU cores |
|
MAX_PARALLEL_JOBS=$(($(nproc) / 2 > 0 ? $(nproc) / 2 : 1)) |
|
|
|
# URL of the script gist for auto-updating |
|
GIST_URL=https://gist.githubusercontent.com/CharlVS/14233fff7e9b3d66a7268d578cc34b36/raw |
|
SCRIPT_GIST_URL=${GIST_URL}/komodo_flutter_codex_env_setup.sh |
|
AGENTS_GIST_URL=${GIST_URL}/AGENTS.md |
|
|
|
# Dependency tracking mechanism |
|
declare -A job_pids |
|
job_count=0 |
|
# Remove unused declaration |
|
# declare -A job_deps |
|
|
|
# Function to execute commands with dependencies - compatible with all bash versions |
|
run_with_deps() { |
|
local name="$1" |
|
local deps="$2" |
|
local cmd="$3" |
|
local dir="${4:-$(pwd)}" |
|
|
|
# Wait for dependencies if they exist |
|
for dep in $deps; do |
|
if [[ -n "${job_pids[$dep]}" ]]; then |
|
echo "Waiting for dependency: $dep" |
|
wait "${job_pids[$dep]}" || { |
|
echo "Dependency $dep failed" |
|
return 1 |
|
} |
|
fi |
|
done |
|
|
|
# Check if we need to limit parallel jobs |
|
if [[ "$PARALLEL_EXECUTION" == "true" ]]; then |
|
# Wait if we've reached the maximum number of jobs |
|
if ((job_count >= MAX_PARALLEL_JOBS)); then |
|
# Compatible alternative to wait -n |
|
# Wait for the oldest job to complete and remove it |
|
for job_name in "${!job_pids[@]}"; do |
|
local job_pid=${job_pids[$job_name]} |
|
wait "$job_pid" || true |
|
unset job_pids[$job_name] |
|
job_count=$((job_count - 1)) |
|
break |
|
done |
|
fi |
|
|
|
echo "Executing in parallel: $cmd (in directory: $dir)" |
|
(cd "$dir" && eval "$cmd") & |
|
job_pids[$name]=$! |
|
job_count=$((job_count + 1)) |
|
else |
|
echo "Executing sequentially: $cmd (in directory: $dir)" |
|
(cd "$dir" && eval "$cmd") || return 1 |
|
fi |
|
} |
|
|
|
# Function to execute commands in parallel if enabled, or sequentially if disabled |
|
run_parallel() { |
|
local cmd="$1" |
|
local dir="${2:-$(pwd)}" |
|
|
|
if [[ "$PARALLEL_EXECUTION" == "true" ]]; then |
|
# Wait if we've reached the maximum number of jobs |
|
if ((job_count >= MAX_PARALLEL_JOBS)); then |
|
# Wait for the oldest job to complete and remove it |
|
for job_name in "${!job_pids[@]}"; do |
|
local job_pid=${job_pids[$job_name]} |
|
wait "$job_pid" || true |
|
unset job_pids[$job_name] |
|
job_count=$((job_count - 1)) |
|
break |
|
done |
|
fi |
|
|
|
echo "Executing in parallel: $cmd (in directory: $dir)" |
|
(cd "$dir" && eval "$cmd") & |
|
local rand_key="job_$(date +%s%N)" |
|
job_pids[$rand_key]=$! |
|
job_count=$((job_count + 1)) |
|
else |
|
echo "Executing sequentially: $cmd (in directory: $dir)" |
|
(cd "$dir" && eval "$cmd") |
|
fi |
|
} |
|
|
|
# Wait for all background jobs if parallel execution is enabled |
|
wait_if_parallel() { |
|
if [[ "$PARALLEL_EXECUTION" == "true" ]]; then |
|
echo "Waiting for parallel jobs to complete..." |
|
wait |
|
job_count=0 |
|
# Clear the job tracking array |
|
for key in "${!job_pids[@]}"; do |
|
unset job_pids[$key] |
|
done |
|
fi |
|
} |
|
|
|
# Improved function to check if we're in a git repository |
|
is_git_repo() { |
|
# Check if this directory (not a parent) is a git repository |
|
if git rev-parse --is-inside-work-tree >/dev/null 2>&1 && [[ "$(git rev-parse --show-toplevel)" == "$(pwd)" ]]; then |
|
return 0 |
|
else |
|
return 1 |
|
fi |
|
} |
|
|
|
# Initial directory |
|
INITIAL_DIR=$(pwd) |
|
echo "Current directory: $INITIAL_DIR" |
|
|
|
# Environment variables |
|
FLUTTER_VERSION="3.32.5" |
|
|
|
# Installation method for Flutter. Options: |
|
# - "git": Clone Flutter from Git repository (slower but works for any version) |
|
# - "precompiled": Download pre-compiled Flutter SDK binaries (faster setup) |
|
FLUTTER_INSTALL_METHOD=${FLUTTER_INSTALL_METHOD:-"precompiled"} |
|
|
|
# List of platforms to set up build tools for. Supported values: "web" (More to come soon) |
|
if [ -z "${PLATFORMS+x}" ]; then |
|
PLATFORMS=("web") |
|
fi |
|
|
|
# Whether to fetch all remote branches. |
|
# Set to "true" to fetch all remote branches, "false" to skip this step. |
|
# This is necessary if you want to work with multiple branches in the same environment |
|
# because Codex cuts the internet after this script completes. |
|
FETCH_ALL_REMOTE_BRANCHES=${FETCH_ALL_REMOTE_BRANCHES:-true} |
|
|
|
REMOTE_BASE_URL="https://github.com/KomodoPlatform" |
|
|
|
# Safely retrieve the Git repo name |
|
if is_git_repo; then |
|
GIT_REPO_NAME=$(basename "$(git rev-parse --show-toplevel)") |
|
GIT_REMOTE_URL="${REMOTE_BASE_URL}/${GIT_REPO_NAME}.git" |
|
else |
|
echo "Warning: Not in a Git repository. Git operations will be skipped." |
|
GIT_REPO_NAME="unknown" |
|
GIT_REMOTE_URL="" |
|
fi |
|
|
|
# Whether to fetch the `AGENTS.md` file from the gist repository. |
|
# This will be removed in the future when the files exist in the repository. |
|
SHOULD_FETCH_AGENTS_DOCS=${SHOULD_FETCH_AGENTS_DOCS:-true} |
|
|
|
# Whether to fetch the KDF API documentation. Defaults to if we are in the KDF SDK repository. |
|
SHOULD_FETCH_KDF_API_DOCS=${SHOULD_FETCH_KDF_API_DOCS:-$([ "$GIT_REPO_NAME" = "komodo-defi-sdk-flutter" ] && echo "true" || echo "false")} |
|
# URL to fetch KDF API documentation |
|
KDF_API_DOCS_URL="https://raw.githubusercontent.com/KomodoPlatform/komodo-docs-mdx/refs/heads/dev/data-for-gpts/komodefi-api/all-api-content.txt" |
|
|
|
# Detect shell profile |
|
SHELL_PROFILE="" |
|
if [[ "$SHELL" == */zsh ]]; then |
|
SHELL_PROFILE="$HOME/.zshrc" |
|
echo "Detected zsh shell" |
|
elif [[ "$SHELL" == */bash ]]; then |
|
SHELL_PROFILE="$HOME/.bashrc" |
|
echo "Detected bash shell" |
|
else |
|
SHELL_PROFILE="$HOME/.profile" |
|
echo "Shell could not be determined, using $SHELL_PROFILE" |
|
fi |
|
|
|
# Improved function to avoid duplicating PATH entries |
|
add_to_path() { |
|
local path_entry="$1" |
|
local profile="$2" |
|
|
|
# Normalize path by removing trailing slash |
|
path_entry=${path_entry%/} |
|
|
|
# Escape special characters for grep |
|
local escaped_entry=$(echo "$path_entry" | sed 's/[\/&]/\\&/g') |
|
|
|
# Check if the path or equivalent is already in profile |
|
if ! grep -q "PATH=.*${escaped_entry}.*" "$profile" && ! grep -q "export PATH=\".*${escaped_entry}.*" "$profile"; then |
|
echo "Adding $path_entry to PATH in $profile" |
|
echo "export PATH=\"\$PATH:$path_entry\"" >>"$profile" |
|
# Apply to current session |
|
export PATH="$PATH:$path_entry" |
|
return 0 |
|
else |
|
echo "$path_entry already in PATH configuration" |
|
# Ensure path is available in current session regardless |
|
export PATH="$PATH:$path_entry" |
|
return 1 |
|
fi |
|
} |
|
|
|
# Install required dependencies using apt - but only what's needed |
|
echo "Checking required dependencies..." |
|
MISSING_TOOLS="" |
|
for tool in curl git unzip xz-utils zip; do |
|
if ! command -v "$tool" &>/dev/null && ! dpkg -l | grep -q " $tool "; then |
|
MISSING_TOOLS="$MISSING_TOOLS $tool" |
|
fi |
|
done |
|
|
|
# Check for libglu1-mesa separately as it doesn't have a command |
|
if ! dpkg -l | grep -q " libglu1-mesa "; then |
|
MISSING_TOOLS="$MISSING_TOOLS libglu1-mesa" |
|
fi |
|
|
|
# Only update and install if there are missing tools |
|
if [ ! -z "$MISSING_TOOLS" ]; then |
|
echo "Installing missing tools:$MISSING_TOOLS" |
|
# Update first before installing packages |
|
sudo apt-get update -y |
|
sudo apt-get install -y $MISSING_TOOLS |
|
else |
|
echo "All required dependencies are already installed." |
|
fi |
|
|
|
# Check for updates to the setup script and update if auto-updated is enabled |
|
SCRIPT_CONTENT=$(curl -s $SCRIPT_GIST_URL) |
|
if [[ $? -ne 0 ]]; then |
|
echo "Warning: Failed to check for script updates. Continuing with current version." |
|
LATEST_SCRIPT_VERSION=$SCRIPT_VERSION |
|
else |
|
# Extract just the version number using head to get the first line containing the version |
|
LATEST_SCRIPT_VERSION=$(echo "$SCRIPT_CONTENT" | grep "SCRIPT_VERSION=" | head -n 1 | cut -d'"' -f2) |
|
if [[ -z "$LATEST_SCRIPT_VERSION" ]]; then |
|
echo "Warning: Could not parse script version. Continuing with current version." |
|
LATEST_SCRIPT_VERSION=$SCRIPT_VERSION |
|
fi |
|
fi |
|
|
|
# Fixed auto-update logic to prevent recursion |
|
if [[ "$LATEST_SCRIPT_VERSION" != "$SCRIPT_VERSION" ]]; then |
|
echo "A new version of the setup script is available: $LATEST_SCRIPT_VERSION" |
|
|
|
if [[ "$AUTO_UPDATE_SCRIPT" == "true" && "$SKIP_RECURSIVE_UPDATE" != "true" ]]; then |
|
echo "Updating setup script..." |
|
curl -s $SCRIPT_GIST_URL -o $HOME/komodo_flutter_codex_env_setup.sh |
|
chmod +x $HOME/komodo_flutter_codex_env_setup.sh |
|
# Run the updated script with flag to prevent recursive updates |
|
echo "Running the updated setup script..." |
|
SKIP_RECURSIVE_UPDATE=true bash $HOME/komodo_flutter_codex_env_setup.sh |
|
exit 0 |
|
else |
|
echo "WARN: Auto-update is disabled or skipped to prevent recursion. Please update manually at $SCRIPT_GIST_URL" |
|
fi |
|
else |
|
echo "Setup script is up to date: $SCRIPT_VERSION" |
|
fi |
|
|
|
# Get all remote branches if FETCH_ALL_REMOTE_BRANCHES is true and in a git repo |
|
if [[ "$FETCH_ALL_REMOTE_BRANCHES" == "true" && -n "$GIT_REMOTE_URL" ]]; then |
|
if is_git_repo; then |
|
echo "Fetching all remote branches..." |
|
|
|
# Check if remote exists before adding |
|
if ! git remote | grep -q "^origin$"; then |
|
git remote add origin "$GIT_REMOTE_URL" |
|
else |
|
git remote set-url origin "$GIT_REMOTE_URL" |
|
fi |
|
|
|
# Add timeout to git fetch to prevent hanging |
|
if ! timeout 120 git fetch --all; then |
|
echo "ERROR: Git fetch failed or timed out. Repository may be incomplete." |
|
# Continue but warn user |
|
fi |
|
else |
|
echo "Not in a git repository, skipping git fetch operations." |
|
fi |
|
|
|
# ============== UNCOMMENT WHEN TESTING IN CODEX ENVIRONMENT SETTINGS ============== |
|
# git checkout -b dev origin/dev || { |
|
# echo "ERROR: Failed to checkout dev branch. Please check your git configuration." |
|
# exit 1 |
|
# } |
|
# ============== END OF UNCOMMENT BLOCK ============== |
|
fi |
|
|
|
# Set up directories |
|
echo "Setting up directories..." |
|
mkdir -p $HOME/flutter |
|
|
|
# Set up environment variables with improved path handling |
|
echo "Setting up environment variables..." |
|
add_to_path "$HOME/flutter/bin" "$SHELL_PROFILE" |
|
add_to_path "$HOME/.pub-cache/bin" "$SHELL_PROFILE" |
|
|
|
# Ensure PATH is set correctly before any operations |
|
export PATH="$HOME/flutter/bin:$PATH:$HOME/.pub-cache/bin" |
|
|
|
# Print PATH for verification |
|
echo "Current PATH: $PATH" |
|
|
|
# Download and install Flutter if not already installed |
|
FLUTTER_INSTALLED=false |
|
if [ ! -d "$HOME/flutter/bin" ]; then |
|
echo "Downloading and installing Flutter ${FLUTTER_VERSION}..." |
|
|
|
# Check for sufficient disk space (Flutter needs ~1GB) |
|
REQUIRED_SPACE=1500000 # ~1.5GB in KB |
|
AVAILABLE_SPACE=$(df -k $HOME | awk 'NR==2 {print $4}') |
|
|
|
if [ $AVAILABLE_SPACE -lt $REQUIRED_SPACE ]; then |
|
echo "Error: Not enough disk space. Need at least 1.5GB, have $(($AVAILABLE_SPACE / 1024))MB" |
|
exit 1 |
|
fi |
|
|
|
cd $HOME |
|
|
|
if [[ "$FLUTTER_INSTALL_METHOD" == "precompiled" ]]; then |
|
echo "Using pre-compiled Flutter SDK binaries for version ${FLUTTER_VERSION}..." |
|
|
|
# Format version number for download URL (remove build number if present) |
|
FLUTTER_RELEASE_VERSION=$(echo "${FLUTTER_VERSION}" | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/') |
|
FLUTTER_ARCHIVE="flutter_linux_${FLUTTER_RELEASE_VERSION}-stable.tar.xz" |
|
FLUTTER_URL="https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/${FLUTTER_ARCHIVE}" |
|
|
|
echo "Downloading Flutter SDK from: ${FLUTTER_URL}" |
|
if ! curl -L -o "${FLUTTER_ARCHIVE}" "${FLUTTER_URL}"; then |
|
echo "Warning: Failed to download pre-compiled Flutter SDK. The specified version may not be available as a pre-built package." |
|
echo "Falling back to Git installation method..." |
|
FLUTTER_INSTALL_METHOD="git" |
|
else |
|
echo "Extracting Flutter SDK..." |
|
if ! tar xf "${FLUTTER_ARCHIVE}"; then |
|
echo "Error: Failed to extract Flutter SDK archive." |
|
echo "Falling back to Git installation method..." |
|
FLUTTER_INSTALL_METHOD="git" |
|
rm "${FLUTTER_ARCHIVE}" # Clean up failed download |
|
else |
|
# Clean up the archive |
|
rm "${FLUTTER_ARCHIVE}" |
|
|
|
# Verify the extracted version matches our requirement |
|
EXTRACTED_VERSION=$(cat flutter/version) |
|
echo "Extracted Flutter version: ${EXTRACTED_VERSION}" |
|
|
|
if [[ "${EXTRACTED_VERSION}" != *"${FLUTTER_RELEASE_VERSION}"* ]]; then |
|
echo "Warning: The extracted Flutter version (${EXTRACTED_VERSION}) does not match the requested version (${FLUTTER_VERSION})." |
|
echo "Continuing with the downloaded version. If you need the exact version, use FLUTTER_INSTALL_METHOD=git." |
|
fi |
|
fi |
|
fi |
|
fi |
|
|
|
# If precompiled download failed or was not selected, use git |
|
if [[ "$FLUTTER_INSTALL_METHOD" == "git" ]]; then |
|
echo "Installing Flutter from Git repository..." |
|
|
|
# Remove any partial flutter directory from failed precompiled attempt |
|
[ -d "flutter" ] && rm -rf flutter |
|
|
|
# Use shallow clone for faster download |
|
echo "Shallow cloning Flutter repository (branch: ${FLUTTER_VERSION})..." |
|
if ! git clone --depth 1 --branch ${FLUTTER_VERSION} https://github.com/flutter/flutter.git; then |
|
echo "Error: Failed to clone Flutter repository. Please check your internet connection and try again." |
|
cd $INITIAL_DIR # Return to initial directory before exiting |
|
exit 1 |
|
fi |
|
fi |
|
|
|
# Navigate to flutter directory |
|
cd flutter |
|
|
|
# Configure Flutter |
|
echo "Configuring Flutter..." |
|
# Fix ownership issues to prevent Git dubious ownership warnings |
|
sudo chown -R $(whoami):$(whoami) $HOME/flutter |
|
|
|
# Configure Git to trust this directory (only needed for git install method) |
|
if [[ "$FLUTTER_INSTALL_METHOD" == "git" ]]; then |
|
git config --global --add safe.directory $HOME/flutter |
|
fi |
|
|
|
# Optimize Flutter configuration for web only |
|
echo "Precaching Flutter assets for web..." |
|
# Pre-warm with dart command |
|
if [ -f "bin/dart" ]; then |
|
echo "Pre-warming Dart compiler..." |
|
bin/dart --version >/dev/null 2>&1 |
|
fi |
|
|
|
# Run sequentially to avoid issues - these operations have dependencies |
|
flutter config --no-analytics |
|
flutter precache --web --no-android --no-ios --no-fuchsia --no-linux --no-macos --no-windows |
|
|
|
# Run streamlined doctor check |
|
if ! timeout 60 flutter doctor --no-analytics; then |
|
echo "ERROR: Flutter doctor failed. Flutter installation may be incomplete." |
|
# Continue anyway |
|
fi |
|
|
|
# Verify Flutter was installed correctly |
|
if ! command -v flutter &>/dev/null; then |
|
echo "Error: Flutter installation failed or not available in PATH" |
|
cd $INITIAL_DIR # Return to initial directory before exiting |
|
exit 1 |
|
fi |
|
|
|
FLUTTER_INSTALLED=true |
|
echo "Flutter installation completed successfully!" |
|
else |
|
echo "Flutter already installed, skipping download" |
|
fi |
|
|
|
# Return to the initial directory |
|
cd $INITIAL_DIR |
|
|
|
# ============== Platform-specific setup ============== |
|
for PLATFORM in "${PLATFORMS[@]}"; do |
|
echo "Setting up platform: $PLATFORM" |
|
case "$PLATFORM" in |
|
web) |
|
# Install Node.js if not already installed |
|
if ! command -v node &>/dev/null; then |
|
run_parallel "sudo apt-get update && sudo apt-get install -y nodejs npm" |
|
fi |
|
;; |
|
esac |
|
echo "Platform $PLATFORM setup complete." |
|
done |
|
|
|
wait_if_parallel |
|
|
|
echo "Environment setup complete!" |
|
echo "Current directory: $(pwd)" |
|
|
|
# Functions for document fetching and processing |
|
update_git_exclude() { |
|
if is_git_repo; then |
|
echo "Updating .git/info/exclude file to ignore downloaded documentation..." >&2 |
|
mkdir -p "$INITIAL_DIR/.git/info" |
|
|
|
# Patterns to exclude (including script-generated files) |
|
local patterns=( |
|
"AGENTS.md" |
|
"AGENTS_*.md" |
|
"KDF_API_DOCUMENTATION.md" |
|
"# Script-generated documentation files" |
|
) |
|
|
|
local EXCLUDE_FILE="$INITIAL_DIR/.git/info/exclude" |
|
|
|
for pattern in "${patterns[@]}"; do |
|
# Skip comment lines for pattern matching |
|
if [[ "$pattern" == \#* ]]; then |
|
# Add comment if not already present |
|
if ! grep -Fq "$pattern" "$EXCLUDE_FILE" 2>/dev/null; then |
|
echo "$pattern" >>"$EXCLUDE_FILE" |
|
fi |
|
else |
|
# Escape special characters for grep |
|
local escaped_pattern=$(echo "$pattern" | sed 's/[.*+?^${}()|[\]\\]/\\&/g') |
|
if ! grep -q "^$escaped_pattern$" "$EXCLUDE_FILE" 2>/dev/null; then |
|
echo "$pattern" >>"$EXCLUDE_FILE" |
|
fi |
|
fi |
|
done |
|
echo "Git exclude file updated." >&2 |
|
else |
|
echo "Not in a git repository, skipping git exclude file update." >&2 |
|
fi |
|
} |
|
|
|
# Enhanced fetch_all_docs function with deduplication logic |
|
fetch_all_docs() { |
|
# Send informational messages to stderr instead of stdout |
|
echo "Fetching documentation..." >&2 |
|
|
|
# Script-generated file marker |
|
local SCRIPT_MARKER="<!-- Generated by komodo_flutter_codex_env_setup.sh v${SCRIPT_VERSION} -->" |
|
|
|
# Determine target filename for AGENTS.md |
|
local BASE_AGENTS_FILE="$INITIAL_DIR/AGENTS.md" |
|
local AGENTS_FILE="$BASE_AGENTS_FILE" |
|
local SHOULD_CREATE_FILE=true |
|
|
|
# First, fetch the remote content to a temporary file for comparison |
|
local TEMP_AGENTS_FILE="/tmp/agents_temp_$(date +%s).md" |
|
echo "Downloading AGENTS.md for content comparison..." >&2 |
|
|
|
if curl -s "$AGENTS_GIST_URL" -o "$TEMP_AGENTS_FILE"; then |
|
# Add our script marker to the temp file |
|
local TEMP_WITH_MARKER="/tmp/agents_with_marker_$(date +%s).md" |
|
{ |
|
echo "$SCRIPT_MARKER" |
|
echo "" |
|
cat "$TEMP_AGENTS_FILE" |
|
} >"$TEMP_WITH_MARKER" |
|
|
|
if [ -f "$BASE_AGENTS_FILE" ]; then |
|
echo "AGENTS.md already exists, checking if update is needed..." >&2 |
|
|
|
# Check if existing file was generated by this script |
|
if head -n 1 "$BASE_AGENTS_FILE" | grep -q "Generated by komodo_flutter_codex_env_setup.sh"; then |
|
echo "Existing AGENTS.md was generated by script, checking content..." >&2 |
|
|
|
# Compare content (excluding the version-specific marker line) |
|
local EXISTING_CONTENT_HASH=$(tail -n +3 "$BASE_AGENTS_FILE" | sha256sum | cut -d' ' -f1) |
|
local NEW_CONTENT_HASH=$(cat "$TEMP_AGENTS_FILE" | sha256sum | cut -d' ' -f1) |
|
|
|
if [ "$EXISTING_CONTENT_HASH" = "$NEW_CONTENT_HASH" ]; then |
|
echo "AGENTS.md content is identical, skipping download." >&2 |
|
SHOULD_CREATE_FILE=false |
|
AGENTS_FILE="$BASE_AGENTS_FILE" # Use existing file |
|
else |
|
echo "AGENTS.md content has changed, updating file..." >&2 |
|
# Overwrite existing script-generated file |
|
AGENTS_FILE="$BASE_AGENTS_FILE" |
|
fi |
|
else |
|
echo "Existing AGENTS.md appears to be user-created, creating versioned file..." >&2 |
|
# Find the highest version number of AGENTS_X.md files |
|
local MAX_NUM=0 |
|
for f in "$INITIAL_DIR"/AGENTS_*.md; do |
|
if [ -f "$f" ]; then |
|
local NUM=$(echo "$f" | sed -E 's/.*AGENTS_([0-9]+)\.md/\1/') |
|
if [[ "$NUM" =~ ^[0-9]+$ ]] && [ "$NUM" -gt "$MAX_NUM" ]; then |
|
MAX_NUM=$NUM |
|
fi |
|
fi |
|
done |
|
|
|
# Create new filename with incremented number |
|
local NEXT_NUM=$((MAX_NUM + 1)) |
|
AGENTS_FILE="$INITIAL_DIR/AGENTS_$NEXT_NUM.md" |
|
echo "User-created AGENTS.md detected, saving to $AGENTS_FILE" >&2 |
|
fi |
|
fi |
|
|
|
# Create/update the file if needed |
|
if [ "$SHOULD_CREATE_FILE" = true ]; then |
|
echo "Creating/updating $(basename "$AGENTS_FILE")..." >&2 |
|
cp "$TEMP_WITH_MARKER" "$AGENTS_FILE" |
|
fi |
|
|
|
# Clean up temp files |
|
rm -f "$TEMP_AGENTS_FILE" "$TEMP_WITH_MARKER" |
|
else |
|
echo "Failed to fetch AGENTS.md from remote" >&2 |
|
# If we can't fetch, but file exists, use the existing one |
|
if [ -f "$BASE_AGENTS_FILE" ]; then |
|
AGENTS_FILE="$BASE_AGENTS_FILE" |
|
SHOULD_CREATE_FILE=false |
|
else |
|
echo "No existing AGENTS.md found and remote fetch failed" >&2 |
|
return 1 |
|
fi |
|
fi |
|
|
|
# Only fetch other documents if we're creating/updating AGENTS.md |
|
if [ "$SHOULD_CREATE_FILE" = true ]; then |
|
echo "Fetching additional documentation for processing..." >&2 |
|
|
|
# Fetch all other documents in parallel |
|
run_with_deps "fetch_bloc" "" "curl -s https://raw.githubusercontent.com/felangel/bloc/refs/heads/master/docs/src/content/docs/naming-conventions.mdx > /tmp/bloc_conventions.txt || echo \"Failed to fetch Bloc conventions\"" "$INITIAL_DIR" |
|
run_with_deps "fetch_commit" "" "curl -s https://raw.githubusercontent.com/conventional-commits/conventionalcommits.org/refs/heads/master/content/v1.0.0/index.md > /tmp/commit_conventions.txt || echo \"Failed to fetch Commit conventions\"" "$INITIAL_DIR" |
|
else |
|
echo "Using existing AGENTS.md, skipping additional downloads." >&2 |
|
fi |
|
|
|
# Fetch KDF API docs if needed (independent of AGENTS.md) |
|
if [[ "$SHOULD_FETCH_KDF_API_DOCS" == "true" ]]; then |
|
local KDF_FILE="$INITIAL_DIR/KDF_API_DOCUMENTATION.md" |
|
local KDF_MARKER="<!-- Generated by komodo_flutter_codex_env_setup.sh - KDF API Documentation -->" |
|
|
|
echo "Checking KDF API documentation..." >&2 |
|
|
|
# Check if KDF API docs need updating using similar logic |
|
local SHOULD_CREATE_KDF=true |
|
if [ -f "$KDF_FILE" ]; then |
|
if head -n 1 "$KDF_FILE" | grep -q "Generated by komodo_flutter_codex_env_setup.sh"; then |
|
# Check if file is recent (created within last 24 hours) |
|
local FILE_AGE=$(($(date +%s) - $(stat -c %Y "$KDF_FILE" 2>/dev/null || echo 0))) |
|
if [ $FILE_AGE -lt 86400 ]; then # 24 hours = 86400 seconds |
|
echo "KDF API documentation is recent (< 24h old), skipping download." >&2 |
|
SHOULD_CREATE_KDF=false |
|
fi |
|
fi |
|
fi |
|
|
|
if [ "$SHOULD_CREATE_KDF" = true ]; then |
|
echo "Updating KDF API documentation..." >&2 |
|
run_with_deps "fetch_kdf_api" "" " |
|
echo '$KDF_MARKER' > '$KDF_FILE' && |
|
echo '' >> '$KDF_FILE' && |
|
curl -s '$KDF_API_DOCS_URL' >> '$KDF_FILE' || |
|
echo 'Failed to fetch KDF API documentation' |
|
" "$INITIAL_DIR" |
|
fi |
|
fi |
|
|
|
# Return the AGENTS file path for processing (only stdout output) |
|
echo "$AGENTS_FILE" |
|
} |
|
|
|
# Enhanced process_agents_docs function that checks if processing is needed |
|
process_agents_docs() { |
|
local AGENTS_FILE=$1 |
|
|
|
# Check if the file already contains the appended content |
|
if grep -q "# Bloc and Commit Conventions" "$AGENTS_FILE" 2>/dev/null; then |
|
echo "AGENTS.md already contains appended content, skipping processing." >&2 |
|
return 0 |
|
fi |
|
|
|
echo "Processing AGENTS.md with additional content..." >&2 |
|
|
|
# Wait for all document fetching to complete (only if they were started) |
|
run_with_deps "process_agents" "fetch_bloc fetch_commit" " |
|
echo \"Appending bloc and commit conventions to $(basename '$AGENTS_FILE')\" |
|
echo -e \"\n# Bloc and Commit Conventions\n\" >>'$AGENTS_FILE' |
|
cat /tmp/bloc_conventions.txt >>'$AGENTS_FILE' |
|
echo -e \"\n# Commit Conventions\n\" >>'$AGENTS_FILE' |
|
cat /tmp/commit_conventions.txt >>'$AGENTS_FILE' |
|
echo \"$(basename '$AGENTS_FILE') processed successfully.\" |
|
" "$INITIAL_DIR" |
|
} |
|
|
|
# Setup repository-specific configurations |
|
if [[ "$GIT_REPO_NAME" == "komodo-wallet" ]]; then |
|
echo "Detected Komodo Wallet repository, running additional setup..." |
|
# Start document fetching process |
|
if [[ "$SHOULD_FETCH_AGENTS_DOCS" == "true" ]]; then |
|
AGENTS_FILE=$(fetch_all_docs) |
|
process_agents_docs "$AGENTS_FILE" |
|
fi |
|
# Additional setup for Komodo Wallet can be added here |
|
fi |
|
|
|
# Check if we are in the KDF SDK repository |
|
if [[ "$GIT_REPO_NAME" == "komodo-defi-sdk-flutter" ]]; then |
|
echo "Detected KDF SDK repository, running additional setup..." |
|
|
|
# Install melos if not already installed |
|
if ! command -v melos &>/dev/null; then |
|
echo "Downloading and installing melos..." |
|
if ! timeout 60 flutter pub global activate melos; then |
|
echo "ERROR: Melos installation failed. SDK setup may be incomplete." |
|
# Continue but warn user |
|
fi |
|
else |
|
echo "Melos already installed, skipping download" |
|
fi |
|
|
|
# Store the KDF SDK directory |
|
MELOS_DIR="$INITIAL_DIR" |
|
|
|
# Start document fetching process |
|
if [[ "$SHOULD_FETCH_AGENTS_DOCS" == "true" || "$SHOULD_FETCH_KDF_API_DOCS" == "true" ]]; then |
|
AGENTS_FILE=$(fetch_all_docs) |
|
if [[ "$SHOULD_FETCH_AGENTS_DOCS" == "true" ]]; then |
|
process_agents_docs "$AGENTS_FILE" |
|
fi |
|
fi |
|
|
|
# Run melos bootstrap |
|
echo "Running melos bootstrap..." |
|
if ! (cd "$MELOS_DIR" && timeout 180 melos bootstrap); then |
|
echo "ERROR: Melos bootstrap failed or timed out. SDK setup may be incomplete." |
|
# Continue but warn user |
|
fi |
|
|
|
# Go to the example directory for test-build to fetch KDF binaries |
|
if [ -d "$MELOS_DIR/packages/komodo_defi_sdk/example" ]; then |
|
cd "$MELOS_DIR/packages/komodo_defi_sdk/example" |
|
else |
|
echo "Warning: KDF example directory not found." |
|
fi |
|
fi |
|
|
|
# Optimize pub get and build_runner |
|
echo "Getting package dependencies..." |
|
if ! flutter pub get; then |
|
echo "ERROR: Flutter pub get failed. Package dependencies may be incomplete." |
|
echo "Attempting offline mode..." |
|
if ! flutter pub get --offline; then |
|
echo "ERROR: Flutter pub get failed in offline mode as well. Setup incomplete." |
|
# Continue but warn user |
|
fi |
|
fi |
|
|
|
# Check if build_runner is in pubspec.yaml |
|
if grep -q "build_runner" pubspec.yaml; then |
|
echo "Building Flutter app to generate assets..." |
|
if ! dart run build_runner build --delete-conflicting-outputs; then |
|
echo "WARN: Dart build_runner failed. Some generated files may be missing." |
|
echo "This is expected on first run if there are code generation issues." |
|
fi |
|
else |
|
echo "build_runner not found in pubspec.yaml, skipping code generation step." |
|
fi |
|
|
|
# Optimize web build - use a single, more efficient build |
|
echo "Building web app to fetch/generate assets..." |
|
if ! timeout 240 flutter build web --dart-define=FLUTTER_WEB_USE_SKIA=true --web-renderer=canvaskit --profile; then |
|
echo "WARN: Flutter web build failed or timed out. This is expected for initial code generation." |
|
# Continue - this is expected to fail |
|
fi |
|
|
|
# Return to the initial directory |
|
cd $INITIAL_DIR |
|
|
|
# Wait for any remaining background jobs |
|
wait_if_parallel |
|
|
|
# Update git exclude file |
|
update_git_exclude |
|
|
|
# Calculate and display execution time |
|
SCRIPT_END_TIME=$(date +%s) |
|
EXECUTION_TIME=$((SCRIPT_END_TIME - SCRIPT_START_TIME)) |
|
EXECUTION_PERCENTAGE=$((EXECUTION_TIME * 100 / MAX_EXECUTION_TIME)) |
|
|
|
echo "------------------------------------------------------------" |
|
echo "Script execution completed in ${EXECUTION_TIME} seconds" |
|
echo "Used ${EXECUTION_PERCENTAGE}% of maximum allowed time (${MAX_EXECUTION_TIME} seconds)" |
|
echo "------------------------------------------------------------" |
|
|
|
exit 0 |