Browse Source

Merge branch 'main' into lunny/fix_compare

pull/29704/head
Lunny Xiao 2 months ago
parent
commit
f28a35920a

+ 4
- 8
modules/indexer/code/git.go View File

return nil, runErr return nil, runErr
} }


objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName)

var err error var err error
objectFormat, err := git.GetObjectFormatOfRepo(ctx, repo.RepoPath())
if err != nil {
return nil, err
}
changes.Updates, err = parseGitLsTreeOutput(objectFormat, stdout) changes.Updates, err = parseGitLsTreeOutput(objectFormat, stdout)
return &changes, err return &changes, err
} }
return nil, err return nil, err
} }


objectFormat, err := git.GetObjectFormatOfRepo(ctx, repo.RepoPath())
if err != nil {
return nil, err
}
objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName)

changes.Updates, err = parseGitLsTreeOutput(objectFormat, lsTreeStdout) changes.Updates, err = parseGitLsTreeOutput(objectFormat, lsTreeStdout)
return &changes, err return &changes, err
} }

+ 2
- 1
modules/markup/markdown/markdown.go View File

} }


// include language-x class as part of commonmark spec // include language-x class as part of commonmark spec
_, err = w.WriteString(`<code class="chroma language-` + string(language) + `">`)
// the "display" class is used by "js/markup/math.js" to render the code element as a block
_, err = w.WriteString(`<code class="chroma language-` + string(language) + ` display">`)
if err != nil { if err != nil {
return return
} }

+ 8
- 0
modules/markup/orgmode/orgmode.go View File

// so we need to try to guess the link kind again here // so we need to try to guess the link kind again here
kind = org.RegularLink{URL: link}.Kind() kind = org.RegularLink{URL: link}.Kind()
} }

base := r.Ctx.Links.Base base := r.Ctx.Links.Base
if r.Ctx.IsWiki {
base = r.Ctx.Links.WikiLink()
} else if r.Ctx.Links.HasBranchInfo() {
base = r.Ctx.Links.SrcLink()
}

if kind == "image" || kind == "video" { if kind == "image" || kind == "video" {
base = r.Ctx.Links.ResolveMediaLink(r.Ctx.IsWiki) base = r.Ctx.Links.ResolveMediaLink(r.Ctx.IsWiki)
} }

link = util.URLJoin(base, link) link = util.URLJoin(base, link)
} }
return link return link

+ 30
- 4
modules/markup/orgmode/orgmode_test.go View File

func TestRender_StandardLinks(t *testing.T) { func TestRender_StandardLinks(t *testing.T) {
setting.AppURL = AppURL setting.AppURL = AppURL


test := func(input, expected string) {
test := func(input, expected string, isWiki bool) {
buffer, err := RenderString(&markup.RenderContext{ buffer, err := RenderString(&markup.RenderContext{
Ctx: git.DefaultContext, Ctx: git.DefaultContext,
Links: markup.Links{ Links: markup.Links{
Base: "/relative-path", Base: "/relative-path",
BranchPath: "branch/main", BranchPath: "branch/main",
}, },
IsWiki: isWiki,
}, input) }, input)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
} }


test("[[https://google.com/]]", test("[[https://google.com/]]",
`<p><a href="https://google.com/">https://google.com/</a></p>`)
`<p><a href="https://google.com/">https://google.com/</a></p>`, false)
test("[[WikiPage][The WikiPage Desc]]", test("[[WikiPage][The WikiPage Desc]]",
`<p><a href="/relative-path/WikiPage">The WikiPage Desc</a></p>`)
`<p><a href="/relative-path/wiki/WikiPage">The WikiPage Desc</a></p>`, true)
test("[[ImageLink.svg][The Image Desc]]", test("[[ImageLink.svg][The Image Desc]]",
`<p><a href="/relative-path/media/branch/main/ImageLink.svg">The Image Desc</a></p>`)
`<p><a href="/relative-path/media/branch/main/ImageLink.svg">The Image Desc</a></p>`, false)
}

func TestRender_InternalLinks(t *testing.T) {
setting.AppURL = AppURL

test := func(input, expected string) {
buffer, err := RenderString(&markup.RenderContext{
Ctx: git.DefaultContext,
Links: markup.Links{
Base: "/relative-path",
BranchPath: "branch/main",
},
}, input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
}

test("[[file:test.org][Test]]",
`<p><a href="/relative-path/src/branch/main/test.org">Test</a></p>`)
test("[[./test.org][Test]]",
`<p><a href="/relative-path/src/branch/main/test.org">Test</a></p>`)
test("[[test.org][Test]]",
`<p><a href="/relative-path/src/branch/main/test.org">Test</a></p>`)
test("[[path/to/test.org][Test]]",
`<p><a href="/relative-path/src/branch/main/path/to/test.org">Test</a></p>`)
} }


func TestRender_Media(t *testing.T) { func TestRender_Media(t *testing.T) {

+ 1
- 6
routers/web/repo/branch.go View File

return return
} }


objectFormat, err := git.GetObjectFormatOfRepo(ctx, ctx.Repo.Repository.RepoPath())
if err != nil {
log.Error("RestoreBranch: CreateBranch: %w", err)
ctx.Flash.Error(ctx.Tr("repo.branch.restore_failed", deletedBranch.Name))
return
}
objectFormat := git.ObjectFormatFromName(ctx.Repo.Repository.ObjectFormatName)


// Don't return error below this // Don't return error below this
if err := repo_service.PushUpdate( if err := repo_service.PushUpdate(

+ 1
- 6
routers/web/repo/setting/webhook.go View File

commit := ctx.Repo.Commit commit := ctx.Repo.Commit
if commit == nil { if commit == nil {
ghost := user_model.NewGhostUser() ghost := user_model.NewGhostUser()
objectFormat, err := git.GetObjectFormatOfRepo(ctx, ctx.Repo.Repository.RepoPath())
if err != nil {
ctx.Flash.Error("GetObjectFormatOfRepo: " + err.Error())
ctx.Status(http.StatusInternalServerError)
return
}
objectFormat := git.ObjectFormatFromName(ctx.Repo.Repository.ObjectFormatName)
commit = &git.Commit{ commit = &git.Commit{
ID: objectFormat.EmptyObjectID(), ID: objectFormat.EmptyObjectID(),
Author: ghost.NewGitSig(), Author: ghost.NewGitSig(),

+ 1
- 4
services/mirror/mirror_pull.go View File

log.Error("SyncMirrors [repo: %-v]: unable to GetRefCommitID [ref_name: %s]: %v", m.Repo, result.refName, err) log.Error("SyncMirrors [repo: %-v]: unable to GetRefCommitID [ref_name: %s]: %v", m.Repo, result.refName, err)
continue continue
} }
objectFormat, err := git.GetObjectFormatOfRepo(ctx, m.Repo.RepoPath())
if err != nil {
log.Error("SyncMirrors [repo: %-v]: unable to GetHashTypeOfRepo: %v", m.Repo, err)
}
objectFormat := git.ObjectFormatFromName(m.Repo.ObjectFormatName)
notify_service.SyncPushCommits(ctx, m.Repo.MustOwner(ctx), m.Repo, &repo_module.PushUpdateOptions{ notify_service.SyncPushCommits(ctx, m.Repo.MustOwner(ctx), m.Repo, &repo_module.PushUpdateOptions{
RefFullName: result.refName, RefFullName: result.refName,
OldCommitID: objectFormat.EmptyObjectID().String(), OldCommitID: objectFormat.EmptyObjectID().String(),

+ 1
- 1
services/pull/pull.go View File

} }
if err == nil { if err == nil {
for _, pr := range prs { for _, pr := range prs {
objectFormat, _ := git.GetObjectFormatOfRepo(ctx, pr.BaseRepo.RepoPath())
objectFormat := git.ObjectFormatFromName(pr.BaseRepo.ObjectFormatName)
if newCommitID != "" && newCommitID != objectFormat.EmptyObjectID().String() { if newCommitID != "" && newCommitID != objectFormat.EmptyObjectID().String() {
changed, err := checkIfPRContentChanged(ctx, pr, oldCommitID, newCommitID) changed, err := checkIfPRContentChanged(ctx, pr, oldCommitID, newCommitID)
if err != nil { if err != nil {

+ 1
- 4
services/release/release.go View File

} }


refName := git.RefNameFromTag(rel.TagName) refName := git.RefNameFromTag(rel.TagName)
objectFormat, err := git.GetObjectFormatOfRepo(ctx, repo.RepoPath())
if err != nil {
return err
}
objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName)
notify_service.PushCommits( notify_service.PushCommits(
ctx, doer, repo, ctx, doer, repo,
&repository.PushUpdateOptions{ &repository.PushUpdateOptions{

+ 17
- 1
web_src/css/repo.css View File



.repository .data-table tr { .repository .data-table tr {
border-top: 0; border-top: 0;
background: none !important;
} }


.repository .data-table td, .repository .data-table td,
border: 1px solid var(--color-secondary); border: 1px solid var(--color-secondary);
} }


/* the border css competes with .markup where all tables have outer border which would add a double
border here, remove only the outer borders from this table */
.repository .data-table tr:first-child :is(td,th) {
border-top: none !important;
}
.repository .data-table tr:last-child :is(td,th) {
border-bottom: none !important;
}
.repository .data-table tr :is(td,th):first-child {
border-left: none !important;
}
.repository .data-table tr :is(td,th):last-child {
border-right: none !important;
}

.repository .data-table td { .repository .data-table td {
white-space: pre-line; white-space: pre-line;
} }
min-width: 50px; min-width: 50px;
font-family: monospace; font-family: monospace;
line-height: 20px; line-height: 20px;
color: var(--color-secondary-dark-2);
color: var(--color-text-light-1);
white-space: nowrap; white-space: nowrap;
vertical-align: top; vertical-align: top;
cursor: pointer; cursor: pointer;

+ 36
- 22
web_src/js/features/repo-issue-content.js View File

import $ from 'jquery'; import $ from 'jquery';
import {svg} from '../svg.js'; import {svg} from '../svg.js';
import {showErrorToast} from '../modules/toast.js'; import {showErrorToast} from '../modules/toast.js';
import {GET, POST} from '../modules/fetch.js';


const {appSubUrl, csrfToken} = window.config;
const {appSubUrl} = window.config;
let i18nTextEdited; let i18nTextEdited;
let i18nTextOptions; let i18nTextOptions;
let i18nTextDeleteFromHistory; let i18nTextDeleteFromHistory;
$dialog.find('.dialog-header-options').dropdown({ $dialog.find('.dialog-header-options').dropdown({
showOnFocus: false, showOnFocus: false,
allowReselection: true, allowReselection: true,
onChange(_value, _text, $item) {
async onChange(_value, _text, $item) {
const optionItem = $item.data('option-item'); const optionItem = $item.data('option-item');
if (optionItem === 'delete') { if (optionItem === 'delete') {
if (window.confirm(i18nTextDeleteFromHistoryConfirm)) { if (window.confirm(i18nTextDeleteFromHistoryConfirm)) {
$.post(`${issueBaseUrl}/content-history/soft-delete?comment_id=${commentId}&history_id=${historyId}`, {
_csrf: csrfToken,
}).done((resp) => {
try {
const params = new URLSearchParams();
params.append('comment_id', commentId);
params.append('history_id', historyId);

const response = await POST(`${issueBaseUrl}/content-history/soft-delete?${params.toString()}`);
const resp = await response.json();

if (resp.ok) { if (resp.ok) {
$dialog.modal('hide'); $dialog.modal('hide');
} else { } else {
showErrorToast(resp.message); showErrorToast(resp.message);
} }
});
} catch (error) {
console.error('Error:', error);
showErrorToast('An error occurred while deleting the history.');
}
} }
} else { // required by eslint } else { // required by eslint
showErrorToast(`unknown option item: ${optionItem}`); showErrorToast(`unknown option item: ${optionItem}`);
} }
}); });
$dialog.modal({ $dialog.modal({
onShow() {
$.ajax({
url: `${issueBaseUrl}/content-history/detail?comment_id=${commentId}&history_id=${historyId}`,
data: {
_csrf: csrfToken,
},
}).done((resp) => {
async onShow() {
try {
const params = new URLSearchParams();
params.append('comment_id', commentId);
params.append('history_id', historyId);

const url = `${issueBaseUrl}/content-history/detail?${params.toString()}`;
const response = await GET(url);
const resp = await response.json();

$dialog.find('.comment-diff-data').removeClass('is-loading').html(resp.diffHtml); $dialog.find('.comment-diff-data').removeClass('is-loading').html(resp.diffHtml);
// there is only one option "item[data-option-item=delete]", so the dropdown can be entirely shown/hidden. // there is only one option "item[data-option-item=delete]", so the dropdown can be entirely shown/hidden.
if (resp.canSoftDelete) { if (resp.canSoftDelete) {
$dialog.find('.dialog-header-options').removeClass('gt-hidden'); $dialog.find('.dialog-header-options').removeClass('gt-hidden');
} }
});
} catch (error) {
console.error('Error:', error);
}
}, },
onHidden() { onHidden() {
$dialog.remove(); $dialog.remove();
}); });
} }


export function initRepoIssueContentHistory() {
export async function initRepoIssueContentHistory() {
const issueIndex = $('#issueIndex').val(); const issueIndex = $('#issueIndex').val();
if (!issueIndex) return; if (!issueIndex) return;


const repoLink = $('#repolink').val(); const repoLink = $('#repolink').val();
const issueBaseUrl = `${appSubUrl}/${repoLink}/issues/${issueIndex}`; const issueBaseUrl = `${appSubUrl}/${repoLink}/issues/${issueIndex}`;


$.ajax({
url: `${issueBaseUrl}/content-history/overview`,
data: {
_csrf: csrfToken,
},
}).done((resp) => {
try {
const response = await GET(`${issueBaseUrl}/content-history/overview`);
const resp = await response.json();

i18nTextEdited = resp.i18n.textEdited; i18nTextEdited = resp.i18n.textEdited;
i18nTextDeleteFromHistory = resp.i18n.textDeleteFromHistory; i18nTextDeleteFromHistory = resp.i18n.textDeleteFromHistory;
i18nTextDeleteFromHistoryConfirm = resp.i18n.textDeleteFromHistoryConfirm; i18nTextDeleteFromHistoryConfirm = resp.i18n.textDeleteFromHistoryConfirm;
const $itemComment = $(`#issuecomment-${commentId}`); const $itemComment = $(`#issuecomment-${commentId}`);
showContentHistoryMenu(issueBaseUrl, $itemComment, commentId); showContentHistoryMenu(issueBaseUrl, $itemComment, commentId);
} }
});
} catch (error) {
console.error('Error:', error);
}
} }

Loading…
Cancel
Save