Compare commits
10 Commits
727435743a
...
d86492f3bd
Author | SHA1 | Date |
---|---|---|
|
d86492f3bd | |
|
78cb09deda | |
|
0f35cb5a2a | |
|
0b3d6c399c | |
|
f98a1b851c | |
|
e75594f7a6 | |
|
a1c0b3a02e | |
|
6624f257d3 | |
|
35db5a373b | |
|
5043ad54c7 |
15
CHANGELOG.md
15
CHANGELOG.md
|
@ -4,6 +4,21 @@ This changelog goes through all the changes that have been made in each release
|
||||||
without substantial changes to our git log; to see the highlights of what has
|
without substantial changes to our git log; to see the highlights of what has
|
||||||
been added to each release, please refer to the [blog](https://blog.gitea.com).
|
been added to each release, please refer to the [blog](https://blog.gitea.com).
|
||||||
|
|
||||||
|
## [1.21.7](https://github.com/go-gitea/gitea/releases/tag/1.21.7) - 2024-02-26
|
||||||
|
|
||||||
|
* ENHANCEMENTS
|
||||||
|
* Users with `read` permission of pull requests can be assigned too (#27263) (#29372)
|
||||||
|
* BUGFIXES
|
||||||
|
* Do not double close reader (#29354) (#29370)
|
||||||
|
* Display friendly error message (#29105) (#29363)
|
||||||
|
* Fix project counter in organization/individual profile (#28068) (#29361)
|
||||||
|
* Fix validity of the FROM email address not being checked (#29347) (#29360)
|
||||||
|
* Fix tarball/zipball download bug (#29342) (#29352)
|
||||||
|
* DOCS
|
||||||
|
* Docker Tag Information in Docs (#29047) (#29362)
|
||||||
|
* MISC
|
||||||
|
* Enforce maxlength in frontend (#29389) (#29396)
|
||||||
|
|
||||||
## [1.21.6](https://github.com/go-gitea/gitea/releases/tag/v1.21.6) - 2024-02-22
|
## [1.21.6](https://github.com/go-gitea/gitea/releases/tag/v1.21.6) - 2024-02-22
|
||||||
|
|
||||||
* SECURITY
|
* SECURITY
|
||||||
|
|
|
@ -39,6 +39,16 @@ Images must follow this naming convention:
|
||||||
|
|
||||||
`{registry}/{owner}/{image}`
|
`{registry}/{owner}/{image}`
|
||||||
|
|
||||||
|
When building your docker image, using the naming convention above, this looks like:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# build an image with tag
|
||||||
|
docker build -t {registry}/{owner}/{image}:{tag} .
|
||||||
|
# name an existing image with tag
|
||||||
|
docker tag {some-existing-image}:{tag} {registry}/{owner}/{image}:{tag}
|
||||||
|
```
|
||||||
|
|
||||||
|
where your registry is the domain of your gitea instance (e.g. gitea.example.com).
|
||||||
For example, these are all valid image names for the owner `testuser`:
|
For example, these are all valid image names for the owner `testuser`:
|
||||||
|
|
||||||
`gitea.example.com/testuser/myimage`
|
`gitea.example.com/testuser/myimage`
|
||||||
|
|
|
@ -332,7 +332,6 @@ func HasAccessUnit(ctx context.Context, user *user_model.User, repo *repo_model.
|
||||||
|
|
||||||
// CanBeAssigned return true if user can be assigned to issue or pull requests in repo
|
// CanBeAssigned return true if user can be assigned to issue or pull requests in repo
|
||||||
// Currently any write access (code, issues or pr's) is assignable, to match assignee list in user interface.
|
// Currently any write access (code, issues or pr's) is assignable, to match assignee list in user interface.
|
||||||
// FIXME: user could send PullRequest also could be assigned???
|
|
||||||
func CanBeAssigned(ctx context.Context, user *user_model.User, repo *repo_model.Repository, _ bool) (bool, error) {
|
func CanBeAssigned(ctx context.Context, user *user_model.User, repo *repo_model.Repository, _ bool) (bool, error) {
|
||||||
if user.IsOrganization() {
|
if user.IsOrganization() {
|
||||||
return false, fmt.Errorf("Organization can't be added as assignee [user_id: %d, repo_id: %d]", user.ID, repo.ID)
|
return false, fmt.Errorf("Organization can't be added as assignee [user_id: %d, repo_id: %d]", user.ID, repo.ID)
|
||||||
|
@ -341,7 +340,8 @@ func CanBeAssigned(ctx context.Context, user *user_model.User, repo *repo_model.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
return perm.CanAccessAny(perm_model.AccessModeWrite, unit.TypeCode, unit.TypeIssues, unit.TypePullRequests), nil
|
return perm.CanAccessAny(perm_model.AccessModeWrite, unit.AllRepoUnitTypes...) ||
|
||||||
|
perm.CanAccessAny(perm_model.AccessModeRead, unit.TypePullRequests), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasAccess returns true if user has access to repo
|
// HasAccess returns true if user has access to repo
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
"code.gitea.io/gitea/models/perm"
|
"code.gitea.io/gitea/models/perm"
|
||||||
|
"code.gitea.io/gitea/models/unit"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/container"
|
"code.gitea.io/gitea/modules/container"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
|
@ -78,7 +79,8 @@ func GetRepoAssignees(ctx context.Context, repo *Repository) (_ []*user_model.Us
|
||||||
if err = e.Table("team_user").
|
if err = e.Table("team_user").
|
||||||
Join("INNER", "team_repo", "`team_repo`.team_id = `team_user`.team_id").
|
Join("INNER", "team_repo", "`team_repo`.team_id = `team_user`.team_id").
|
||||||
Join("INNER", "team_unit", "`team_unit`.team_id = `team_user`.team_id").
|
Join("INNER", "team_unit", "`team_unit`.team_id = `team_user`.team_id").
|
||||||
Where("`team_repo`.repo_id = ? AND `team_unit`.access_mode >= ?", repo.ID, perm.AccessModeWrite).
|
Where("`team_repo`.repo_id = ? AND (`team_unit`.access_mode >= ? OR (`team_unit`.access_mode = ? AND `team_unit`.`type` = ?))",
|
||||||
|
repo.ID, perm.AccessModeWrite, perm.AccessModeRead, unit.TypePullRequests).
|
||||||
Distinct("`team_user`.uid").
|
Distinct("`team_user`.uid").
|
||||||
Select("`team_user`.uid").
|
Select("`team_user`.uid").
|
||||||
Find(&additionalUserIDs); err != nil {
|
Find(&additionalUserIDs); err != nil {
|
||||||
|
|
|
@ -102,7 +102,17 @@ func (b *blobReader) Read(p []byte) (n int, err error) {
|
||||||
|
|
||||||
// Close implements io.Closer
|
// Close implements io.Closer
|
||||||
func (b *blobReader) Close() error {
|
func (b *blobReader) Close() error {
|
||||||
|
if b.rd == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
defer b.cancel()
|
defer b.cancel()
|
||||||
|
|
||||||
return DiscardFull(b.rd, b.n+1)
|
if err := DiscardFull(b.rd, b.n+1); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
b.rd = nil
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ package rubygems
|
||||||
import (
|
import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -41,8 +42,8 @@ type Metadata struct {
|
||||||
Summary string `json:"summary,omitempty"`
|
Summary string `json:"summary,omitempty"`
|
||||||
Authors []string `json:"authors,omitempty"`
|
Authors []string `json:"authors,omitempty"`
|
||||||
Licenses []string `json:"licenses,omitempty"`
|
Licenses []string `json:"licenses,omitempty"`
|
||||||
RequiredRubyVersion []VersionRequirement `json:"required_ruby_version,omitempty"`
|
RequiredRubyVersion VersionRequirementArray `json:"required_ruby_version,omitempty"`
|
||||||
RequiredRubygemsVersion []VersionRequirement `json:"required_rubygems_version,omitempty"`
|
RequiredRubygemsVersion VersionRequirementArray `json:"required_rubygems_version,omitempty"`
|
||||||
ProjectURL string `json:"project_url,omitempty"`
|
ProjectURL string `json:"project_url,omitempty"`
|
||||||
RuntimeDependencies []Dependency `json:"runtime_dependencies,omitempty"`
|
RuntimeDependencies []Dependency `json:"runtime_dependencies,omitempty"`
|
||||||
DevelopmentDependencies []Dependency `json:"development_dependencies,omitempty"`
|
DevelopmentDependencies []Dependency `json:"development_dependencies,omitempty"`
|
||||||
|
@ -54,10 +55,12 @@ type VersionRequirement struct {
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type VersionRequirementArray []VersionRequirement
|
||||||
|
|
||||||
// Dependency represents a dependency of a RubyGems package
|
// Dependency represents a dependency of a RubyGems package
|
||||||
type Dependency struct {
|
type Dependency struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Version []VersionRequirement `json:"version"`
|
Version VersionRequirementArray `json:"version"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type gemspec struct {
|
type gemspec struct {
|
||||||
|
@ -108,9 +111,45 @@ type requirement struct {
|
||||||
Requirements [][]any `yaml:"requirements"`
|
Requirements [][]any `yaml:"requirements"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// AsVersionRequirement converts into []VersionRequirement
|
func (vr VersionRequirement) String() string {
|
||||||
func (r requirement) AsVersionRequirement() []VersionRequirement {
|
return vr.Restriction + " " + vr.Version
|
||||||
requirements := make([]VersionRequirement, 0, len(r.Requirements))
|
}
|
||||||
|
|
||||||
|
func (arr VersionRequirementArray) List() []string {
|
||||||
|
arr_len := len(arr)
|
||||||
|
str_arr := make([]string, arr_len)
|
||||||
|
for i := 0; i < arr_len; i++ {
|
||||||
|
str_arr[i] = arr[i].String()
|
||||||
|
}
|
||||||
|
return str_arr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (arr VersionRequirementArray) Dumps() RubyUserMarshal {
|
||||||
|
arr_len := len(arr)
|
||||||
|
val0 := make([][]any, 1)
|
||||||
|
val0[0] = make([]any, arr_len)
|
||||||
|
for i := 0; i < arr_len; i++ {
|
||||||
|
val0[0][i] = []any{
|
||||||
|
arr[i].Restriction,
|
||||||
|
RubyUserMarshal{
|
||||||
|
Name: "Gem::Version",
|
||||||
|
Value: []any{
|
||||||
|
arr[i].Version,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
val := RubyUserMarshal{
|
||||||
|
Name: "Gem::Requirement",
|
||||||
|
Value: val0,
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsVersionRequirement converts into VersionRequirementArray
|
||||||
|
func (r requirement) AsVersionRequirement() VersionRequirementArray {
|
||||||
|
requirements := make(VersionRequirementArray, 0, len(r.Requirements))
|
||||||
for _, req := range r.Requirements {
|
for _, req := range r.Requirements {
|
||||||
if len(req) != 2 {
|
if len(req) != 2 {
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -246,6 +246,7 @@ email_title = Email Settings
|
||||||
smtp_addr = SMTP Host
|
smtp_addr = SMTP Host
|
||||||
smtp_port = SMTP Port
|
smtp_port = SMTP Port
|
||||||
smtp_from = Send Email As
|
smtp_from = Send Email As
|
||||||
|
smtp_from_invalid = The "Send Email As" address is invalid
|
||||||
smtp_from_helper = Email address Gitea will use. Enter a plain email address or use the "Name" <email@example.com> format.
|
smtp_from_helper = Email address Gitea will use. Enter a plain email address or use the "Name" <email@example.com> format.
|
||||||
mailer_user = SMTP Username
|
mailer_user = SMTP Username
|
||||||
mailer_password = SMTP Password
|
mailer_password = SMTP Password
|
||||||
|
|
|
@ -139,8 +139,8 @@ func ServePackageSpecification(ctx *context.Context) {
|
||||||
},
|
},
|
||||||
nil, // date
|
nil, // date
|
||||||
metadata.Summary, // @summary
|
metadata.Summary, // @summary
|
||||||
nil, // @required_ruby_version
|
metadata.RequiredRubyVersion.Dumps(), // @required_ruby_version
|
||||||
nil, // @required_rubygems_version
|
metadata.RequiredRubygemsVersion.Dumps(), // @required_rubygems_version
|
||||||
metadata.Platform, // @original_platform
|
metadata.Platform, // @original_platform
|
||||||
[]any{}, // @dependencies
|
[]any{}, // @dependencies
|
||||||
nil, // rubyforge_project
|
nil, // rubyforge_project
|
||||||
|
|
|
@ -7,6 +7,7 @@ package install
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/mail"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -417,6 +418,11 @@ func SubmitInstall(ctx *context.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(strings.TrimSpace(form.SMTPAddr)) > 0 {
|
if len(strings.TrimSpace(form.SMTPAddr)) > 0 {
|
||||||
|
if _, err := mail.ParseAddress(form.SMTPFrom); err != nil {
|
||||||
|
ctx.RenderWithErr(ctx.Tr("install.smtp_from_invalid"), tplInstall, &form)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
cfg.Section("mailer").Key("ENABLED").SetValue("true")
|
cfg.Section("mailer").Key("ENABLED").SetValue("true")
|
||||||
cfg.Section("mailer").Key("SMTP_ADDR").SetValue(form.SMTPAddr)
|
cfg.Section("mailer").Key("SMTP_ADDR").SetValue(form.SMTPAddr)
|
||||||
cfg.Section("mailer").Key("SMTP_PORT").SetValue(form.SMTPPort)
|
cfg.Section("mailer").Key("SMTP_PORT").SetValue(form.SMTPPort)
|
||||||
|
|
|
@ -61,17 +61,17 @@ func List(ctx *context.Context) {
|
||||||
|
|
||||||
var workflows []Workflow
|
var workflows []Workflow
|
||||||
if empty, err := ctx.Repo.GitRepo.IsEmpty(); err != nil {
|
if empty, err := ctx.Repo.GitRepo.IsEmpty(); err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, err.Error())
|
ctx.ServerError("IsEmpty", err)
|
||||||
return
|
return
|
||||||
} else if !empty {
|
} else if !empty {
|
||||||
commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch)
|
commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, err.Error())
|
ctx.ServerError("GetBranchCommit", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
entries, err := actions.ListWorkflows(commit)
|
entries, err := actions.ListWorkflows(commit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, err.Error())
|
ctx.ServerError("ListWorkflows", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ func List(ctx *context.Context) {
|
||||||
workflow := Workflow{Entry: *entry}
|
workflow := Workflow{Entry: *entry}
|
||||||
content, err := actions.GetContentFromEntry(entry)
|
content, err := actions.GetContentFromEntry(entry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, err.Error())
|
ctx.ServerError("GetContentFromEntry", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
wf, err := model.ReadWorkflow(bytes.NewReader(content))
|
wf, err := model.ReadWorkflow(bytes.NewReader(content))
|
||||||
|
@ -173,7 +173,7 @@ func List(ctx *context.Context) {
|
||||||
|
|
||||||
runs, total, err := actions_model.FindRuns(ctx, opts)
|
runs, total, err := actions_model.FindRuns(ctx, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, err.Error())
|
ctx.ServerError("FindAndCount", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ func List(ctx *context.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := runs.LoadTriggerUser(ctx); err != nil {
|
if err := runs.LoadTriggerUser(ctx); err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, err.Error())
|
ctx.ServerError("LoadTriggerUser", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ func List(ctx *context.Context) {
|
||||||
|
|
||||||
actors, err := actions_model.GetActors(ctx, ctx.Repo.Repository.ID)
|
actors, err := actions_model.GetActors(ctx, ctx.Repo.Repository.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, err.Error())
|
ctx.ServerError("GetActors", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.Data["Actors"] = repo.MakeSelfOnTop(ctx.Doer, actors)
|
ctx.Data["Actors"] = repo.MakeSelfOnTop(ctx.Doer, actors)
|
||||||
|
|
|
@ -161,9 +161,6 @@ func editFile(ctx *context.Context, isNewFile bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
d, _ := io.ReadAll(dataRc)
|
d, _ := io.ReadAll(dataRc)
|
||||||
if err := dataRc.Close(); err != nil {
|
|
||||||
log.Error("Error whilst closing blob data: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = append(buf, d...)
|
buf = append(buf, d...)
|
||||||
if content, err := charset.ToUTF8(buf, charset.ConvertOpts{KeepBOM: true}); err != nil {
|
if content, err := charset.ToUTF8(buf, charset.ConvertOpts{KeepBOM: true}); err != nil {
|
||||||
|
|
|
@ -6,6 +6,7 @@ package user
|
||||||
import (
|
import (
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
"code.gitea.io/gitea/models/organization"
|
"code.gitea.io/gitea/models/organization"
|
||||||
|
project_model "code.gitea.io/gitea/models/project"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
|
@ -125,5 +126,21 @@ func LoadHeaderCount(ctx *context.Context) error {
|
||||||
}
|
}
|
||||||
ctx.Data["RepoCount"] = repoCount
|
ctx.Data["RepoCount"] = repoCount
|
||||||
|
|
||||||
|
var projectType project_model.Type
|
||||||
|
if ctx.ContextUser.IsOrganization() {
|
||||||
|
projectType = project_model.TypeOrganization
|
||||||
|
} else {
|
||||||
|
projectType = project_model.TypeIndividual
|
||||||
|
}
|
||||||
|
projectCount, err := project_model.CountProjects(ctx, project_model.SearchOptions{
|
||||||
|
OwnerID: ctx.ContextUser.ID,
|
||||||
|
IsClosed: util.OptionalBoolOf(false),
|
||||||
|
Type: projectType,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ctx.Data["ProjectCount"] = projectCount
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
{{if .CanReadProjects}}
|
{{if .CanReadProjects}}
|
||||||
<a class="{{if .PageIsViewProjects}}active {{end}}item" href="{{$.Org.HomeLink}}/-/projects">
|
<a class="{{if .PageIsViewProjects}}active {{end}}item" href="{{$.Org.HomeLink}}/-/projects">
|
||||||
{{svg "octicon-project-symlink"}} {{ctx.Locale.Tr "user.projects"}}
|
{{svg "octicon-project-symlink"}} {{ctx.Locale.Tr "user.projects"}}
|
||||||
|
{{if .ProjectCount}}
|
||||||
|
<div class="ui small label">{{.ProjectCount}}</div>
|
||||||
|
{{end}}
|
||||||
</a>
|
</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if and .IsPackageEnabled .CanReadPackages}}
|
{{if and .IsPackageEnabled .CanReadPackages}}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
{{ctx.Locale.Tr "repo.editor.commit_changes"}}
|
{{ctx.Locale.Tr "repo.editor.commit_changes"}}
|
||||||
{{- end}}</h3>
|
{{- end}}</h3>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<input name="commit_summary" placeholder="{{if .PageIsDelete}}{{ctx.Locale.Tr "repo.editor.delete" .TreePath}}{{else if .PageIsUpload}}{{ctx.Locale.Tr "repo.editor.upload_files_to_dir" .TreePath}}{{else if .IsNewFile}}{{ctx.Locale.Tr "repo.editor.add_tmpl"}}{{else if .PageIsPatch}}{{ctx.Locale.Tr "repo.editor.patch"}}{{else}}{{ctx.Locale.Tr "repo.editor.update" .TreePath}}{{end}}" value="{{.commit_summary}}" autofocus>
|
<input name="commit_summary" maxlength="100" placeholder="{{if .PageIsDelete}}{{ctx.Locale.Tr "repo.editor.delete" .TreePath}}{{else if .PageIsUpload}}{{ctx.Locale.Tr "repo.editor.upload_files_to_dir" .TreePath}}{{else if .IsNewFile}}{{ctx.Locale.Tr "repo.editor.add_tmpl"}}{{else if .PageIsPatch}}{{ctx.Locale.Tr "repo.editor.patch"}}{{else}}{{ctx.Locale.Tr "repo.editor.update" .TreePath}}{{end}}" value="{{.commit_summary}}" autofocus>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<textarea name="commit_message" placeholder="{{ctx.Locale.Tr "repo.editor.commit_message_desc"}}" rows="5">{{.commit_message}}</textarea>
|
<textarea name="commit_message" placeholder="{{ctx.Locale.Tr "repo.editor.commit_message_desc"}}" rows="5">{{.commit_message}}</textarea>
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
<div class="quick-pull-branch-name {{if not (eq .commit_choice "commit-to-new-branch")}}gt-hidden{{end}}">
|
<div class="quick-pull-branch-name {{if not (eq .commit_choice "commit-to-new-branch")}}gt-hidden{{end}}">
|
||||||
<div class="new-branch-name-input field {{if .Err_NewBranchName}}error{{end}}">
|
<div class="new-branch-name-input field {{if .Err_NewBranchName}}error{{end}}">
|
||||||
{{svg "octicon-git-branch"}}
|
{{svg "octicon-git-branch"}}
|
||||||
<input type="text" name="new_branch_name" value="{{.new_branch_name}}" class="input-contrast gt-mr-2 js-quick-pull-new-branch-name" placeholder="{{ctx.Locale.Tr "repo.editor.new_branch_name_desc"}}" {{if eq .commit_choice "commit-to-new-branch"}}required{{end}} title="{{ctx.Locale.Tr "repo.editor.new_branch_name"}}">
|
<input type="text" name="new_branch_name" maxlength="100" value="{{.new_branch_name}}" class="input-contrast gt-mr-2 js-quick-pull-new-branch-name" placeholder="{{ctx.Locale.Tr "repo.editor.new_branch_name_desc"}}" {{if eq .commit_choice "commit-to-new-branch"}}required{{end}} title="{{ctx.Locale.Tr "repo.editor.new_branch_name"}}">
|
||||||
<span class="text-muted js-quick-pull-normalization-info"></span>
|
<span class="text-muted js-quick-pull-normalization-info"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
{{range $i, $v := .TreeNames}}
|
{{range $i, $v := .TreeNames}}
|
||||||
<div class="breadcrumb-divider">/</div>
|
<div class="breadcrumb-divider">/</div>
|
||||||
{{if eq $i $l}}
|
{{if eq $i $l}}
|
||||||
<input id="file-name" value="{{$v}}" placeholder="{{ctx.Locale.Tr "repo.editor.name_your_file"}}" data-editorconfig="{{$.EditorconfigJson}}" required autofocus>
|
<input id="file-name" maxlength="500" value="{{$v}}" placeholder="{{ctx.Locale.Tr "repo.editor.name_your_file"}}" data-editorconfig="{{$.EditorconfigJson}}" required autofocus>
|
||||||
<span data-tooltip-content="{{ctx.Locale.Tr "repo.editor.filename_help"}}">{{svg "octicon-info"}}</span>
|
<span data-tooltip-content="{{ctx.Locale.Tr "repo.editor.filename_help"}}">{{svg "octicon-info"}}</span>
|
||||||
{{else}}
|
{{else}}
|
||||||
<span class="section"><a href="{{$.BranchLink}}/{{index $.TreePaths $i | PathEscapeSegments}}">{{$v}}</a></span>
|
<span class="section"><a href="{{$.BranchLink}}/{{index $.TreePaths $i | PathEscapeSegments}}">{{$v}}</a></span>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<a class="section" href="{{$.BranchLink}}">{{.BranchName}}</a>
|
<a class="section" href="{{$.BranchLink}}">{{.BranchName}}</a>
|
||||||
<span>{{ctx.Locale.Tr "repo.editor.or"}} <a href="{{$.BranchLink}}">{{ctx.Locale.Tr "repo.editor.cancel_lower"}}</a></span>
|
<span>{{ctx.Locale.Tr "repo.editor.or"}} <a href="{{$.BranchLink}}">{{ctx.Locale.Tr "repo.editor.cancel_lower"}}</a></span>
|
||||||
<input type="hidden" id="tree_path" name="tree_path" value="" required>
|
<input type="hidden" id="tree_path" name="tree_path" value="" required>
|
||||||
<input id="file-name" type="hidden" value="diff.patch">
|
<input id="file-name" maxlength="500" type="hidden" value="diff.patch">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
{{range $i, $v := .TreeNames}}
|
{{range $i, $v := .TreeNames}}
|
||||||
<div class="breadcrumb-divider">/</div>
|
<div class="breadcrumb-divider">/</div>
|
||||||
{{if eq $i $l}}
|
{{if eq $i $l}}
|
||||||
<input type="text" id="file-name" value="{{$v}}" placeholder="{{ctx.Locale.Tr "repo.editor.add_subdir"}}" autofocus>
|
<input type="text" id="file-name" maxlength="500" value="{{$v}}" placeholder="{{ctx.Locale.Tr "repo.editor.add_subdir"}}" autofocus>
|
||||||
<span data-tooltip-content="{{ctx.Locale.Tr "repo.editor.filename_help"}}">{{svg "octicon-info"}}</span>
|
<span data-tooltip-content="{{ctx.Locale.Tr "repo.editor.filename_help"}}">{{svg "octicon-info"}}</span>
|
||||||
{{else}}
|
{{else}}
|
||||||
<span class="section"><a href="{{$.BranchLink}}/{{index $.TreePaths $i | PathEscapeSegments}}">{{$v}}</a></span>
|
<span class="section"><a href="{{$.BranchLink}}/{{index $.TreePaths $i | PathEscapeSegments}}">{{$v}}</a></span>
|
||||||
|
|
|
@ -13,6 +13,9 @@
|
||||||
{{if or .ContextUser.IsIndividual (and .ContextUser.IsOrganization .CanReadProjects)}}
|
{{if or .ContextUser.IsIndividual (and .ContextUser.IsOrganization .CanReadProjects)}}
|
||||||
<a href="{{.ContextUser.HomeLink}}/-/projects" class="{{if .PageIsViewProjects}}active {{end}}item">
|
<a href="{{.ContextUser.HomeLink}}/-/projects" class="{{if .PageIsViewProjects}}active {{end}}item">
|
||||||
{{svg "octicon-project-symlink"}} {{ctx.Locale.Tr "user.projects"}}
|
{{svg "octicon-project-symlink"}} {{ctx.Locale.Tr "user.projects"}}
|
||||||
|
{{if .ProjectCount}}
|
||||||
|
<div class="ui small label">{{.ProjectCount}}</div>
|
||||||
|
{{end}}
|
||||||
</a>
|
</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if and .IsPackageEnabled (or .ContextUser.IsIndividual (and .ContextUser.IsOrganization .CanReadPackages))}}
|
{{if and .IsPackageEnabled (or .ContextUser.IsIndividual (and .ContextUser.IsOrganization .CanReadPackages))}}
|
||||||
|
|
|
@ -2,13 +2,14 @@ import {encode, decode} from 'uint8-to-base64';
|
||||||
|
|
||||||
// transform /path/to/file.ext to file.ext
|
// transform /path/to/file.ext to file.ext
|
||||||
export function basename(path = '') {
|
export function basename(path = '') {
|
||||||
return path ? path.replace(/^.*\//, '') : '';
|
const lastSlashIndex = path.lastIndexOf('/');
|
||||||
|
return lastSlashIndex < 0 ? path : path.substring(lastSlashIndex + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// transform /path/to/file.ext to .ext
|
// transform /path/to/file.ext to .ext
|
||||||
export function extname(path = '') {
|
export function extname(path = '') {
|
||||||
const [_, ext] = /.+(\.[^.]+)$/.exec(path) || [];
|
const lastPointIndex = path.lastIndexOf('.');
|
||||||
return ext || '';
|
return lastPointIndex < 0 ? '' : path.substring(lastPointIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// test whether a variable is an object
|
// test whether a variable is an object
|
||||||
|
|
Loading…
Reference in New Issue