Skip to content
Merged
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
43 changes: 33 additions & 10 deletions .github/workflows/regression.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ jobs:
run_all_tests:
runs-on: ubuntu-latest
#if: "!contains(github.event.pull_request.title, '[NO-REGRESSION-TEST]')"
env:
LANGS: "go rust python java typescript"
steps:
- name: Setup Go environment
uses: actions/setup-go@v5
Expand All @@ -29,16 +31,21 @@ jobs:
with:
python-version: '3.11'

- name: Setup JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'

- name: Checkout pull request code
uses: actions/checkout@v4
with:
path: 'pr_repo'
submodules: true

- name: Install Python dependencies
run: |
pip install -r ./pr_repo/script/requirements.txt
pip install ./pr_repo/pylsp

- name: Checkout main branch code
uses: actions/checkout@v4
Expand All @@ -51,14 +58,26 @@ jobs:
(cd main_repo && go build -o ../abcoder_old)
(cd pr_repo && go build -o ../abcoder_new)

- name: Run test scripts and generate outputs
- name: Install evaluation dependencies
run: pip install -r ./pr_repo/script/requirements.txt

- name: Install LSPs
run: |
LANGS="go rust python" OUTDIR=out_old ABCEXE=./abcoder_old ./pr_repo/script/run_all_testdata.sh
LANGS="go rust python" OUTDIR=out_new ABCEXE=./abcoder_new ./pr_repo/script/run_all_testdata.sh
OUTDIR=out_new ABCEXE=./abcoder_new ./pr_repo/script/run_testdata.sh first
# use the same JDTLS for consistency and to avoid wasting time installing a duplicate JDTLS
echo "JDTLS_ROOT_PATH=$(realpath ./pr_repo/lang/java/lsp/jdtls/jdt-language-server-*)" >> $GITHUB_ENV

- name: Run OLD abcoder
run:
OUTDIR=out_old ABCEXE=./abcoder_old ./pr_repo/script/run_testdata.sh all

- name: Run NEW abcoder
run:
OUTDIR=out_new ABCEXE=./abcoder_new ./pr_repo/script/run_testdata.sh all

- name: Compare outputs and check for regression
id: diff_check
run: ./pr_repo/script/diffjson.py out_old out_new
run: ./pr_repo/script/diffjson.py out_old out_new || echo "failed=true" >> $GITHUB_OUTPUT
continue-on-error: true

- name: Upload output directories
Expand All @@ -70,3 +89,7 @@ jobs:
out_old
out_new
retention-days: 3

- name: Status check
if: steps.diff_check.outputs.failed == 'true'
run: exit 1
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,19 @@ see [UniAST Specification](docs/uniast-zh.md)
2. Use ABCoder to parse a repository to UniAST (JSON)

```bash
abcoder parse {language} {repo-path} > xxx.json
abcoder parse {language} {repo-path} -o xxx.json
```

ABCoder will try to install any dependency automatically.
In case of failure (or if you want to customize installation), refer to the [docs](./docs/lsp-installation-en.md).

For example, to parse a Go repository:

```bash
git clone https://github.com/cloudwego/localsession.git localsession
abcoder parse go localsession -o /abcoder-asts/localsession.json
```

To parse repositories in other languages, [install the corresponding language server first](./docs/lsp-installation-en.md).

3. Integrate ABCoder's MCP tools into your AI agent.

Expand Down
5 changes: 0 additions & 5 deletions lang/python/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ package python

import (
"fmt"
"os"
"os/exec"
"regexp"
"strconv"
Expand Down Expand Up @@ -63,10 +62,6 @@ func InstallLanguageServer() (string, error) {
log.Info("pylsp already installed: %v", out)
return lspName, nil
}
if _, err := os.Stat("go.mod"); os.IsNotExist(err) {
log.Error("Auto installation requires working directory to be /path/to/abcoder/")
return "", fmt.Errorf("bad cwd")
}
if err := CheckPythonVersion(); err != nil {
log.Error("python version check failed: %v", err)
return "", err
Expand Down
40 changes: 0 additions & 40 deletions script/run_all_testdata.sh

This file was deleted.

81 changes: 81 additions & 0 deletions script/run_testdata.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/bin/bash
# Generate uniast for all testdata.
#
# USAGE:
# 1. Save the uniast for all testdata to out/
# $ OUTDIR=out/ ./script/run_testdata.sh all
#
# 2. Save the uniast for the first testdata item (0_*) in each language to out/
# $ OUTDIR=out/ ./script/run_testdata.sh first
#
# 3. Use a custom abcoder executable
# OUTDIR=out/ ABCEXE="./other_abcoder" ./script/run_testdata.sh all

if [[ "$1" != "all" && "$1" != "first" ]]; then
echo "Usage: $0 all|first [--dry-run|-n]" >&2
echo " all: Run on all testdata." >&2
echo " first: Run only on testdata starting with '0_*' in each language directory." >&2
echo " --dry-run|-n: Print commands without executing them." >&2
exit 1
fi

MODE=$1
DRY_RUN=false
if [[ "$2" == "--dry-run" || "$2" == "-n" ]]; then
DRY_RUN=true
fi

SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
REPO_ROOT=$(realpath --relative-to=$(pwd) "$SCRIPT_DIR/..")

ABCEXE=${ABCEXE:-"$REPO_ROOT/abcoder"}
OUTDIR=${OUTDIR:?Error: OUTDIR is a mandatory environment variable}
PARALLEL_FLAGS=${PARALLEL_FLAGS:---tag}
LANGS=${LANGS:-"go rust python cxx"}

detect_jobs() {
local ABCEXE=${1:-$ABCEXE}
for lang in ${LANGS[@]}; do
local repo_glob="$REPO_ROOT/testdata/$lang/*"
if [[ "$MODE" == "first" ]]; then
repo_glob="$REPO_ROOT/testdata/$lang/0_*"
fi
for repo in $repo_glob; do
# Skip if glob doesn't match anything to avoid errors
[[ -e "$repo" ]] || continue
local rel_path=$(realpath --no-symlinks --relative-to="$REPO_ROOT/testdata" "$repo")
local outname=$(echo "$rel_path" | sed 's/[/:? ]/_/g')
echo $ABCEXE parse $lang $repo -o $OUTDIR/$outname.json
done
done
}

if [[ ! -x "$ABCEXE" ]]; then
echo "Error: The specified abcoder executable '$ABCEXE' does not exist or is not executable." >&2
exit 1
fi
mkdir -pv "$OUTDIR"
detect_jobs
if $DRY_RUN ; then
exit 0
fi
echo
detect_jobs | parallel $PARALLEL_FLAGS -j$(nproc --all) --jobs 0 "eval {}" 2>&1

echo
echo "Verifying that all expected output files were generated..."
all_files_exist=true
# Rerun detect_jobs to get the list of expected json files and check for their existence.
for file_path in $(detect_jobs | awk '{print $NF}'); do
if [[ ! -f "$file_path" ]]; then
echo "Error: Expected output file does not exist: $file_path" >&2
all_files_exist=false
fi
done

if [[ "$all_files_exist" == "false" ]]; then
echo "One or more output files are missing. Failing." >&2
exit 1
else
echo "All expected output files were successfully generated."
fi
1 change: 1 addition & 0 deletions testdata/typescript/0_test-repo
Loading