mirror of
https://github.com/go-gitea/gitea.git
synced 2025-02-27 16:07:39 +08:00
Merge branch 'main' into main
This commit is contained in:
commit
abc5d12590
@ -324,6 +324,10 @@ RUN_USER = ; git
|
||||
;; Maximum number of locks returned per page
|
||||
;LFS_LOCKS_PAGING_NUM = 50
|
||||
;;
|
||||
;; When clients make lfs batch requests, reject them if there are more pointers than this number
|
||||
;; zero means 'unlimited'
|
||||
;LFS_MAX_BATCH_SIZE = 0
|
||||
;;
|
||||
;; Allow graceful restarts using SIGHUP to fork
|
||||
;ALLOW_GRACEFUL_RESTARTS = true
|
||||
;;
|
||||
@ -2638,6 +2642,10 @@ LEVEL = Info
|
||||
;; override the azure blob base path if storage type is azureblob
|
||||
;AZURE_BLOB_BASE_PATH = lfs/
|
||||
|
||||
;[lfs_client]
|
||||
;; When mirroring an upstream lfs endpoint, limit the number of pointers in each batch request to this number
|
||||
;BATCH_SIZE = 20
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; settings for packages, will override storage setting
|
||||
|
@ -16,10 +16,9 @@ import (
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/proxy"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
const httpBatchSize = 20
|
||||
|
||||
// HTTPClient is used to communicate with the LFS server
|
||||
// https://github.com/git-lfs/git-lfs/blob/main/docs/api/batch.md
|
||||
type HTTPClient struct {
|
||||
@ -30,7 +29,7 @@ type HTTPClient struct {
|
||||
|
||||
// BatchSize returns the preferred size of batchs to process
|
||||
func (c *HTTPClient) BatchSize() int {
|
||||
return httpBatchSize
|
||||
return setting.LFSClient.BatchSize
|
||||
}
|
||||
|
||||
func newHTTPClient(endpoint *url.URL, httpTransport *http.Transport) *HTTPClient {
|
||||
|
@ -10,7 +10,10 @@ import (
|
||||
"code.gitea.io/gitea/modules/generate"
|
||||
)
|
||||
|
||||
// LFS represents the configuration for Git LFS
|
||||
// LFS represents the server-side configuration for Git LFS.
|
||||
// Ideally these options should be in a section like "[lfs_server]",
|
||||
// but they are in "[server]" section due to historical reasons.
|
||||
// Could be refactored in the future while keeping backwards compatibility.
|
||||
var LFS = struct {
|
||||
StartServer bool `ini:"LFS_START_SERVER"`
|
||||
AllowPureSSH bool `ini:"LFS_ALLOW_PURE_SSH"`
|
||||
@ -18,15 +21,21 @@ var LFS = struct {
|
||||
HTTPAuthExpiry time.Duration `ini:"LFS_HTTP_AUTH_EXPIRY"`
|
||||
MaxFileSize int64 `ini:"LFS_MAX_FILE_SIZE"`
|
||||
LocksPagingNum int `ini:"LFS_LOCKS_PAGING_NUM"`
|
||||
MaxBatchSize int `ini:"LFS_MAX_BATCH_SIZE"`
|
||||
|
||||
Storage *Storage
|
||||
}{}
|
||||
|
||||
// LFSClient represents configuration for Gitea's LFS clients, for example: mirroring upstream Git LFS
|
||||
var LFSClient = struct {
|
||||
BatchSize int `ini:"BATCH_SIZE"`
|
||||
}{}
|
||||
|
||||
func loadLFSFrom(rootCfg ConfigProvider) error {
|
||||
mustMapSetting(rootCfg, "lfs_client", &LFSClient)
|
||||
|
||||
mustMapSetting(rootCfg, "server", &LFS)
|
||||
sec := rootCfg.Section("server")
|
||||
if err := sec.MapTo(&LFS); err != nil {
|
||||
return fmt.Errorf("failed to map LFS settings: %v", err)
|
||||
}
|
||||
|
||||
lfsSec, _ := rootCfg.GetSection("lfs")
|
||||
|
||||
@ -53,6 +62,10 @@ func loadLFSFrom(rootCfg ConfigProvider) error {
|
||||
LFS.LocksPagingNum = 50
|
||||
}
|
||||
|
||||
if LFSClient.BatchSize < 1 {
|
||||
LFSClient.BatchSize = 20
|
||||
}
|
||||
|
||||
LFS.HTTPAuthExpiry = sec.Key("LFS_HTTP_AUTH_EXPIRY").MustDuration(24 * time.Hour)
|
||||
|
||||
if !LFS.StartServer || !InstallLock {
|
||||
|
@ -99,3 +99,19 @@ STORAGE_TYPE = minio
|
||||
assert.EqualValues(t, "gitea", LFS.Storage.MinioConfig.Bucket)
|
||||
assert.EqualValues(t, "lfs/", LFS.Storage.MinioConfig.BasePath)
|
||||
}
|
||||
|
||||
func Test_LFSClientServerConfigs(t *testing.T) {
|
||||
iniStr := `
|
||||
[server]
|
||||
LFS_MAX_BATCH_SIZE = 100
|
||||
[lfs_client]
|
||||
# will default to 20
|
||||
BATCH_SIZE = 0
|
||||
`
|
||||
cfg, err := NewConfigProviderFromData(iniStr)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.NoError(t, loadLFSFrom(cfg))
|
||||
assert.EqualValues(t, 100, LFS.MaxBatchSize)
|
||||
assert.EqualValues(t, 20, LFSClient.BatchSize)
|
||||
}
|
||||
|
16
package-lock.json
generated
16
package-lock.json
generated
@ -47,7 +47,6 @@
|
||||
"sortablejs": "1.15.2",
|
||||
"swagger-ui-dist": "5.17.14",
|
||||
"tailwindcss": "3.4.10",
|
||||
"temporal-polyfill": "0.2.5",
|
||||
"throttle-debounce": "5.0.2",
|
||||
"tinycolor2": "1.6.0",
|
||||
"tippy.js": "6.3.7",
|
||||
@ -14748,21 +14747,6 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/temporal-polyfill": {
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/temporal-polyfill/-/temporal-polyfill-0.2.5.tgz",
|
||||
"integrity": "sha512-ye47xp8Cb0nDguAhrrDS1JT1SzwEV9e26sSsrWzVu+yPZ7LzceEcH0i2gci9jWfOfSCCgM3Qv5nOYShVUUFUXA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"temporal-spec": "^0.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/temporal-spec": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/temporal-spec/-/temporal-spec-0.2.4.tgz",
|
||||
"integrity": "sha512-lDMFv4nKQrSjlkHKAlHVqKrBG4DyFfa9F74cmBZ3Iy3ed8yvWnlWSIdi4IKfSqwmazAohBNwiN64qGx4y5Q3IQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/terser": {
|
||||
"version": "5.31.6",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz",
|
||||
|
@ -46,7 +46,6 @@
|
||||
"sortablejs": "1.15.2",
|
||||
"swagger-ui-dist": "5.17.14",
|
||||
"tailwindcss": "3.4.10",
|
||||
"temporal-polyfill": "0.2.5",
|
||||
"throttle-debounce": "5.0.2",
|
||||
"tinycolor2": "1.6.0",
|
||||
"tippy.js": "6.3.7",
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
)
|
||||
|
||||
@ -39,7 +40,7 @@ func Organizations(ctx *context.Context) {
|
||||
)
|
||||
sortOrder := ctx.FormString("sort")
|
||||
if sortOrder == "" {
|
||||
sortOrder = "newest"
|
||||
sortOrder = util.Iif(supportedSortOrders.Contains(setting.UI.ExploreDefaultSort), setting.UI.ExploreDefaultSort, "newest")
|
||||
ctx.SetFormString("sort", sortOrder)
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/sitemap"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
)
|
||||
|
||||
@ -149,7 +150,7 @@ func Users(ctx *context.Context) {
|
||||
)
|
||||
sortOrder := ctx.FormString("sort")
|
||||
if sortOrder == "" {
|
||||
sortOrder = "newest"
|
||||
sortOrder = util.Iif(supportedSortOrders.Contains(setting.UI.ExploreDefaultSort), setting.UI.ExploreDefaultSort, "newest")
|
||||
ctx.SetFormString("sort", sortOrder)
|
||||
}
|
||||
|
||||
|
@ -179,6 +179,11 @@ func BatchHandler(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if setting.LFS.MaxBatchSize != 0 && len(br.Objects) > setting.LFS.MaxBatchSize {
|
||||
writeStatus(ctx, http.StatusRequestEntityTooLarge)
|
||||
return
|
||||
}
|
||||
|
||||
contentStore := lfs_module.NewContentStore()
|
||||
|
||||
var responseObjects []*lfs_module.ObjectResponse
|
||||
|
@ -102,7 +102,7 @@
|
||||
{{$sameBase := ne $.BaseName $.HeadUserName}}
|
||||
{{$differentBranch := ne . $.HeadBranch}}
|
||||
{{if or $sameBase $differentBranch}}
|
||||
<div class="item {{if eq $.BaseBranch .}}selected{{end}}" data-branch="{{.}}">{{$.BaseName}}{{if $.HeadRepo}}/{{$.HeadRepo}}{{end}}:{{.}}</div>
|
||||
<div class="item {{if eq $.BaseBranch .}}selected{{end}}" data-branch="{{.}}">{{$.BaseName}}:{{.}}</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</div>
|
||||
|
@ -17,7 +17,7 @@ const colors = ref({
|
||||
const activityTopAuthors = window.config.pageData.repoActivityTopAuthors || [];
|
||||
|
||||
const graphPoints = computed(() => {
|
||||
return activityTopAuthors.value.map((item) => {
|
||||
return activityTopAuthors.map((item) => {
|
||||
return {
|
||||
value: item.commits,
|
||||
label: item.name,
|
||||
@ -26,7 +26,7 @@ const graphPoints = computed(() => {
|
||||
});
|
||||
|
||||
const graphAuthors = computed(() => {
|
||||
return activityTopAuthors.value.map((item, idx) => {
|
||||
return activityTopAuthors.map((item, idx) => {
|
||||
return {
|
||||
position: idx + 1,
|
||||
...item,
|
||||
@ -35,7 +35,7 @@ const graphAuthors = computed(() => {
|
||||
});
|
||||
|
||||
const graphWidth = computed(() => {
|
||||
return activityTopAuthors.value.length * 40;
|
||||
return activityTopAuthors.length * 40;
|
||||
});
|
||||
|
||||
const styleElement = ref<HTMLElement | null>(null);
|
||||
|
@ -7,9 +7,15 @@ test('toAbsoluteLocaleDate', () => {
|
||||
day: 'numeric',
|
||||
})).toEqual('March 15, 2024');
|
||||
|
||||
expect(toAbsoluteLocaleDate('2024-03-15', 'de-DE', {
|
||||
expect(toAbsoluteLocaleDate('2024-03-15T01:02:03', 'de-DE', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
})).toEqual('15. März 2024');
|
||||
|
||||
expect(toAbsoluteLocaleDate('12345-03-15 01:02:03', '', {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
})).toEqual('Mar 15, 12345');
|
||||
});
|
||||
|
@ -1,30 +1,28 @@
|
||||
import {Temporal} from 'temporal-polyfill';
|
||||
|
||||
export function toAbsoluteLocaleDate(dateStr, lang, opts) {
|
||||
return Temporal.PlainDate.from(dateStr).toLocaleString(lang ?? [], opts);
|
||||
export function toAbsoluteLocaleDate(date: string, lang: string, opts: Intl.DateTimeFormatOptions) {
|
||||
return new Date(date).toLocaleString(lang || [], opts);
|
||||
}
|
||||
|
||||
window.customElements.define('absolute-date', class extends HTMLElement {
|
||||
static observedAttributes = ['date', 'year', 'month', 'weekday', 'day'];
|
||||
|
||||
initialized = false;
|
||||
|
||||
update = () => {
|
||||
const year = this.getAttribute('year') ?? '';
|
||||
const month = this.getAttribute('month') ?? '';
|
||||
const weekday = this.getAttribute('weekday') ?? '';
|
||||
const day = this.getAttribute('day') ?? '';
|
||||
const opt: Intl.DateTimeFormatOptions = {};
|
||||
for (const attr of ['year', 'month', 'weekday', 'day']) {
|
||||
if (this.getAttribute(attr)) opt[attr] = this.getAttribute(attr);
|
||||
}
|
||||
const lang = this.closest('[lang]')?.getAttribute('lang') ||
|
||||
this.ownerDocument.documentElement.getAttribute('lang') || '';
|
||||
|
||||
// only use the first 10 characters, e.g. the `yyyy-mm-dd` part
|
||||
const dateStr = this.getAttribute('date').substring(0, 10);
|
||||
// only use the date part, it is guaranteed to be in ISO format (YYYY-MM-DDTHH:mm:ss.sssZ)
|
||||
let date = this.getAttribute('date');
|
||||
let dateSep = date.indexOf('T');
|
||||
dateSep = dateSep === -1 ? date.indexOf(' ') : dateSep;
|
||||
date = dateSep === -1 ? date : date.substring(0, dateSep);
|
||||
|
||||
if (!this.shadowRoot) this.attachShadow({mode: 'open'});
|
||||
this.shadowRoot.textContent = toAbsoluteLocaleDate(dateStr, lang, {
|
||||
...(year && {year}),
|
||||
...(month && {month}),
|
||||
...(weekday && {weekday}),
|
||||
...(day && {day}),
|
||||
});
|
||||
this.shadowRoot.textContent = toAbsoluteLocaleDate(date, lang, opt);
|
||||
};
|
||||
|
||||
attributeChangedCallback(_name, oldValue, newValue) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user