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

Local annotations setup and minor dependency handling #750

Open
wants to merge 6 commits into
base: future
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,9 @@ runtime/dgsh-tee
.vscode/*
.idea/*
.vs/*

#venv
venv/*

# Ignore local annotations path
local-annotations-path.txt
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ export PASH_TOP="$PWD/pash/"

For more details, manual installation, or other platforms see [installation instructions](./docs/install).

## Running with a local annotations library

To run with a local version of the library, please refer to the documentation [local annotations setup and usage](docs/local-annotations-library-documentation.md)

## Repo Structure

This repo hosts the core `pash` development. The structure is as follows:
Expand Down
8 changes: 8 additions & 0 deletions compiler/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,14 @@ def __init__(self, *args, **kwargs):
help=" output the preprocessed script",
action="store_true",
)
self.add_argument(
Copy link
Member

Choose a reason for hiding this comment

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

This is only useful for the help message, other than that the parsing of the argument just happens outside in pash_init_setup.sh so I am not sure whether all of these options (like nargs, const) are useful

"--local-annotations-dir",
help="Specify a local annotations directory instead of using the default one",
nargs="?", # <-- Makes it optional (accepts zero or one argument)
const="", # <-- Allows flag usage without an argument
type=str,
default=None,
)
self.add_argument(
"--interactive",
help="Executes the script using an interactive internal shell session (experimental)",
Expand Down
22 changes: 22 additions & 0 deletions compiler/orchestrator_runtime/pash_init_setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export pash_daemon_communicates_through_unix_pipes_flag=0
export pash_speculative_flag=0
export show_version=0
export distributed_exec=0
export local_annotations=0

for item in "$@"
do
Expand Down Expand Up @@ -87,11 +88,27 @@ do
if [ "--distributed_exec" == "$item" ]; then
export distributed_exec=1
fi

if [ "--local-annotations-dir" == "$item" ]; then
shift
export ANNOTATIONS_PATH=$(realpath "$2")
Copy link
Member

Choose a reason for hiding this comment

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

I found it surprising that this works with $2 here...

export local_annotations=1
export PYTHONPATH="$ANNOTATIONS_PATH:$PYTHONPATH"
#echo "✅ Using local annotations directory: $ANNOTATIONS_PATH"
fi
done

## `pash_redir_output` and `pash_redir_all_output` are strictly for logging.
##
## They do not execute their arguments if there is no debugging.
if [ "$local_annotations" -eq 1 ]; then
# Comment out the PyPI-installed `pash-annotations`
sed -i 's/^pash-annotations.*/#&/' "$PASH_TOP/requirements.txt"
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need to do that? At this point is anyone reading the requirements.txt?


# Add the local annotations path only if not already in `requirements.txt`
grep -qxF "-e $ANNOTATIONS_PATH" "$PASH_TOP/requirements.txt" || echo "-e $ANNOTATIONS_PATH" >> "$PASH_TOP/requirements.txt"
fi

if [ "$PASH_DEBUG_LEVEL" -eq 0 ]; then
pash_redir_output()
{
Expand Down Expand Up @@ -221,6 +238,11 @@ else
{
local daemon_pid=$1
## Only wait for daemon if it lives (it might be dead, rip)

##bring back the pypi annotations and remove the local annotations library
sed -i 's/^#\(pash-annotations.*\)$/\1/' "$PASH_TOP/requirements.txt"
sed -i "\|^-e $ANNOTATIONS_PATH|d" "$PASH_TOP/requirements.txt"

if ps -p "$daemon_pid" > /dev/null
then
## Send and receive from daemon
Expand Down
76 changes: 76 additions & 0 deletions docs/local-annotations-library-documentation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# PaSh Setup and Execution Guide

This guide walks you through **setting up and running PaSh**, including:
- Installing dependencies
- Running `setup-pash.sh` to install required tools
- Exporting `PASH_TOP`
- Running the `setup-annotations.sh` script to configure package installation with an optional `--local-annotations` flag

---

## **🔹 Step 1: Clone PaSh Repository (If Not Already Cloned)**
If you haven't already cloned PaSh, do so with:

```sh
git clone https://github.com/binpash/pash.git
cd pash
```

## **🔹 Step 2: Run setup-pash.sh to Install Dependencies and Build Runtime Tools**
PaSh includes a setup script that installs necessary dependencies and compiles missing runtime binaries.

Run:

```sh
./scripts/setup-pash.sh
```

Before using PaSh, set the `PASH_TOP` environment variable to the directory where PaSh is stored:

```sh
export PASH_TOP=/path/to/pash
```

To make this persistent across terminal sessions, add it to your shell configuration file:

```sh
echo 'export PASH_TOP=/path/to/pash' >> ~/.bashrc
source ~/.bashrc
```

## **🔹 Step 3: Run setup-annotations.sh to Configure Package Installation**
PaSh provides a script to configure dependencies, including an option to install local annotations.

To install dependencies normally:
Copy link
Member

Choose a reason for hiding this comment

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

Is this a typo?


To install local annotations:
```sh
./setup-local.sh
```

This will:
- Clone the `annotations` repository as a **sibling** to `pash` (i.e., in the same parent directory), or in a specified path if provided.
- Update `requirements.txt` to add the local `annotations` repo.

## **🔹 Step 4: Run PaSh**
Once everything is set up, test PaSh with:

```sh
cd pash/evaluation/intro
time $PASH_TOP/pa.sh $PASH_TOP/evaluation/intro/hello-world.sh
```

To run it with local annotation:
```sh
cd pash/evaluation/intro
time $PASH_TOP/pa.sh $PASH_TOP/evaluation/intro/hello-world.sh --local-annotations
```

You can also run the full PaSh test suite:
```sh
$PASH_TOP/evaluation/tests/test_evaluation_scripts.sh
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't run the PaSh test suite with the local annotations, why do you mention it then?

```
For more details, check the test script here:
[PaSh Evaluation Tests](https://github.com/binpash/pash/blob/main/evaluation/tests/test_evaluation_scripts.sh)


2 changes: 1 addition & 1 deletion evaluation/intro/hello-world.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[ $(uname) = 'Darwin' ] && a=/usr/share/dict/web2 || a=/usr/share/dict/words

if [ -f $a ]; then
cat $a $a $a $a $a $a $a $a | grep '\(.\).*\1\(.\).*\2\(.\).*\3\(.\).*\4' | wc -l
cat-wrapper $a $a $a $a $a $a $a $a | grep '\(.\).*\1\(.\).*\2\(.\).*\3\(.\).*\4' | wc -l
else
echo "Dictionary file $a not found.."
fi
Expand Down
1 change: 1 addition & 0 deletions local-annotations-path.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/home/divikchotani.linux/annotations
Copy link
Member

Choose a reason for hiding this comment

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

This should probably be git-ignored!

Copy link
Member

Choose a reason for hiding this comment

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

Or completely removed since it is not used anymore

30 changes: 30 additions & 0 deletions pa.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,24 @@ export PASH_TOP=${PASH_TOP:-${BASH_SOURCE%/*}}
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib/"
# point to the local downloaded folders
export PYTHONPATH="${PASH_TOP}/python_pkgs/:${PYTHONPATH}"
export ANNOTATIONS_PATH=$([ -f "$PASH_TOP/local-annotations-path.txt" ] && tr -d '[:space:]' < "$PASH_TOP/local-annotations-path.txt")
Copy link
Member

Choose a reason for hiding this comment

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

I see where you are going with this but it is very scary and a very big dependency for PaSh. I think the most appropriate way would be to modify PaSh's installation (scripts/setup_pash.sh) to copy the annotation repo in the right place. I could see two ways to do this:

  1. Either create a small installation script that replaces the annotation repo where pash looks for dependencies (https://github.com/binpash/pash/blob/future/scripts/setup-pash.sh#L37) and call it there (https://github.com/binpash/pash/blob/future/scripts/setup-pash.sh#L37). Then everytime the user modifies the annotation repo they will call this script and replace their local version of annotations. If we do that we also need to create a script that redownloads the latest normal annotations if needed.
  2. Properly add a new --local-annotations-dir option to PaSh (https://github.com/binpash/pash/blob/future/compiler/orchestrator_runtime/pash_init_setup.sh#L27) which could be used to update PYTHONPATH to point first to where the local annotation library is. I think this is the preferred solution if it works :)

Copy link
Member

Choose a reason for hiding this comment

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

Why do we need the changes in pa.sh now? I think we should delete all of them, I don't see why they are necessary.

#export PYTHONPATH="$ANNOTATIONS_PATH:$PYTHONPATH"
trap cleanup EXIT

## Function to restore `requirements.txt` on script exit
cleanup() {
if [ -f "$PASH_TOP/requirements_backup.txt" ]; then
mv "$PASH_TOP/requirements_backup.txt" "$PASH_TOP/requirements.txt"
fi

if [ "$PASH_DEBUG_LEVEL" -eq 0 ]; then
rm -rf "${PASH_TMP_PREFIX}"
fi
}

## Backup `requirements.txt`
cp "$PASH_TOP/requirements.txt" "$PASH_TOP/requirements_backup.txt"

## Register the signal handlers, we can add more signals here
trap kill_all SIGTERM SIGINT

Expand All @@ -25,6 +43,7 @@ if [ "$#" -eq 1 ] && [ "$1" = "--init" ]; then
exit
fi


if ! command -v python3 &> /dev/null
then
echo "Python >=3 could not be found"
Expand Down Expand Up @@ -54,6 +73,12 @@ export DSPASH_SOCKET="${PASH_TMP_PREFIX}/dspash_socket"
## Initialize all things necessary for pash to execute (logging/functions/etc)
source "$PASH_TOP/compiler/orchestrator_runtime/pash_init_setup.sh" "$@"

# Read annotations path if set

#echo $PYTHONPATH

# Ensure the local annotations directory is in `PYTHONPATH`

## This starts a different server depending on the configuration
if [ "$show_version" -eq 0 ]; then
## Exports $daemon_pid
Expand All @@ -73,4 +98,9 @@ if [ "$PASH_DEBUG_LEVEL" -eq 0 ]; then
rm -rf "${PASH_TMP_PREFIX}"
fi

sed -i 's/^#\(pash-annotations.*\)$/\1/' "$PASH_TOP/requirements.txt"
sed -i "s|^#-e $ANNOTATIONS_PATH|-e $ANNOTATIONS_PATH|" "$PASH_TOP/requirements.txt"

(exit "$pash_exit_code")


1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ libdash
pash-annotations==0.2.2
shasta==0.1.0
sh-expand>=0.1.6

37 changes: 37 additions & 0 deletions setup-local.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash

# Define the requirements file path
REQ_FILE="requirements.txt"

# Determine PaSh top directory
PASH_TOP=$(dirname "$(realpath "$0")")

# Default annotations directory (sibling of PASH_TOP)
DEFAULT_ANNOTATIONS_DIR="$(dirname "$PASH_TOP")/annotations"

# Use user-provided path if given, otherwise use default
if [ -n "$1" ]; then
ANNOTATIONS_DIR="$1"
ANNOTATIONS_DIR=$(realpath "$ANNOTATIONS_DIR")
else
ANNOTATIONS_DIR="$DEFAULT_ANNOTATIONS_DIR"
fi

echo "📂 Annotations directory set to: $ANNOTATIONS_DIR"

# Always clone the repository to the specified or default location
echo "🔄 Downloading annotations repository..."
rm -rf "$ANNOTATIONS_DIR"
git clone https://github.com/binpash/annotations.git "$ANNOTATIONS_DIR"

if [ $? -ne 0 ]; then
echo "❌ Failed to clone annotations repository."
exit 1
fi

# Get the absolute path
ANNOTATIONS_PATH=$(realpath "$ANNOTATIONS_DIR")
echo $ANNOTATIONS_PATH > local-annotations-path.txt
echo "✅ Annotations repository cloned to: $ANNOTATIONS_PATH"
grep -qxF "$ANNOTATIONS_PATH" requirements.txt || echo -e "\n-e $ANNOTATIONS_PATH" >> requirements.txt
Copy link
Member

Choose a reason for hiding this comment

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

Why do we modify requirements here? Why is this useful?


Loading