Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions models/issues/comment.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,11 @@ type RoleDescriptor int
const (
RoleDescriptorNone RoleDescriptor = iota
RoleDescriptorPoster
RoleDescriptorWriter
RoleDescriptorOwner
RoleDescriptorMember
RoleDescriptorCollaborator
RoleDescriptorFirstTimeContributor
RoleDescriptorContributor
)

// WithRole enable a specific tag on the RoleDescriptor.
Expand All @@ -201,10 +204,16 @@ func stringToRoleDescriptor(role string) RoleDescriptor {
switch role {
case "Poster":
return RoleDescriptorPoster
case "Writer":
return RoleDescriptorWriter
case "Owner":
return RoleDescriptorOwner
case "Member":
return RoleDescriptorMember
case "Collaborator":
return RoleDescriptorCollaborator
case "First-time contributor":
return RoleDescriptorFirstTimeContributor
case "Contributor":
return RoleDescriptorContributor
default:
return RoleDescriptorNone
}
Expand Down
5 changes: 4 additions & 1 deletion modules/git/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,12 @@ func (c *Commit) CommitsBeforeUntil(commitID string) ([]*Commit, error) {

// SearchCommitsOptions specify the parameters for SearchCommits
type SearchCommitsOptions struct {
CommitID SHA1
Keywords []string
Authors, Committers []string
After, Before string
All bool
Limit int
}

// NewSearchCommitsOptions construct a SearchCommitsOption from a space-delimited search string
Expand Down Expand Up @@ -297,7 +299,8 @@ func NewSearchCommitsOptions(searchString string, forAllRefs bool) SearchCommits

// SearchCommits returns the commits match the keyword before current revision
func (c *Commit) SearchCommits(opts SearchCommitsOptions) ([]*Commit, error) {
return c.repo.searchCommits(c.ID, opts)
opts.CommitID = c.ID
return c.repo.SearchCommits(opts)
}

// GetFilesChangedSinceCommit get all changed file names between pastCommit to current revision
Expand Down
17 changes: 14 additions & 3 deletions modules/git/repo_commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func (repo *Repository) commitsByRange(id SHA1, page, pageSize int, not string)
return repo.parsePrettyFormatLogToList(stdout)
}

func (repo *Repository) searchCommits(id SHA1, opts SearchCommitsOptions) ([]*Commit, error) {
func (repo *Repository) SearchCommits(opts SearchCommitsOptions) ([]*Commit, error) {
// add common arguments to git command
addCommonSearchArgs := func(c *Command) {
// ignore case
Expand Down Expand Up @@ -138,8 +138,19 @@ func (repo *Repository) searchCommits(id SHA1, opts SearchCommitsOptions) ([]*Co
}
}

// create new git log command with limit of 100 commits
cmd := NewCommand(repo.Ctx, "log", "-100", prettyLogFormat).AddDynamicArguments(id.String())
// create new git log command
cmd := NewCommand(repo.Ctx, "log")

// By default, limit 100 commits
limit := 100
if opts.Limit > 0 {
limit = opts.Limit
}
cmd = cmd.AddOptionFormat("-%d", limit).AddArguments(prettyLogFormat)

if !opts.CommitID.IsZero() {
cmd = cmd.AddDynamicArguments(opts.CommitID.String())
}

// pretend that all refs along with HEAD were listed on command line as <commis>
// https://git-scm.com/docs/git-log#Documentation/git-log.txt---all
Expand Down
13 changes: 11 additions & 2 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1480,9 +1480,18 @@ issues.ref_reopening_from = `<a href="%[3]s">referenced a pull request %[4]s tha
issues.ref_closed_from = `<a href="%[3]s">closed this issue %[4]s</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.ref_reopened_from = `<a href="%[3]s">reopened this issue %[4]s</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.ref_from = `from %[1]s`
issues.poster = Poster
issues.collaborator = Collaborator
issues.author = Author
issues.author_helper = This user is the author.
Comment on lines +1483 to +1484
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where do we even assign author?
I haven't found it inside roleDescriptor

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Gitea, it is called poster.

issues.owner = Owner
issues.owner_helper = This user is the owner of this repository.
issues.member = Member
issues.member_helper = This user is a member of the organization.
issues.collaborator = Collaborator
issues.collaborator_helper = This user has been invited to collaborate on the repository.
issues.first_time_contributor = First-time contributor
issues.first_time_contributor_helper = This user is a first-time contributor to the repository.
issues.contributor = Contributor
issues.contributor_helper = This user has previously committed to the repository.
issues.re_request_review=Re-request review
issues.is_stale = There have been changes to this PR since this review
issues.remove_request_review=Remove review request
Expand Down
68 changes: 48 additions & 20 deletions routers/web/repo/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -1229,7 +1229,7 @@ func NewIssuePost(ctx *context.Context) {
}

// roleDescriptor returns the Role Descriptor for a comment in/with the given repo, poster and issue
func roleDescriptor(ctx stdCtx.Context, repo *repo_model.Repository, poster *user_model.User, issue *issues_model.Issue, hasOriginalAuthor bool) (issues_model.RoleDescriptor, error) {
func roleDescriptor(ctx stdCtx.Context, repo *repo_model.Repository, poster *user_model.User, issue *issues_model.Issue, gitRepo *git.Repository, hasOriginalAuthor bool) (issues_model.RoleDescriptor, error) {
if hasOriginalAuthor {
return issues_model.RoleDescriptorNone, nil
}
Expand All @@ -1242,33 +1242,61 @@ func roleDescriptor(ctx stdCtx.Context, repo *repo_model.Repository, poster *use
// By default the poster has no roles on the comment.
roleDescriptor := issues_model.RoleDescriptorNone

// If the poster is the actual poster of the issue, enable Poster role.
if issue.IsPoster(poster.ID) {
roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorPoster)
}

// Check if the poster is owner of the repo.
if perm.IsOwner() {
// If the poster isn't a admin, enable the owner role.
if !poster.IsAdmin {
roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorOwner)
} else {
return roleDescriptor, nil
}

// Otherwise check if poster is the real repo admin.
ok, err := access_model.IsUserRealRepoAdmin(repo, poster)
if err != nil {
return issues_model.RoleDescriptorNone, err
}
if ok {
roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorOwner)
}
// Otherwise check if poster is the real repo admin.
ok, err := access_model.IsUserRealRepoAdmin(repo, poster)
if err != nil {
return issues_model.RoleDescriptorNone, err
}
if ok {
roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorOwner)
return roleDescriptor, nil
}
}

// Is the poster can write issues or pulls to the repo, enable the Writer role.
// Only enable this if the poster doesn't have the owner role already.
if !roleDescriptor.HasRole("Owner") && perm.CanWriteIssuesOrPulls(issue.IsPull) {
roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorWriter)
// If repo is organization, check Member role
if err := repo.LoadOwner(ctx); err != nil {
return issues_model.RoleDescriptorNone, err
}
if repo.Owner.IsOrganization() {
if isMember, err := organization.IsOrganizationMember(ctx, repo.Owner.ID, poster.ID); err != nil {
return issues_model.RoleDescriptorNone, err
} else if isMember {
roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorMember)
return roleDescriptor, nil
}
}

// If the poster is the actual poster of the issue, enable Poster role.
if issue.IsPoster(poster.ID) {
roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorPoster)
// If the poster is the collaborator of the repo
if isCollaborator, err := repo_model.IsCollaborator(ctx, repo.ID, poster.ID); err != nil {
return issues_model.RoleDescriptorNone, err
} else if isCollaborator {
roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorCollaborator)
return roleDescriptor, nil
}

if commits, err := gitRepo.SearchCommits(git.SearchCommitsOptions{
Authors: []string{poster.Name},
All: true,
Limit: 2,
}); err != nil {
return issues_model.RoleDescriptorNone, err
} else if len(commits) == 1 {
roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorContributor)
} else if len(commits) > 1 {
roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorFirstTimeContributor)
}

return roleDescriptor, nil
Expand Down Expand Up @@ -1526,7 +1554,7 @@ func ViewIssue(ctx *context.Context) {
// check if dependencies can be created across repositories
ctx.Data["AllowCrossRepositoryDependencies"] = setting.Service.AllowCrossRepositoryDependencies

if issue.ShowRole, err = roleDescriptor(ctx, repo, issue.Poster, issue, issue.HasOriginalAuthor()); err != nil {
if issue.ShowRole, err = roleDescriptor(ctx, repo, issue.Poster, issue, ctx.Repo.GitRepo, issue.HasOriginalAuthor()); err != nil {
ctx.ServerError("roleDescriptor", err)
return
}
Expand Down Expand Up @@ -1565,7 +1593,7 @@ func ViewIssue(ctx *context.Context) {
continue
}

comment.ShowRole, err = roleDescriptor(ctx, repo, comment.Poster, issue, comment.HasOriginalAuthor())
comment.ShowRole, err = roleDescriptor(ctx, repo, comment.Poster, issue, ctx.Repo.GitRepo, comment.HasOriginalAuthor())
if err != nil {
ctx.ServerError("roleDescriptor", err)
return
Expand Down Expand Up @@ -1664,7 +1692,7 @@ func ViewIssue(ctx *context.Context) {
continue
}

c.ShowRole, err = roleDescriptor(ctx, repo, c.Poster, issue, c.HasOriginalAuthor())
c.ShowRole, err = roleDescriptor(ctx, repo, c.Poster, issue, ctx.Repo.GitRepo, c.HasOriginalAuthor())
if err != nil {
ctx.ServerError("roleDescriptor", err)
return
Expand Down
28 changes: 20 additions & 8 deletions templates/repo/issue/view_content/show_role.tmpl
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
{{if and (.ShowRole.HasRole "Poster") (not .IgnorePoster)}}
<div class="ui basic label role-label">
{{ctx.Locale.Tr "repo.issues.poster"}}
</div>
{{end}}
{{if (.ShowRole.HasRole "Writer")}}
<div class="ui basic label role-label">
{{ctx.Locale.Tr "repo.issues.collaborator"}}
<div class="ui basic label role-label" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.author_helper"}}">
{{ctx.Locale.Tr "repo.issues.author"}}
</div>
{{end}}

{{if (.ShowRole.HasRole "Owner")}}
<div class="ui basic label role-label">
<div class="ui basic label role-label" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.owner_helper"}}">
{{ctx.Locale.Tr "repo.issues.owner"}}
</div>
{{else if (.ShowRole.HasRole "Member")}}
<div class="ui basic label role-label" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.member_helper"}}">
{{ctx.Locale.Tr "repo.issues.member"}}
</div>
{{else if (.ShowRole.HasRole "Collaborator")}}
<div class="ui basic label role-label" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.collaborator_helper"}}">
{{ctx.Locale.Tr "repo.issues.collaborator"}}
</div>
{{else if and (.ShowRole.HasRole "First-time contributor") (.ShowRole.HasRole "Poster")}}
<div class="ui basic label role-label" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.first_time_contributor_helper"}}">
{{ctx.Locale.Tr "repo.issues.first_time_contributor"}}
</div>
{{else if (.ShowRole.HasRole "Contributor")}}
<div class="ui basic label role-label" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.contributor_helper"}}">
{{ctx.Locale.Tr "repo.issues.contributor"}}
</div>
{{end}}