Skip to content

Commit dbc1c23

Browse files
committed
feat!: Migrate imports from glean to glean.api_client
Add automated tool to transform glean package structure from flat to namespace package layout with Speakeasy regeneration detection. Includes comprehensive documentation and dry-run capabilities.
1 parent 57edf6a commit dbc1c23

File tree

3 files changed

+612
-13
lines changed

3 files changed

+612
-13
lines changed
Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
name: Patch Speakeasy PR
1+
name: Restructure Speakeasy PR
22

33
on:
44
pull_request:
55
types: [opened, synchronize]
6-
paths:
7-
- 'src/glean/__init__.py'
86
workflow_dispatch:
97

108
jobs:
@@ -21,17 +19,19 @@ jobs:
2119
ref: ${{ github.head_ref || github.ref_name }}
2220
fetch-depth: 0
2321

24-
- name: Patch glean/__init__.py with extend_path
25-
id: patch
22+
- name: Restructure glean package to namespace structure
2623
run: |
27-
OUTPUT=$GITHUB_OUTPUT .github/scripts/patch_extend_path.sh
24+
python scripts/restructure_to_namespace.py
2825
29-
- name: Commit and push if file changed
30-
if: steps.patch.outputs.patched == 'true'
26+
- name: Commit and push if files changed
3127
run: |
32-
git config --global user.name "github-actions[bot]"
33-
git config --global user.email "github-actions[bot]@users.noreply.github.com"
28+
if [ -n "$(git status --porcelain)" ]; then
29+
git config --global user.name "github-actions[bot]"
30+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
3431
35-
git add src/glean/__init__.py
36-
git commit -m "ci: ensure extend_path lines in glean/__init__.py" || echo "No changes to commit"
37-
git push origin HEAD:${{ github.head_ref || github.ref_name }}
32+
git add .
33+
git commit -m "ci: restructure glean package to namespace structure"
34+
git push origin HEAD:${{ github.head_ref || github.ref_name }}
35+
else
36+
echo "No changes detected"
37+
fi

scripts/README.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Restructuring Script
2+
3+
This directory contains a script to restructure the glean package from:
4+
5+
```
6+
src/glean/ # All implementation files
7+
```
8+
9+
To:
10+
11+
```
12+
src/glean/ # Implicit namespace package (no __init__.py)
13+
src/glean/api_client/ # All implementation files moved here
14+
```
15+
16+
## Usage
17+
18+
### Analyze what would change (recommended first step)
19+
20+
```bash
21+
python scripts/restructure_to_namespace.py --dry-run
22+
```
23+
24+
This shows you:
25+
26+
- Which files would be moved
27+
- Which import statements would be updated
28+
- Current state of the transformation
29+
30+
### Perform the restructuring
31+
32+
```bash
33+
python scripts/restructure_to_namespace.py
34+
```
35+
36+
This script:
37+
38+
- **Detects Speakeasy regeneration** and automatically handles it
39+
- Creates a backup and moves all files
40+
- Uses implicit namespace packages (no `__init__.py` needed)
41+
- Can be run multiple times safely
42+
- Updates all import statements throughout the codebase
43+
44+
## Smart Speakeasy Integration
45+
46+
The script automatically detects when Speakeasy has regenerated files:
47+
48+
1. **First run**: Moves everything to `api_client/`
49+
2. **After Speakeasy regeneration**: Detects new files in `src/glean/`, removes old `api_client/`, and re-runs the transformation
50+
3. **Subsequent runs**: Detects already-transformed structure and skips
51+
52+
This means you can safely run the script as part of your build process!
53+
54+
## Examples
55+
56+
```bash
57+
# First, see what would be changed
58+
python scripts/restructure_to_namespace.py --dry-run
59+
60+
# If it looks good, perform the restructuring
61+
python scripts/restructure_to_namespace.py
62+
63+
# Safe to run multiple times - it will detect and handle various states
64+
python scripts/restructure_to_namespace.py # Skips if already done
65+
python scripts/restructure_to_namespace.py # Auto-detects Speakeasy regeneration
66+
```
67+
68+
## What the restructuring does
69+
70+
1. **Creates a backup** of the current `src/glean` directory
71+
2. **Moves all files** from `src/glean/` to `src/glean/api_client/`
72+
3. **Creates an implicit namespace package** (no `__init__.py` - Python 3.3+ feature)
73+
4. **Updates all import statements** in tests, examples, and internal files
74+
5. **Handles Speakeasy regeneration** automatically
75+
76+
## After restructuring
77+
78+
Users will need to update their imports:
79+
80+
### Before
81+
82+
```python
83+
from glean import Glean, models, errors
84+
from glean.utils import parse_datetime
85+
```
86+
87+
### After
88+
89+
```python
90+
from glean.api_client import Glean, models, errors
91+
from glean.api_client.utils import parse_datetime
92+
93+
# Or use an alias for convenience:
94+
import glean.api_client as glean
95+
client = glean.Glean(...)
96+
```
97+
98+
## Workflow Integration
99+
100+
You can integrate this into your build process:
101+
102+
```bash
103+
# In your build script or CI
104+
speakeasy generate # Regenerates files to src/glean/
105+
python scripts/restructure_to_namespace.py # Automatically detects and re-transforms
106+
```
107+
108+
## Recovery
109+
110+
If something goes wrong, the script provides the path to the backup directory:
111+
112+
```bash
113+
rm -rf src/glean
114+
cp -r /path/to/backup/glean src/glean
115+
```
116+
117+
## Testing after restructuring
118+
119+
```bash
120+
# Run tests
121+
python -m pytest
122+
123+
# Try importing
124+
python -c "from glean.api_client import Glean; print('Success!')"
125+
```
126+

0 commit comments

Comments
 (0)