Skip to content

fix(sdk): match literal suffixes after leading dockerignore globstars - #1934

Draft
siye566 wants to merge 2 commits into
e2b-dev:mainfrom
siye566:fix/dockerignore-leading-globstar-suffix
Draft

siye566 wants to merge 2 commits into
e2b-dev:mainfrom
siye566:fix/dockerignore-leading-globstar-suffix

Conversation

@siye566

@siye566 siye566 commented Oct 2, 2026 •

Copy link
Copy Markdown

Summary

Follow-up to #1917. The Dockerignore port currently compiles **.txt to an optional directory prefix followed by the literal .txt, so root.txt and src/nested.txt remain in the template copy file list.

Moby uses suffix matching when a leading ** is followed only by literal characters. Apply that case in both SDKs while leaving the existing regex path unchanged for additional wildcard syntax. Python sync and async templates share this matcher. No new dependencies.

  • Cover root/nested files, literal regex characters, negation/re-inclusion, and patterns containing subsequent *, ?, or bracket expressions.
  • Include a patch changeset for e2b and @e2b/python-sdk.

Usage example

With **.txt in .dockerignore, copying a context containing root.txt, src/nested.txt, and keep.txt.bak now excludes the first two and retains the backup. !**.ts re-includes matching files under excluded directories.

Validation

  • Before the fix: the initial file-selection regression failed in both JS and Python because root.txt was still included.
  • pnpm --dir packages/js-sdk run test --project template tests/template/utils: 89 passed, 1 skipped.
  • uv run pytest tests/shared/template/utils -k 'not test_should_handle_symlinks and not test_should_resolve_symlinks_when_enabled and not test_should_preserve_symlinks_when_disabled' -q: 96 passed, 1 skipped, 3 deselected.
  • JS SDK format, lint, typecheck, and build completed successfully.
  • Python SDK ruff check ., ruff format --check ., and ty check passed.
  • Prettier checks for the changeset and changed JS files and git diff --cached --check passed.

Tested on Windows with Node 22.23.2, Python 3.12.14, and pnpm 10.34.5. The three deselected existing Python tests fail with WinError 1314 (symlink privilege unavailable); the directory-symlink test is already skipped on Windows. GNU Make is unavailable, so the Python Makefile's actual commands were run directly. Validation was SDK-scoped; the whole-workspace commands and live cloud suites were not run, and no E2B credentials were used.

AI-assisted with Codex; the commands above were executed locally.


Devin Review

@siye566
siye566 requested a review from mishushakov as a code owner October 2, 2026 15:05
@cla-bot

cla-bot Bot commented Oct 2, 2026

Copy link
Copy Markdown

We require contributors to sign our Contributor License Agreement, and we don't have @siye566 on file. You can sign our CLA at https://e2b.dev/docs/cla . Once you've signed, post a comment here that says '@cla-bot check'

@changeset-bot

changeset-bot Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 78010e7

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
e2b Patch
@e2b/python-sdk Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

TASTE.md review: complies — 0 violations (checked JS/Python parity T-1/T-2, error classes T-42/T-57–T-59, enum/literal rules T-15, docs T-69–T-71; changes are confined to private matcher helpers compile/_compile with identical logic in both SDKs and no public surface change).

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

Devin Review

and not _WILDCARD_CHARS.search(suffix)
and "]" not in suffix
):
return re.compile("^.*" + re.escape(suffix) + "$")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Globstar suffixes misclassify newline filenames

With **.txt, _compile retains a\n.txt and excludes a.txt\n. Regex . cannot cross newlines, while $ matches before a trailing newline. The JS matcher has the same behavior.

Learn more

The matcher compiles a leading globstar and literal suffix into a regular expression. Python's . does not match a newline unless DOTALL is enabled, and $ also matches just before a final newline. The same defaults apply in the JS matcher. Filenames can contain newlines, so both cases disagree with literal suffix matching and affect template file selection.

Example: Given **.txt, a\n.txt must be ignored but stays in the copy list; a.txt\n must remain in the list but is ignored.

Recommended fix: Check path.endswith(suffix) / path.endsWith(suffix) directly for this branch, or use a newline-safe regex prefix and a true end-of-string assertion in both SDKs. Add matching tests for embedded and trailing newlines.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good catch — fixed in 78010e7. Both SDKs now do a true literal suffix match that is newline-safe:

  • Python: the suffix branch compiles with re.DOTALL and anchors with \Z instead of $ (Python's $ also matches just before a trailing newline, and . does not cross newlines by default), so a\n.txt is ignored and a.txt\n stays in the copy list.
  • JS: same branch now uses the s (dotAll) flag; $ without m already anchors to the absolute end of input, so only the embedded-newline direction was broken there.

Added string-level PatternMatcher unit tests in both SDKs (packages/python-sdk/tests/shared/template/utils/test_dockerignore_matcher.py, packages/js-sdk/tests/template/dockerignore.test.ts) covering normal, embedded-newline and trailing-newline names, plus extended the changeset. Red-green verified: the newline cases fail without each fix and pass with it; ruff/oxlint/prettier/tsc clean.

@siye566

siye566 commented Oct 2, 2026

Copy link
Copy Markdown
Author

@cla-bot check

@cla-bot

cla-bot Bot commented Oct 2, 2026

Copy link
Copy Markdown

We require contributors to sign our Contributor License Agreement, and we don't have @siye566 on file. You can sign our CLA at https://e2b.dev/docs/cla . Once you've signed, post a comment here that says '@cla-bot check'

@cla-bot

cla-bot Bot commented Oct 2, 2026

Copy link
Copy Markdown

The cla-bot has been summoned, and re-checked this pull request!

@siye566

siye566 commented Oct 3, 2026

Copy link
Copy Markdown
Author

@cla-bot check

@cla-bot cla-bot Bot added the cla-signed label Oct 3, 2026
@cla-bot

cla-bot Bot commented Oct 3, 2026

Copy link
Copy Markdown

The cla-bot has been summoned, and re-checked this pull request!

Follow-up to the leading-globstar literal-suffix fix (e2b-dev#1933), addressing a review comment on e2b-dev#1934: the suffix branch compiled to a plain regex where '.' does not cross newlines and (in Python) '$' also matches just before a trailing newline, so a filename containing a newline was matched wrongly in both directions.

- Python: compile the suffix branch with re.DOTALL and anchor with '\Z', not '$'.
- JS: add the 's' (dotAll) flag; '$' without 'm' already anchors to the absolute end.
- Add string-level PatternMatcher unit tests in both SDKs covering normal, embedded-newline and trailing-newline names (deterministic, no filesystem).
- Extend the changeset with the newline semantics.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant