mirror of
https://github.com/go-gitea/gitea.git
synced 2026-11-02 13:44:16 +09:00
enhance: replace tea CLI with gt (#40036)
tea has been replaced by [gitea-cli](https://gitea.com/gitea/cli) (`gt`), which reuses tea's OAuth2 client ID. - The repository clone panel now offers `gt repo clone owner/repo` under a "Gitea CLI" tab. - The built-in OAuth2 application is renamed from `tea` to `gitea-cli`. `tea` in `[oauth2] DEFAULT_APPLICATIONS` is still accepted as an alias, so existing configs keep working. - Instances that already registered the app keep its stored display name "tea".
This commit is contained in:
1 parent
c62e07f18a
commit
d3021b69ee
11 files changed
+36
-31
No files matched your search
@@ -68,7 +68,7 @@ Get more information from [the translation section of our contributing guide](CO
|
||||
|
||||
## Official and Third-Party Projects
|
||||
|
||||
We provide an official [go-sdk](https://gitea.com/gitea/go-sdk), a CLI tool called [tea](https://gitea.com/gitea/tea) and an [action runner](https://gitea.com/gitea/runner) for Gitea Action.
|
||||
We provide an official [go-sdk](https://gitea.com/gitea/go-sdk), a CLI tool called [gt](https://gitea.com/gitea/cli) and an [action runner](https://gitea.com/gitea/runner) for Gitea Action.
|
||||
|
||||
We maintain a list of Gitea-related projects at [gitea/awesome-gitea](https://gitea.com/gitea/awesome-gitea), where you can discover more third-party projects, including SDKs, plugins, themes, and more.
|
||||
|
||||
|
||||
+1
-1
@@ -76,7 +76,7 @@
|
||||
|
||||
## 官方和第三方项目
|
||||
|
||||
我们提供了一个官方的 [go-sdk](https://gitea.com/gitea/go-sdk),一个名为 [tea](https://gitea.com/gitea/tea) 的 CLI 工具和一个 Gitea Action 的 [action runner](https://gitea.com/gitea/runner)。
|
||||
我们提供了一个官方的 [go-sdk](https://gitea.com/gitea/go-sdk),一个名为 [gt](https://gitea.com/gitea/cli) 的 CLI 工具和一个 Gitea Action 的 [action runner](https://gitea.com/gitea/runner)。
|
||||
|
||||
我们在 [gitea/awesome-gitea](https://gitea.com/gitea/awesome-gitea) 维护了一个 Gitea 相关项目的列表,您可以在那里发现更多的第三方项目,包括 SDK、插件、主题等。
|
||||
|
||||
|
||||
+1
-1
@@ -76,7 +76,7 @@
|
||||
|
||||
## 官方和第三方項目
|
||||
|
||||
我們提供了一個官方的 [go-sdk](https://gitea.com/gitea/go-sdk),一個名為 [tea](https://gitea.com/gitea/tea) 的 CLI 工具和一個 Gitea Action 的 [action runner](https://gitea.com/gitea/runner)。
|
||||
我們提供了一個官方的 [go-sdk](https://gitea.com/gitea/go-sdk),一個名為 [gt](https://gitea.com/gitea/cli) 的 CLI 工具和一個 Gitea Action 的 [action runner](https://gitea.com/gitea/runner)。
|
||||
|
||||
我們在 [gitea/awesome-gitea](https://gitea.com/gitea/awesome-gitea) 維護了一個 Gitea 相關項目的列表,您可以在那裡發現更多的第三方項目,包括 SDK、插件、主題等。
|
||||
|
||||
|
||||
@@ -637,10 +637,10 @@ ENABLED = true
|
||||
;; Pre-register OAuth2 applications for some universally useful services
|
||||
;; * https://github.com/hickford/git-credential-oauth
|
||||
;; * https://github.com/git-ecosystem/git-credential-manager
|
||||
;; * https://gitea.com/gitea/tea
|
||||
;; * https://gitea.com/gitea/cli
|
||||
;; * Gitea App (the official Gitea mobile app)
|
||||
;; * https://gitea.com/gitea/gitea-vscode
|
||||
;DEFAULT_APPLICATIONS = git-credential-oauth, git-credential-manager, tea, gitea-app, gitea-vscode
|
||||
;DEFAULT_APPLICATIONS = git-credential-oauth, git-credential-manager, gitea-cli, gitea-app, gitea-vscode
|
||||
;;
|
||||
;; By default, OAuth2 applications can only use "http" and "https" as their redirect URI schemes.
|
||||
;; If you need to use other schemes (e.g. for desktop applications), you can specify them here as a comma-separated list.
|
||||
|
||||
@@ -78,8 +78,8 @@ func BuiltinApplications() map[string]*BuiltinOAuth2Application {
|
||||
RedirectURIs: []string{"http://127.0.0.1", "https://127.0.0.1"},
|
||||
}
|
||||
m["d57cb8c4-630c-4168-8324-ec79935e18d4"] = &BuiltinOAuth2Application{
|
||||
ConfigName: "tea",
|
||||
DisplayName: "tea",
|
||||
ConfigName: "gitea-cli",
|
||||
DisplayName: "gitea-cli",
|
||||
RedirectURIs: []string{"http://127.0.0.1", "https://127.0.0.1"},
|
||||
}
|
||||
m["b757811a-05c8-4c76-8d74-a5ee3d2073f2"] = &BuiltinOAuth2Application{
|
||||
|
||||
+5
-5
@@ -605,7 +605,7 @@ type CloneLink struct {
|
||||
|
||||
SSH string
|
||||
HTTPS string
|
||||
Tea string
|
||||
CLI string
|
||||
}
|
||||
|
||||
// ComposeHTTPSCloneURL returns HTTPS clone URL based on the given owner and repository name.
|
||||
@@ -656,9 +656,9 @@ func composeSSHCloneURL(doer *user_model.User, ownerName, repoName string, useUR
|
||||
return fmt.Sprintf("%s@%s:%s/%s.git", sshUser, sshHost, url.PathEscape(ownerName), url.PathEscape(repoName))
|
||||
}
|
||||
|
||||
// ComposeTeaCloneCommand returns Tea CLI clone command based on the given owner and repository name.
|
||||
func ComposeTeaCloneCommand(ctx context.Context, owner, repo string) string {
|
||||
return fmt.Sprintf("tea clone %s/%s", url.PathEscape(owner), url.PathEscape(repo))
|
||||
// ComposeCLICloneCommand returns the gt (gitea-cli) clone command based on the given owner and repository name.
|
||||
func ComposeCLICloneCommand(ctx context.Context, owner, repo string) string {
|
||||
return fmt.Sprintf("gt repo clone %s/%s", url.PathEscape(owner), url.PathEscape(repo))
|
||||
}
|
||||
|
||||
func (repo *Repository) cloneLink(ctx context.Context, doer *user_model.User, repoPathName string) *CloneLink {
|
||||
@@ -668,7 +668,7 @@ func (repo *Repository) cloneLink(ctx context.Context, doer *user_model.User, re
|
||||
SupportSSH: !setting.SSH.Disabled && (doer != nil || setting.SSH.ExposeAnonymous),
|
||||
SSH: ComposeSSHCloneURL(doer, repo.OwnerName, repoPathName),
|
||||
HTTPS: ComposeHTTPSCloneURL(ctx, repo.OwnerName, repoPathName),
|
||||
Tea: ComposeTeaCloneCommand(ctx, repo.OwnerName, repoPathName),
|
||||
CLI: ComposeCLICloneCommand(ctx, repo.OwnerName, repoPathName),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ var OAuth2 = struct {
|
||||
JWTSigningAlgorithm: "RS256",
|
||||
JWTSigningPrivateKeyFile: "jwt/private.pem",
|
||||
MaxTokenLength: math.MaxInt16,
|
||||
DefaultApplications: []string{"git-credential-oauth", "git-credential-manager", "tea", "gitea-app", "gitea-vscode"},
|
||||
DefaultApplications: []string{"git-credential-oauth", "git-credential-manager", "gitea-cli", "gitea-app", "gitea-vscode"},
|
||||
}
|
||||
|
||||
func loadOAuth2From(rootCfg ConfigProvider) {
|
||||
@@ -121,6 +121,11 @@ func loadOAuth2From(rootCfg ConfigProvider) {
|
||||
if sec.HasKey("DEFAULT_APPLICATIONS") && sec.Key("DEFAULT_APPLICATIONS").String() == "" {
|
||||
OAuth2.DefaultApplications = nil
|
||||
}
|
||||
for i, name := range OAuth2.DefaultApplications {
|
||||
if name == "tea" { // tea was renamed to gitea-cli, which kept its OAuth2 client ID
|
||||
OAuth2.DefaultApplications[i] = "gitea-cli"
|
||||
}
|
||||
}
|
||||
|
||||
if !filepath.IsAbs(OAuth2.JWTSigningPrivateKeyFile) {
|
||||
OAuth2.JWTSigningPrivateKeyFile = filepath.Join(AppDataPath, OAuth2.JWTSigningPrivateKeyFile)
|
||||
|
||||
@@ -64,13 +64,13 @@ func TestOauth2DefaultApplications(t *testing.T) {
|
||||
|
||||
cfg, _ := NewConfigProviderFromData(``)
|
||||
loadOAuth2From(cfg)
|
||||
assert.Equal(t, []string{"git-credential-oauth", "git-credential-manager", "tea", "gitea-app", "gitea-vscode"}, OAuth2.DefaultApplications)
|
||||
assert.Equal(t, []string{"git-credential-oauth", "git-credential-manager", "gitea-cli", "gitea-app", "gitea-vscode"}, OAuth2.DefaultApplications)
|
||||
|
||||
cfg, _ = NewConfigProviderFromData(`[oauth2]
|
||||
DEFAULT_APPLICATIONS = tea
|
||||
`)
|
||||
loadOAuth2From(cfg)
|
||||
assert.Equal(t, []string{"tea"}, OAuth2.DefaultApplications)
|
||||
assert.Equal(t, []string{"gitea-cli"}, OAuth2.DefaultApplications)
|
||||
|
||||
cfg, _ = NewConfigProviderFromData(`[oauth2]
|
||||
DEFAULT_APPLICATIONS =
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
{{if $showCloneLinks}}
|
||||
<div class="flex-text-block clone-panel-field">{{svg "octicon-terminal"}} Clone</div>
|
||||
<div class="clone-panel-tab">
|
||||
<!-- tea clone also uses the git HTTPS/SSH transports, so the whole clone section is hidden when both are disabled -->
|
||||
<!-- gt repo clone also uses the git HTTPS/SSH transports, so the whole clone section is hidden when both are disabled -->
|
||||
{{if $cloneLink.SupportHTTPS}}
|
||||
<button type="button" class="item repo-clone-https" data-link="{{$cloneLink.HTTPS}}">HTTPS</button>
|
||||
{{end}}
|
||||
@@ -21,7 +21,7 @@
|
||||
<button type="button" class="item repo-clone-ssh" data-link="{{$cloneLink.SSH}}">SSH</button>
|
||||
{{end}}
|
||||
{{if not $cloneLink.IsWikiRepo}}
|
||||
<button type="button" class="item repo-clone-tea" data-link="{{$cloneLink.Tea}}">Tea CLI</button>
|
||||
<button type="button" class="item repo-clone-cli" data-link="{{$cloneLink.CLI}}">Gitea CLI</button>
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="divider"></div>
|
||||
|
||||
@@ -186,9 +186,9 @@ func testViewRepo1CloneLinkAnonymous(t *testing.T) {
|
||||
_, exists = htmlDoc.doc.Find(".repo-clone-ssh").Attr("data-link")
|
||||
assert.False(t, exists)
|
||||
|
||||
link, exists = htmlDoc.doc.Find(".repo-clone-tea").Attr("data-link")
|
||||
link, exists = htmlDoc.doc.Find(".repo-clone-cli").Attr("data-link")
|
||||
assert.True(t, exists, "The template has changed")
|
||||
assert.Equal(t, "tea clone user2/repo1", link)
|
||||
assert.Equal(t, "gt repo clone user2/repo1", link)
|
||||
}
|
||||
|
||||
func testViewRepo1CloneLinkAuthorized(t *testing.T) {
|
||||
@@ -209,9 +209,9 @@ func testViewRepo1CloneLinkAuthorized(t *testing.T) {
|
||||
sshURL := fmt.Sprintf("ssh://%s@%s:%d/user2/repo1.git", setting.SSH.User, setting.SSH.Domain, setting.SSH.Port)
|
||||
assert.Equal(t, sshURL, link)
|
||||
|
||||
link, exists = htmlDoc.doc.Find(".repo-clone-tea").Attr("data-link")
|
||||
link, exists = htmlDoc.doc.Find(".repo-clone-cli").Attr("data-link")
|
||||
assert.True(t, exists, "The template has changed")
|
||||
assert.Equal(t, "tea clone user2/repo1", link)
|
||||
assert.Equal(t, "gt repo clone user2/repo1", link)
|
||||
}
|
||||
|
||||
func testViewRepoWithSymlinks(t *testing.T) {
|
||||
|
||||
@@ -59,24 +59,24 @@ function initRepoCloneButtonsCombo(parent: Element) {
|
||||
|
||||
const tabHttps = parent.querySelector('.repo-clone-https');
|
||||
const tabSsh = parent.querySelector('.repo-clone-ssh');
|
||||
const tabTea = parent.querySelector('.repo-clone-tea');
|
||||
const tabCli = parent.querySelector('.repo-clone-cli');
|
||||
const listOpenWithEditorApps = parent.querySelector('.repo-clone-with-apps');
|
||||
|
||||
// not every tab exists in every panel, eg: the admin may disable HTTP/SSH, and the empty repo page has no Tea CLI tab
|
||||
const tabByScheme: Record<string, Element | null> = {https: tabHttps, ssh: tabSsh, tea: tabTea};
|
||||
// not every tab exists in every panel, eg: the admin may disable HTTP/SSH, and the empty repo page has no Gitea CLI tab
|
||||
const tabByScheme: Record<string, Element | null> = {https: tabHttps, ssh: tabSsh, cli: tabCli};
|
||||
const updateClonePanelUi = function() {
|
||||
let scheme = localUserSettings.getString('repo-clone-protocol');
|
||||
// fall back to the first available tab when the preferred scheme's tab is absent (unset preference, or disabled protocol)
|
||||
if (!tabByScheme[scheme]) {
|
||||
scheme = ['https', 'ssh', 'tea'].find((s) => tabByScheme[s]) ?? '';
|
||||
scheme = ['https', 'ssh', 'cli'].find((s) => tabByScheme[s]) ?? '';
|
||||
}
|
||||
|
||||
const isHttps = scheme === 'https';
|
||||
const isSsh = scheme === 'ssh';
|
||||
const isTea = scheme === 'tea';
|
||||
const isCli = scheme === 'cli';
|
||||
|
||||
if (listOpenWithEditorApps) {
|
||||
toggleElem(listOpenWithEditorApps, !isTea); // don't show the "Open with editor apps" list when "Tea" clone is selected
|
||||
toggleElem(listOpenWithEditorApps, !isCli); // don't show the "Open with editor apps" list when "Gitea CLI" clone is selected
|
||||
}
|
||||
|
||||
if (tabHttps) {
|
||||
@@ -87,8 +87,8 @@ function initRepoCloneButtonsCombo(parent: Element) {
|
||||
if (tabSsh) {
|
||||
tabSsh.classList.toggle('active', isSsh);
|
||||
}
|
||||
if (tabTea) {
|
||||
tabTea.classList.toggle('active', isTea);
|
||||
if (tabCli) {
|
||||
tabCli.classList.toggle('active', isCli);
|
||||
}
|
||||
|
||||
const tab = tabByScheme[scheme];
|
||||
@@ -118,8 +118,8 @@ function initRepoCloneButtonsCombo(parent: Element) {
|
||||
localUserSettings.setString('repo-clone-protocol', 'ssh');
|
||||
updateClonePanelUi();
|
||||
});
|
||||
tabTea?.addEventListener('click', () => {
|
||||
localUserSettings.setString('repo-clone-protocol', 'tea');
|
||||
tabCli?.addEventListener('click', () => {
|
||||
localUserSettings.setString('repo-clone-protocol', 'cli');
|
||||
updateClonePanelUi();
|
||||
});
|
||||
elCloneUrlInput.addEventListener('focus', () => {
|
||||
|
||||
Reference in new issue
Block a user