EXTRACTION.md

  1# Extracting an extension to dedicated repo
  2
  3These are some notes of how to extract an extension from the main zed repository and generate a new repository which preserves the history as best as possible. In the this example we will be extracting the `ruby` extension, substitute as appropriate.
  4
  5## Pre-requisites
  6
  7Install [git-filter-repo](https://github.com/newren/git-filter-repo/blob/main/INSTALL.md):
  8
  9```
 10brew install git-filter-repo
 11```
 12
 13## Process
 14
 151. Create an expressions.txt file somewhere (e.g. `~/projects/expressions.txt`)
 16
 17```
 18ruby: ==>
 19extension: ==>
 20chore: ==>
 21zed_extension_api: ==>
 22regex:(?<![\[a-zA-Z0-9])(#[0-9]{3,5})==>zed-industries/zed\1
 23```
 24
 25This file takes the form of `patern==>replacement`, where the replacement is optional.
 26Note whitespace matters so `ruby: ==>` is removing the `ruby:` prefix from a commit messages and adding a space after `==> ` means the replacement begins with a space. Regex capture groups are numbered `\1`, `\2`, etc.
 27
 28See: [Git Filter Repo Docs](https://htmlpreview.github.io/?https://github.com/newren/git-filter-repo/blob/docs/html/git-filter-repo.html) for more.
 29
 302. Create a clean clone the zed repository, delete tags, delete branches and do the work.
 31
 32> **Note**
 33> If you get `zsh: command not found: #` errors, run:
 34> `setopt interactive_comments && echo "setopt interactive_comments" >> ~/.zshrc`
 35
 36```sh
 37LANGNAME=ruby
 38rm -rf $LANGNAME
 39git clone --single-branch --no-tags git@github.com:zed-industries/zed.git $LANGNAME
 40cd $LANGNAME
 41
 42# This removes the LICENSE symlink
 43git filter-repo --invert-paths --path extensions/$LANGNAME/LICENSE-APACHE
 44
 45git filter-repo \
 46    --use-mailmap \
 47    --subdirectory-filter extensions/$LANGNAME/ \
 48    --path LICENSE-APACHE \
 49    --replace-message ~/projects/expressions.txt
 50```
 51
 523. Review the commits.
 53
 54This is your last chance to make any modifications.
 55If you don't fix it now, it'll be wrong forever.
 56
 57For example, a previous commit message was `php/ruby: bump version to 0.0.5`
 58which was replaced with `php/bump version to 0.0.5`
 59so I added a new line to expressions.txt with `php/==>`
 60and next run it became `bump version to 0.0.5`.
 61
 624. [Optional] Generate tags
 63
 64You can always add tags later, but it's a nice touch.
 65
 66Show you all commits that mention a version number:
 67
 68```sh
 69git log --grep="(\d+\.\d+\.\d+)" --perl-regexp --oneline --reverse
 70```
 71
 72Then just:
 73
 74```
 75git tag v0.0.2 abcd1234
 76git tag v0.0.3 deadbeef
 77```
 78
 79Usually the initial extraction didn't mention a version number so you can just do that one manually.
 80
 814. [Optional] Add a README.md and commit.
 82
 835. Push to the new repo
 84
 85Create a new empty repo on github under the [zed-extensions](https://github.com/organizations/zed-extensions/repositories/new) organization.
 86
 87```
 88git remote add origin git@github.com:zed-extensions/$LANGNAME
 89git push origin main --tags
 90git branch --set-upstream-to=origin/main main
 91```
 92
 936. Setup the new repository:
 94
 95- Go to the repository settings:
 96  - Disable Wikis
 97  - Uncheck "Allow Merge Commits"
 98  - Check "Allow Squash Merging"
 99    - Default commit message: "Pull request title and description"
100
1017. Publish a new version of the extension.
102
103```
104OLD_VERSION=$(grep '^version = ' extension.toml | cut -d'"' -f2)
105NEW_VERSION=$(echo "$OLD_VERSION" | awk -F. '{$NF = $NF + 1;} 1' OFS=.)
106echo $OLD_VERSION $NEW_VERSION
107perl -i -pe "s/$OLD_VERSION/$NEW_VERSION/" extension.toml
108
109# if there's rust code, update this too.
110test -f Cargo.toml && perl -i -pe "s/$OLD_VERSION/$NEW_VERSION/" cargo.toml
111test -f Cargo.toml && cargo check
112
113# commit and push
114git add -u
115git checkout -b "bump_${NEW_VERSION}"
116git commit -m "Bump to v${NEW_VERSION}"
117git push
118gh pr create --title "Bump to v${NEW_VERSION}" --web
119
120# merge PR in web interface
121git checkout main
122git pull
123git tag v${NEW_VERSION}
124git push origin v${NEW_VERSION}
125```
126
1277. In zed repository, `rm -rf extension/langname` and push a PR.
128
1298. Update extensions repository:
130
131```sh
132cd ../extensions
133git checkout main
134git pull
135git submodule init
136git submodule update
137git status
138
139git checkout -b ${LANGNAME}_v${NEW_VERSION}
140git submodule add https://github.com/zed-extensions/${LANGNAME}.git extensions/${LANGNAME}
141pnpm sort-extensions
142
143# edit extensions.toml:
144# - bump version
145# - change `submodule` from `extensions/zed` to new path
146# - remove `path` line all together
147
148git add extensions.toml .gitmodules extensions/${LANGNAME}
149git diff --cached
150git commit -m "Bump ${LANGNAME} to v${NEW_VERSION}"
151git push
152```
153
154Create PR and reference the Zed PR with removal from tree.