Skip to content

Commit

Permalink
Add API for Repo Advanced Settings of wiki and issue tracker
Browse files Browse the repository at this point in the history
Signed-off-by: David Svantesson <davidsvantesson@gmail.com>
  • Loading branch information
davidsvantesson committed Aug 10, 2019
1 parent cde95f9 commit 7e5c953
Show file tree
Hide file tree
Showing 4 changed files with 289 additions and 73 deletions.
102 changes: 68 additions & 34 deletions models/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,12 +275,37 @@ func (repo *Repository) innerAPIFormat(e Engine, mode AccessMode, isParent bool)
}
}
hasIssues := false
if _, err := repo.getUnit(e, UnitTypeIssues); err == nil {
externalTracker := false
externalTrackerURL := ""
externalTrackerFormat := ""
externalTrackerStyle := ""
enableTimeTracker := false
letOnlyContributorsTrackTime := false
enableIssueDependencies := false
if unit, err := repo.getUnit(e, UnitTypeIssues); err == nil {
config := unit.IssuesConfig()
hasIssues = true
enableTimeTracker = config.EnableTimetracker
letOnlyContributorsTrackTime = config.AllowOnlyContributorsToTrackTime
enableIssueDependencies = config.EnableDependencies
} else if unit, err := repo.getUnit(e, UnitTypeExternalTracker); err == nil {
config := unit.ExternalTrackerConfig()
hasIssues = true
externalTracker = true
externalTrackerURL = config.ExternalTrackerURL
externalTrackerFormat = config.ExternalTrackerFormat
externalTrackerStyle = config.ExternalTrackerStyle
}
hasWiki := false
externalWiki := false
externalWikiURL := ""
if _, err := repo.getUnit(e, UnitTypeWiki); err == nil {
hasWiki = true
} else if unit, err := repo.getUnit(e, UnitTypeExternalWiki); err == nil {
hasWiki = true
config := unit.ExternalWikiConfig()
externalWiki = true
externalWikiURL = config.ExternalWikiURL
}
hasPullRequests := false
ignoreWhitespaceConflicts := false
Expand All @@ -299,39 +324,48 @@ func (repo *Repository) innerAPIFormat(e Engine, mode AccessMode, isParent bool)
}

return &api.Repository{
ID: repo.ID,
Owner: repo.Owner.APIFormat(),
Name: repo.Name,
FullName: repo.FullName(),
Description: repo.Description,
Private: repo.IsPrivate,
Empty: repo.IsEmpty,
Archived: repo.IsArchived,
Size: int(repo.Size / 1024),
Fork: repo.IsFork,
Parent: parent,
Mirror: repo.IsMirror,
HTMLURL: repo.HTMLURL(),
SSHURL: cloneLink.SSH,
CloneURL: cloneLink.HTTPS,
Website: repo.Website,
Stars: repo.NumStars,
Forks: repo.NumForks,
Watchers: repo.NumWatches,
OpenIssues: repo.NumOpenIssues,
DefaultBranch: repo.DefaultBranch,
Created: repo.CreatedUnix.AsTime(),
Updated: repo.UpdatedUnix.AsTime(),
Permissions: permission,
HasIssues: hasIssues,
HasWiki: hasWiki,
HasPullRequests: hasPullRequests,
IgnoreWhitespaceConflicts: ignoreWhitespaceConflicts,
AllowMerge: allowMerge,
AllowRebase: allowRebase,
AllowRebaseMerge: allowRebaseMerge,
AllowSquash: allowSquash,
AvatarURL: repo.avatarLink(e),
ID: repo.ID,
Owner: repo.Owner.APIFormat(),
Name: repo.Name,
FullName: repo.FullName(),
Description: repo.Description,
Private: repo.IsPrivate,
Empty: repo.IsEmpty,
Archived: repo.IsArchived,
Size: int(repo.Size / 1024),
Fork: repo.IsFork,
Parent: parent,
Mirror: repo.IsMirror,
HTMLURL: repo.HTMLURL(),
SSHURL: cloneLink.SSH,
CloneURL: cloneLink.HTTPS,
Website: repo.Website,
Stars: repo.NumStars,
Forks: repo.NumForks,
Watchers: repo.NumWatches,
OpenIssues: repo.NumOpenIssues,
DefaultBranch: repo.DefaultBranch,
Created: repo.CreatedUnix.AsTime(),
Updated: repo.UpdatedUnix.AsTime(),
Permissions: permission,
HasIssues: hasIssues,
ExternalTracker: externalTracker,
ExternalTrackerURL: externalTrackerURL,
ExternalTrackerFormat: externalTrackerFormat,
ExternalTrackerStyle: externalTrackerStyle,
EnableTimeTracker: enableTimeTracker,
LetOnlyContributorsTrackTime: letOnlyContributorsTrackTime,
EnableIssueDependencies: enableIssueDependencies,
HasWiki: hasWiki,
ExternalWiki: externalWiki,
ExternalWikiURL: externalWikiURL,
HasPullRequests: hasPullRequests,
IgnoreWhitespaceConflicts: ignoreWhitespaceConflicts,
AllowMerge: allowMerge,
AllowRebase: allowRebase,
AllowRebaseMerge: allowRebaseMerge,
AllowSquash: allowSquash,
AvatarURL: repo.avatarLink(e),
}
}

Expand Down
49 changes: 38 additions & 11 deletions modules/structs/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,26 @@ type Repository struct {
// swagger:strfmt date-time
Created time.Time `json:"created_at"`
// swagger:strfmt date-time
Updated time.Time `json:"updated_at"`
Permissions *Permission `json:"permissions,omitempty"`
HasIssues bool `json:"has_issues"`
HasWiki bool `json:"has_wiki"`
HasPullRequests bool `json:"has_pull_requests"`
IgnoreWhitespaceConflicts bool `json:"ignore_whitespace_conflicts"`
AllowMerge bool `json:"allow_merge_commits"`
AllowRebase bool `json:"allow_rebase"`
AllowRebaseMerge bool `json:"allow_rebase_explicit"`
AllowSquash bool `json:"allow_squash_merge"`
AvatarURL string `json:"avatar_url"`
Updated time.Time `json:"updated_at"`
Permissions *Permission `json:"permissions,omitempty"`
HasIssues bool `json:"has_issues"`
ExternalTracker bool `json:"external_tracker"`
ExternalTrackerURL string `json:"external_tracker_url"`
ExternalTrackerFormat string `json:"external_tracker_format"`
ExternalTrackerStyle string `json:"external_tracker_style"`
EnableTimeTracker bool `json:"enable_time_tracker"`
LetOnlyContributorsTrackTime bool `json:"let_only_contributors_track_time"`
EnableIssueDependencies bool `json:"enable_issue_dependencies"`
HasWiki bool `json:"has_wiki"`
ExternalWiki bool `json:"external_wiki"`
ExternalWikiURL string `json:"external_wiki_url"`
HasPullRequests bool `json:"has_pull_requests"`
IgnoreWhitespaceConflicts bool `json:"ignore_whitespace_conflicts"`
AllowMerge bool `json:"allow_merge_commits"`
AllowRebase bool `json:"allow_rebase"`
AllowRebaseMerge bool `json:"allow_rebase_explicit"`
AllowSquash bool `json:"allow_squash_merge"`
AvatarURL string `json:"avatar_url"`
}

// CreateRepoOption options when creating repository
Expand Down Expand Up @@ -93,8 +102,26 @@ type EditRepoOption struct {
Private *bool `json:"private,omitempty"`
// either `true` to enable issues for this repository or `false` to disable them.
HasIssues *bool `json:"has_issues,omitempty"`
// either `true` to enable external issue tracker or `false` to disable it.
ExternalTracker *bool `json:"external_tracker,omitempty"`
// URL of external issue tracker.
ExternalTrackerURL *string `json:"external_tracker_url,omitempty"`
// External Issue Tracker URL Format. Use the placeholders {user}, {repo} and {index} for the username, repository name and issue index.
ExternalTrackerFormat *string `json:"external_tracker_format,omitempty"`
// External Issue Tracker Number Format, either `numeric` or `alphanumeric`
ExternalTrackerStyle *string `json:"external_tracker_style,omitempty"`
// Enable time tracking (Built-in issue tracker)
EnableTimeTracker *bool `json:"enable_time_tracker,omitempty"`
// Let only contributors track time (Built-in issue tracker)
LetOnlyContributorsTrackTime *bool `json:"let_only_contributors_track_time,omitempty"`
// Enable dependencies for issues and pull requests (Built-in issue tracker)
EnableIssueDependencies *bool `json:"enable_issue_dependencies,omitempty"`
// either `true` to enable the wiki for this repository or `false` to disable it.
HasWiki *bool `json:"has_wiki,omitempty"`
// either `true` to enable external wiki or `false` to disable it.
ExternalWiki *bool `json:"external_wiki,omitempty"`
// URL of external wiki.
ExternalWikiURL *string `json:"external_wiki_url,omitempty"`
// sets the default branch for this repository.
DefaultBranch *string `json:"default_branch,omitempty"`
// either `true` to allow pull requests, or `false` to prevent pull request.
Expand Down
130 changes: 102 additions & 28 deletions routers/api/v1/repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"code.gitea.io/gitea/modules/notification"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/validation"
"code.gitea.io/gitea/routers/api/v1/convert"

api "code.gitea.io/gitea/modules/structs"
Expand Down Expand Up @@ -659,27 +660,77 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
units = append(units, *unit)
}
} else if *opts.HasIssues {
// We don't currently allow setting individual issue settings through the API,
// only can enable/disable issues, so when enabling issues,
// we either get the existing config which means it was already enabled,
// or create a new config since it doesn't exist.
unit, err := repo.GetUnit(models.UnitTypeIssues)
var config *models.IssuesConfig
if err != nil {
// Unit type doesn't exist so we make a new config file with default values
config = &models.IssuesConfig{
EnableTimetracker: true,
AllowOnlyContributorsToTrackTime: true,
EnableDependencies: true,
if opts.ExternalTracker != nil && *opts.ExternalTracker {

var config *models.ExternalTrackerConfig
if unit, err := repo.GetUnit(models.UnitTypeExternalTracker); err != nil {
// Unit type doesn't exist so we make a new config file, default empty strings
config = &models.ExternalTrackerConfig{
ExternalTrackerURL: "",
ExternalTrackerFormat: "",
ExternalTrackerStyle: "",
}
} else {
config = unit.ExternalTrackerConfig()
}

// Update values if set and valid
if opts.ExternalTrackerURL != nil {
if !validation.IsValidExternalURL(*opts.ExternalTrackerURL) {
err := fmt.Errorf("External tracker URL not valid")
ctx.Error(http.StatusBadRequest, "Invalid external tracker URL", err)
return err
}
config.ExternalTrackerURL = *opts.ExternalTrackerURL
}
if opts.ExternalTrackerFormat != nil {
if len(*opts.ExternalTrackerFormat) != 0 && !validation.IsValidExternalTrackerURLFormat(*opts.ExternalTrackerFormat) {
err := fmt.Errorf("External tracker URL format not valid")
ctx.Error(http.StatusBadRequest, "Invalid external tracker URL format", err)
return err
}
config.ExternalTrackerFormat = *opts.ExternalTrackerFormat
}
if opts.ExternalTrackerStyle != nil {
config.ExternalTrackerStyle = *opts.ExternalTrackerStyle
}

units = append(units, models.RepoUnit{
RepoID: repo.ID,
Type: models.UnitTypeExternalTracker,
Config: config,
})
} else {
config = unit.IssuesConfig()
// Default to built-in tracker
var config *models.IssuesConfig
if unit, err := repo.GetUnit(models.UnitTypeIssues); err != nil {
// Unit type doesn't exist so we make a new config file with default values
config = &models.IssuesConfig{
EnableTimetracker: true,
AllowOnlyContributorsToTrackTime: true,
EnableDependencies: true,
}
} else {
config = unit.IssuesConfig()
}

// Update values if set
if opts.EnableTimeTracker != nil {
config.EnableTimetracker = *opts.EnableTimeTracker
}
if opts.LetOnlyContributorsTrackTime != nil {
config.AllowOnlyContributorsToTrackTime = *opts.LetOnlyContributorsTrackTime
}
if opts.EnableIssueDependencies != nil {
config.EnableDependencies = *opts.EnableIssueDependencies
}

units = append(units, models.RepoUnit{
RepoID: repo.ID,
Type: models.UnitTypeIssues,
Config: config,
})
}
units = append(units, models.RepoUnit{
RepoID: repo.ID,
Type: models.UnitTypeIssues,
Config: config,
})
}

if opts.HasWiki == nil {
Expand All @@ -690,16 +741,39 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
units = append(units, *unit)
}
} else if *opts.HasWiki {
// We don't currently allow setting individual wiki settings through the API,
// only can enable/disable the wiki, so when enabling the wiki,
// we either get the existing config which means it was already enabled,
// or create a new config since it doesn't exist.
config := &models.UnitConfig{}
units = append(units, models.RepoUnit{
RepoID: repo.ID,
Type: models.UnitTypeWiki,
Config: config,
})
if opts.ExternalWiki != nil && *opts.ExternalWiki {
var config *models.ExternalWikiConfig
if unit, err := repo.GetUnit(models.UnitTypeExternalWiki); err != nil {
// Unit type doesn't exist so we make a new config file, default empty strings
config = &models.ExternalWikiConfig{
ExternalWikiURL: "",
}
} else {
config = unit.ExternalWikiConfig()
}

// Update values if set and valid
if opts.ExternalWikiURL != nil {
if !validation.IsValidExternalURL(*opts.ExternalWikiURL) {
err := fmt.Errorf("External wiki URL not valid")
ctx.Error(http.StatusBadRequest, "", "Invalid external wiki URL")
return err
}
config.ExternalWikiURL = *opts.ExternalWikiURL
}
units = append(units, models.RepoUnit{
RepoID: repo.ID,
Type: models.UnitTypeExternalWiki,
Config: config,
})
} else {
config := &models.UnitConfig{}
units = append(units, models.RepoUnit{
RepoID: repo.ID,
Type: models.UnitTypeWiki,
Config: config,
})
}
}

if opts.HasPullRequests == nil {
Expand Down
Loading

0 comments on commit 7e5c953

Please sign in to comment.