2024-02-23 00:26:49 +00:00
// Copyright 2024 The Forgjo Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
2014-11-14 22:07:41 +00:00
// Copyright 2014 The Gogs Authors. All rights reserved.
2020-09-12 14:58:08 +01:00
// Copyright 2020 The Gitea Authors. All rights reserved.
2014-11-14 22:07:41 +00:00
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
2024-02-23 00:26:49 +00:00
package forgejo
2014-11-14 22:07:41 +00:00
2014-12-13 01:29:51 +00:00
import (
"bytes"
"encoding/json"
"fmt"
2021-01-17 17:14:07 +00:00
"io"
2020-02-01 06:26:12 +00:00
"net/url"
2020-06-09 11:47:55 +01:00
"strings"
2019-10-13 02:34:01 +01:00
"time"
2014-12-13 01:29:51 +00:00
)
2019-10-13 02:34:01 +01:00
// Permission represents a set of permissions
type Permission struct {
Admin bool ` json:"admin" `
Push bool ` json:"push" `
Pull bool ` json:"pull" `
}
2014-11-14 22:07:41 +00:00
2021-02-13 19:24:00 +00:00
// InternalTracker represents settings for internal tracker
type InternalTracker struct {
// Enable time tracking (Built-in issue tracker)
EnableTimeTracker bool ` json:"enable_time_tracker" `
// Let only contributors track time (Built-in issue tracker)
AllowOnlyContributorsToTrackTime bool ` json:"allow_only_contributors_to_track_time" `
// Enable dependencies for issues and pull requests (Built-in issue tracker)
EnableIssueDependencies bool ` json:"enable_issue_dependencies" `
}
// ExternalTracker represents settings for external tracker
type ExternalTracker struct {
// URL of external issue tracker.
ExternalTrackerURL string ` json:"external_tracker_url" `
// 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" `
// External Issue Tracker Number Format, either `numeric` or `alphanumeric`
ExternalTrackerStyle string ` json:"external_tracker_style" `
}
// ExternalWiki represents setting for external wiki
type ExternalWiki struct {
// URL of external wiki.
ExternalWikiURL string ` json:"external_wiki_url" `
}
2019-10-13 02:34:01 +01:00
// Repository represents a repository
type Repository struct {
2021-02-13 19:24:00 +00:00
ID int64 ` json:"id" `
Owner * User ` json:"owner" `
Name string ` json:"name" `
FullName string ` json:"full_name" `
Description string ` json:"description" `
Empty bool ` json:"empty" `
Private bool ` json:"private" `
Fork bool ` json:"fork" `
Template bool ` json:"template" `
Parent * Repository ` json:"parent" `
Mirror bool ` json:"mirror" `
Size int ` json:"size" `
HTMLURL string ` json:"html_url" `
SSHURL string ` json:"ssh_url" `
CloneURL string ` json:"clone_url" `
OriginalURL string ` json:"original_url" `
Website string ` json:"website" `
Stars int ` json:"stars_count" `
Forks int ` json:"forks_count" `
Watchers int ` json:"watchers_count" `
OpenIssues int ` json:"open_issues_count" `
OpenPulls int ` json:"open_pr_counter" `
Releases int ` json:"release_counter" `
DefaultBranch string ` json:"default_branch" `
Archived bool ` json:"archived" `
Created time . Time ` json:"created_at" `
Updated time . Time ` json:"updated_at" `
Permissions * Permission ` json:"permissions,omitempty" `
HasIssues bool ` json:"has_issues" `
InternalTracker * InternalTracker ` json:"internal_tracker,omitempty" `
ExternalTracker * ExternalTracker ` json:"external_tracker,omitempty" `
HasWiki bool ` json:"has_wiki" `
ExternalWiki * ExternalWiki ` json:"external_wiki,omitempty" `
HasPullRequests bool ` json:"has_pull_requests" `
HasProjects bool ` json:"has_projects" `
2023-12-24 20:16:02 +00:00
HasReleases bool ` json:"has_releases,omitempty" `
HasPackages bool ` json:"has_packages,omitempty" `
HasActions bool ` json:"has_actions,omitempty" `
2021-02-13 19:24:00 +00:00
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" `
Internal bool ` json:"internal" `
MirrorInterval string ` json:"mirror_interval" `
2022-03-28 12:06:48 +01:00
MirrorUpdated time . Time ` json:"mirror_updated,omitempty" `
2021-07-01 16:10:21 +01:00
DefaultMergeStyle MergeStyle ` json:"default_merge_style" `
2019-10-13 02:34:01 +01:00
}
2019-08-02 16:44:35 +01:00
2020-07-11 20:54:57 +01:00
// RepoType represent repo type
type RepoType string
const (
// RepoTypeNone dont specify a type
RepoTypeNone RepoType = ""
// RepoTypeSource is the default repo type
RepoTypeSource RepoType = "source"
// RepoTypeFork is a repo witch was forked from an other one
RepoTypeFork RepoType = "fork"
// RepoTypeMirror represents an mirror repo
RepoTypeMirror RepoType = "mirror"
)
2020-11-09 15:57:26 +00:00
// TrustModel represent how git signatures are handled in a repository
type TrustModel string
const (
// TrustModelDefault use TM set by global config
TrustModelDefault TrustModel = "default"
// TrustModelCollaborator gpg signature has to be owned by a repo collaborator
TrustModelCollaborator TrustModel = "collaborator"
// TrustModelCommitter gpg signature has to match committer
TrustModelCommitter TrustModel = "committer"
// TrustModelCollaboratorCommitter gpg signature has to match committer and owned by a repo collaborator
TrustModelCollaboratorCommitter TrustModel = "collaboratorcommitter"
)
2020-02-05 07:59:55 +00:00
// ListReposOptions options for listing repositories
type ListReposOptions struct {
ListOptions
}
2014-11-14 22:07:41 +00:00
// ListMyRepos lists all repositories for the authenticated user that has access to.
2020-09-14 03:37:09 +01:00
func ( c * Client ) ListMyRepos ( opt ListReposOptions ) ( [ ] * Repository , * Response , error ) {
2020-02-05 07:59:55 +00:00
opt . setDefaults ( )
repos := make ( [ ] * Repository , 0 , opt . PageSize )
2020-09-14 03:37:09 +01:00
resp , err := c . getParsedResponse ( "GET" , fmt . Sprintf ( "/user/repos?%s" , opt . getURLQuery ( ) . Encode ( ) ) , nil , nil , & repos )
return repos , resp , err
2014-11-14 22:07:41 +00:00
}
2014-12-13 01:29:51 +00:00
2016-11-10 09:44:00 +00:00
// ListUserRepos list all repositories of one user by user's name
2020-09-14 03:37:09 +01:00
func ( c * Client ) ListUserRepos ( user string , opt ListReposOptions ) ( [ ] * Repository , * Response , error ) {
2021-03-21 20:20:32 +00:00
if err := escapeValidatePathSegments ( & user ) ; err != nil {
return nil , nil , err
}
2020-02-05 07:59:55 +00:00
opt . setDefaults ( )
repos := make ( [ ] * Repository , 0 , opt . PageSize )
2020-09-14 03:37:09 +01:00
resp , err := c . getParsedResponse ( "GET" , fmt . Sprintf ( "/users/%s/repos?%s" , user , opt . getURLQuery ( ) . Encode ( ) ) , nil , nil , & repos )
return repos , resp , err
2020-02-05 07:59:55 +00:00
}
// ListOrgReposOptions options for a organization's repositories
type ListOrgReposOptions struct {
ListOptions
2016-08-28 13:35:23 +01:00
}
2016-11-10 09:44:00 +00:00
// ListOrgRepos list all repositories of one organization by organization's name
2020-09-14 03:37:09 +01:00
func ( c * Client ) ListOrgRepos ( org string , opt ListOrgReposOptions ) ( [ ] * Repository , * Response , error ) {
2021-03-21 20:20:32 +00:00
if err := escapeValidatePathSegments ( & org ) ; err != nil {
return nil , nil , err
}
2020-02-05 07:59:55 +00:00
opt . setDefaults ( )
repos := make ( [ ] * Repository , 0 , opt . PageSize )
2020-09-14 03:37:09 +01:00
resp , err := c . getParsedResponse ( "GET" , fmt . Sprintf ( "/orgs/%s/repos?%s" , org , opt . getURLQuery ( ) . Encode ( ) ) , nil , nil , & repos )
return repos , resp , err
2014-11-14 22:07:41 +00:00
}
2014-12-13 01:29:51 +00:00
2020-02-01 06:26:12 +00:00
// SearchRepoOptions options for searching repositories
type SearchRepoOptions struct {
2020-02-05 07:59:55 +00:00
ListOptions
2020-07-11 20:54:57 +01:00
// The keyword to query
Keyword string
// Limit search to repositories with keyword as topic
KeywordIsTopic bool
// Include search of keyword within repository description
KeywordInDescription bool
/ *
User Filter
* /
// Repo Owner
OwnerID int64
// Stared By UserID
StarredByUserID int64
/ *
Repo Attributes
* /
// pubic, private or all repositories (defaults to all)
IsPrivate * bool
// archived, non-archived or all repositories (defaults to all)
IsArchived * bool
// Exclude template repos from search
ExcludeTemplate bool
// Filter by "fork", "source", "mirror"
Type RepoType
/ *
Sort Filters
* /
// sort repos by attribute. Supported values are "alpha", "created", "updated", "size", and "id". Default is "alpha"
Sort string
// sort order, either "asc" (ascending) or "desc" (descending). Default is "asc", ignored if "sort" is not specified.
Order string
// Repo owner to prioritize in the results
PrioritizedByOwnerID int64
/ *
Cover EdgeCases
* /
// if set all other options are ignored and this string is used as query
RawQuery string
2020-02-01 06:26:12 +00:00
}
// QueryEncode turns options into querystring argument
func ( opt * SearchRepoOptions ) QueryEncode ( ) string {
2020-02-05 07:59:55 +00:00
query := opt . getURLQuery ( )
2020-02-01 06:26:12 +00:00
if opt . Keyword != "" {
query . Add ( "q" , opt . Keyword )
}
2020-07-11 20:54:57 +01:00
if opt . KeywordIsTopic {
query . Add ( "topic" , "true" )
2020-02-01 06:26:12 +00:00
}
2020-07-11 20:54:57 +01:00
if opt . KeywordInDescription {
query . Add ( "includeDesc" , "true" )
2020-02-01 06:26:12 +00:00
}
2020-07-11 20:54:57 +01:00
// User Filter
if opt . OwnerID > 0 {
query . Add ( "uid" , fmt . Sprintf ( "%d" , opt . OwnerID ) )
query . Add ( "exclusive" , "true" )
2020-02-01 06:26:12 +00:00
}
2020-07-11 20:54:57 +01:00
if opt . StarredByUserID > 0 {
query . Add ( "starredBy" , fmt . Sprintf ( "%d" , opt . StarredByUserID ) )
2020-02-01 06:26:12 +00:00
}
2020-07-11 20:54:57 +01:00
// Repo Attributes
if opt . IsPrivate != nil {
query . Add ( "is_private" , fmt . Sprintf ( "%v" , opt . IsPrivate ) )
}
if opt . IsArchived != nil {
query . Add ( "archived" , fmt . Sprintf ( "%v" , opt . IsArchived ) )
}
if opt . ExcludeTemplate {
query . Add ( "template" , "false" )
}
if len ( opt . Type ) != 0 {
query . Add ( "mode" , string ( opt . Type ) )
}
2020-02-01 06:26:12 +00:00
2020-07-11 20:54:57 +01:00
// Sort Filters
2020-02-01 06:26:12 +00:00
if opt . Sort != "" {
query . Add ( "sort" , opt . Sort )
}
2020-07-11 20:54:57 +01:00
if opt . PrioritizedByOwnerID > 0 {
query . Add ( "priority_owner_id" , fmt . Sprintf ( "%d" , opt . PrioritizedByOwnerID ) )
}
if opt . Order != "" {
query . Add ( "order" , opt . Order )
}
2020-02-01 06:26:12 +00:00
return query . Encode ( )
}
type searchRepoResponse struct {
Repos [ ] * Repository ` json:"data" `
}
// SearchRepos searches for repositories matching the given filters
2020-09-14 03:37:09 +01:00
func ( c * Client ) SearchRepos ( opt SearchRepoOptions ) ( [ ] * Repository , * Response , error ) {
2020-02-05 07:59:55 +00:00
opt . setDefaults ( )
2020-09-14 03:37:09 +01:00
repos := new ( searchRepoResponse )
2020-02-01 06:26:12 +00:00
link , _ := url . Parse ( "/repos/search" )
2020-07-11 20:54:57 +01:00
if len ( opt . RawQuery ) != 0 {
link . RawQuery = opt . RawQuery
} else {
link . RawQuery = opt . QueryEncode ( )
2024-02-23 00:26:49 +00:00
// IsPrivate only works on forgejo >= 1.12.0
2020-11-12 20:59:04 +00:00
if err := c . checkServerVersionGreaterThanOrEqual ( version1_12_0 ) ; err != nil && opt . IsPrivate != nil {
2020-07-11 20:54:57 +01:00
if * opt . IsPrivate {
2024-02-23 00:26:49 +00:00
// private repos only not supported on forgejo <= 1.11.x
2020-09-14 03:37:09 +01:00
return nil , nil , err
2020-07-11 20:54:57 +01:00
}
2022-04-28 16:33:21 +01:00
newQuery := link . Query ( )
newQuery . Add ( "private" , "false" )
link . RawQuery = newQuery . Encode ( )
2020-07-11 20:54:57 +01:00
}
}
2020-02-01 06:26:12 +00:00
2020-09-14 03:37:09 +01:00
resp , err := c . getParsedResponse ( "GET" , link . String ( ) , nil , nil , & repos )
return repos . Repos , resp , err
2020-02-01 06:26:12 +00:00
}
2019-10-13 02:34:01 +01:00
// CreateRepoOption options when creating repository
type CreateRepoOption struct {
// Name of the repository to create
Name string ` json:"name" `
// Description of the repository to create
Description string ` json:"description" `
// Whether the repository is private
Private bool ` json:"private" `
// Issue Label set to use
IssueLabels string ` json:"issue_labels" `
// Whether the repository should be auto-intialized?
AutoInit bool ` json:"auto_init" `
2020-11-09 15:57:26 +00:00
// Whether the repository is template
Template bool ` json:"template" `
2019-10-13 02:34:01 +01:00
// Gitignores to use
Gitignores string ` json:"gitignores" `
// License to use
License string ` json:"license" `
// Readme of the repository to create
Readme string ` json:"readme" `
2020-04-01 03:59:16 +01:00
// DefaultBranch of the repository (used when initializes and in template)
DefaultBranch string ` json:"default_branch" `
2020-11-09 15:57:26 +00:00
// TrustModel of the repository
TrustModel TrustModel ` json:"trust_model" `
2019-10-13 02:34:01 +01:00
}
2020-06-09 11:47:55 +01:00
// Validate the CreateRepoOption struct
2020-11-09 15:57:26 +00:00
func ( opt CreateRepoOption ) Validate ( c * Client ) error {
2020-06-09 11:47:55 +01:00
if len ( strings . TrimSpace ( opt . Name ) ) == 0 {
return fmt . Errorf ( "name is empty" )
}
2020-11-09 15:57:26 +00:00
if len ( opt . Name ) > 100 {
return fmt . Errorf ( "name has more than 100 chars" )
}
2023-12-30 04:48:39 +00:00
if len ( opt . Description ) > 2048 {
return fmt . Errorf ( "description has more than 2048 chars" )
2020-11-09 15:57:26 +00:00
}
if len ( opt . DefaultBranch ) > 100 {
2022-01-31 23:14:45 +00:00
return fmt . Errorf ( "default branch name has more than 100 chars" )
2020-11-09 15:57:26 +00:00
}
if len ( opt . TrustModel ) != 0 {
2022-01-04 16:31:31 +00:00
if err := c . checkServerVersionGreaterThanOrEqual ( version1_13_0 ) ; err != nil {
2020-11-09 15:57:26 +00:00
return err
}
}
2020-06-09 11:47:55 +01:00
return nil
}
2014-12-13 01:29:51 +00:00
// CreateRepo creates a repository for authenticated user.
2020-09-14 03:37:09 +01:00
func ( c * Client ) CreateRepo ( opt CreateRepoOption ) ( * Repository , * Response , error ) {
2020-11-09 15:57:26 +00:00
if err := opt . Validate ( c ) ; err != nil {
2020-09-14 03:37:09 +01:00
return nil , nil , err
2020-06-09 11:47:55 +01:00
}
2014-12-13 01:29:51 +00:00
body , err := json . Marshal ( & opt )
if err != nil {
2020-09-14 03:37:09 +01:00
return nil , nil , err
2014-12-13 01:29:51 +00:00
}
repo := new ( Repository )
2020-09-14 03:37:09 +01:00
resp , err := c . getParsedResponse ( "POST" , "/user/repos" , jsonHeader , bytes . NewReader ( body ) , repo )
return repo , resp , err
2014-12-13 01:29:51 +00:00
}
// CreateOrgRepo creates an organization repository for authenticated user.
2020-09-14 03:37:09 +01:00
func ( c * Client ) CreateOrgRepo ( org string , opt CreateRepoOption ) ( * Repository , * Response , error ) {
2021-03-21 20:20:32 +00:00
if err := escapeValidatePathSegments ( & org ) ; err != nil {
return nil , nil , err
}
2020-11-09 15:57:26 +00:00
if err := opt . Validate ( c ) ; err != nil {
2020-09-14 03:37:09 +01:00
return nil , nil , err
2020-06-09 11:47:55 +01:00
}
2014-12-13 01:29:51 +00:00
body , err := json . Marshal ( & opt )
if err != nil {
2020-09-14 03:37:09 +01:00
return nil , nil , err
2014-12-13 01:29:51 +00:00
}
repo := new ( Repository )
2020-09-14 03:37:09 +01:00
resp , err := c . getParsedResponse ( "POST" , fmt . Sprintf ( "/org/%s/repos" , org ) , jsonHeader , bytes . NewReader ( body ) , repo )
return repo , resp , err
2014-12-13 01:29:51 +00:00
}
2015-10-09 02:00:46 +01:00
2015-10-22 22:42:42 +01:00
// GetRepo returns information of a repository of given owner.
2020-09-14 03:37:09 +01:00
func ( c * Client ) GetRepo ( owner , reponame string ) ( * Repository , * Response , error ) {
2021-03-21 20:20:32 +00:00
if err := escapeValidatePathSegments ( & owner , & reponame ) ; err != nil {
return nil , nil , err
}
2015-10-22 22:42:42 +01:00
repo := new ( Repository )
2020-09-14 03:37:09 +01:00
resp , err := c . getParsedResponse ( "GET" , fmt . Sprintf ( "/repos/%s/%s" , owner , reponame ) , nil , nil , repo )
return repo , resp , err
2015-10-22 22:42:42 +01:00
}
2021-04-03 17:35:19 +01:00
// GetRepoByID returns information of a repository by a giver repository ID.
func ( c * Client ) GetRepoByID ( id int64 ) ( * Repository , * Response , error ) {
repo := new ( Repository )
resp , err := c . getParsedResponse ( "GET" , fmt . Sprintf ( "/repositories/%d" , id ) , nil , nil , repo )
return repo , resp , err
}
2019-10-13 02:34:01 +01:00
// EditRepoOption options when editing a repository's properties
type EditRepoOption struct {
// name of the repository
Name * string ` json:"name,omitempty" `
// a short description of the repository.
Description * string ` json:"description,omitempty" `
// a URL with more information about the repository.
Website * string ` json:"website,omitempty" `
// either `true` to make the repository private or `false` to make it public.
// Note: you will get a 422 error if the organization restricts changing repository visibility to organization
// owners and a non-owner tries to change the value of private.
Private * bool ` json:"private,omitempty" `
2021-02-13 19:24:00 +00:00
// either `true` to make this repository a template or `false` to make it a normal repository
Template * bool ` json:"template,omitempty" `
2019-10-13 02:34:01 +01:00
// either `true` to enable issues for this repository or `false` to disable them.
HasIssues * bool ` json:"has_issues,omitempty" `
2021-02-13 19:24:00 +00:00
// set this structure to configure internal issue tracker (requires has_issues)
InternalTracker * InternalTracker ` json:"internal_tracker,omitempty" `
// set this structure to use external issue tracker (requires has_issues)
ExternalTracker * ExternalTracker ` json:"external_tracker,omitempty" `
2019-10-13 02:34:01 +01:00
// either `true` to enable the wiki for this repository or `false` to disable it.
HasWiki * bool ` json:"has_wiki,omitempty" `
2021-02-13 19:24:00 +00:00
// set this structure to use external wiki instead of internal (requires has_wiki)
ExternalWiki * ExternalWiki ` json:"external_wiki,omitempty" `
2019-10-13 02:34:01 +01:00
// 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.
HasPullRequests * bool ` json:"has_pull_requests,omitempty" `
2021-02-13 19:24:00 +00:00
// either `true` to enable project unit, or `false` to disable them.
HasProjects * bool ` json:"has_projects,omitempty" `
2023-12-24 20:16:02 +00:00
// either `true` to enable release, or `false` to disable them.
HasReleases * bool ` json:"has_releases,omitempty" `
// either `true` to enable packages, or `false` to disable them.
HasPackages * bool ` json:"has_packages,omitempty" `
// either `true` to enable actions, or `false` to disable them.
HasActions * bool ` json:"has_actions,omitempty" `
2019-10-13 02:34:01 +01:00
// either `true` to ignore whitespace for conflicts, or `false` to not ignore whitespace. `has_pull_requests` must be `true`.
IgnoreWhitespaceConflicts * bool ` json:"ignore_whitespace_conflicts,omitempty" `
// either `true` to allow merging pull requests with a merge commit, or `false` to prevent merging pull requests with merge commits. `has_pull_requests` must be `true`.
AllowMerge * bool ` json:"allow_merge_commits,omitempty" `
// either `true` to allow rebase-merging pull requests, or `false` to prevent rebase-merging. `has_pull_requests` must be `true`.
AllowRebase * bool ` json:"allow_rebase,omitempty" `
// either `true` to allow rebase with explicit merge commits (--no-ff), or `false` to prevent rebase with explicit merge commits. `has_pull_requests` must be `true`.
AllowRebaseMerge * bool ` json:"allow_rebase_explicit,omitempty" `
// either `true` to allow squash-merging pull requests, or `false` to prevent squash-merging. `has_pull_requests` must be `true`.
AllowSquash * bool ` json:"allow_squash_merge,omitempty" `
// set to `true` to archive this repository.
Archived * bool ` json:"archived,omitempty" `
2021-02-13 19:24:00 +00:00
// set to a string like `8h30m0s` to set the mirror interval time
MirrorInterval * string ` json:"mirror_interval,omitempty" `
2021-07-01 16:10:21 +01:00
// either `true` to allow mark pr as merged manually, or `false` to prevent it. `has_pull_requests` must be `true`.
AllowManualMerge * bool ` json:"allow_manual_merge,omitempty" `
// either `true` to enable AutodetectManualMerge, or `false` to prevent it. `has_pull_requests` must be `true`, Note: In some special cases, misjudgments can occur.
AutodetectManualMerge * bool ` json:"autodetect_manual_merge,omitempty" `
// set to a merge style to be used by this repository: "merge", "rebase", "rebase-merge", or "squash". `has_pull_requests` must be `true`.
DefaultMergeStyle * MergeStyle ` json:"default_merge_style,omitempty" `
// set to `true` to archive this repository.
2019-10-13 02:34:01 +01:00
}
2019-05-10 23:30:00 +01:00
// EditRepo edit the properties of a repository
2020-09-14 03:37:09 +01:00
func ( c * Client ) EditRepo ( owner , reponame string , opt EditRepoOption ) ( * Repository , * Response , error ) {
2021-03-21 20:20:32 +00:00
if err := escapeValidatePathSegments ( & owner , & reponame ) ; err != nil {
return nil , nil , err
}
2019-05-10 23:30:00 +01:00
body , err := json . Marshal ( & opt )
if err != nil {
2020-09-14 03:37:09 +01:00
return nil , nil , err
2019-05-10 23:30:00 +01:00
}
repo := new ( Repository )
2020-09-14 03:37:09 +01:00
resp , err := c . getParsedResponse ( "PATCH" , fmt . Sprintf ( "/repos/%s/%s" , owner , reponame ) , jsonHeader , bytes . NewReader ( body ) , repo )
return repo , resp , err
2019-05-10 23:30:00 +01:00
}
2015-10-09 02:00:46 +01:00
// DeleteRepo deletes a repository of user or organization.
2020-09-14 03:37:09 +01:00
func ( c * Client ) DeleteRepo ( owner , repo string ) ( * Response , error ) {
2021-03-21 20:20:32 +00:00
if err := escapeValidatePathSegments ( & owner , & repo ) ; err != nil {
return nil , err
}
2020-09-14 03:37:09 +01:00
_ , resp , err := c . getResponse ( "DELETE" , fmt . Sprintf ( "/repos/%s/%s" , owner , repo ) , nil , nil )
return resp , err
2015-10-09 02:00:46 +01:00
}
2015-10-28 16:04:48 +00:00
2017-05-02 16:01:11 +01:00
// MirrorSync adds a mirrored repository to the mirror sync queue.
2020-09-14 03:37:09 +01:00
func ( c * Client ) MirrorSync ( owner , repo string ) ( * Response , error ) {
2021-03-21 20:20:32 +00:00
if err := escapeValidatePathSegments ( & owner , & repo ) ; err != nil {
return nil , err
}
2020-09-14 03:37:09 +01:00
_ , resp , err := c . getResponse ( "POST" , fmt . Sprintf ( "/repos/%s/%s/mirror-sync" , owner , repo ) , nil , nil )
return resp , err
2017-05-02 16:01:11 +01:00
}
2020-09-06 18:20:00 +01:00
// GetRepoLanguages return language stats of a repo
2020-09-14 03:37:09 +01:00
func ( c * Client ) GetRepoLanguages ( owner , repo string ) ( map [ string ] int64 , * Response , error ) {
2021-03-21 20:20:32 +00:00
if err := escapeValidatePathSegments ( & owner , & repo ) ; err != nil {
return nil , nil , err
}
2020-09-06 18:20:00 +01:00
langMap := make ( map [ string ] int64 )
2020-09-14 03:37:09 +01:00
data , resp , err := c . getResponse ( "GET" , fmt . Sprintf ( "/repos/%s/%s/languages" , owner , repo ) , jsonHeader , nil )
2020-09-06 18:20:00 +01:00
if err != nil {
2020-09-14 03:37:09 +01:00
return nil , resp , err
2020-09-06 18:20:00 +01:00
}
if err = json . Unmarshal ( data , & langMap ) ; err != nil {
2020-09-14 03:37:09 +01:00
return nil , resp , err
2020-09-06 18:20:00 +01:00
}
2020-09-14 03:37:09 +01:00
return langMap , resp , nil
2020-09-06 18:20:00 +01:00
}
2020-09-06 23:14:39 +01:00
2024-02-23 00:26:49 +00:00
// ArchiveType represent supported archive formats by forgejo
2020-09-06 23:14:39 +01:00
type ArchiveType string
const (
// ZipArchive represent zip format
ZipArchive ArchiveType = ".zip"
// TarGZArchive represent tar.gz format
TarGZArchive ArchiveType = ".tar.gz"
)
// GetArchive get an archive of a repository by git reference
// e.g.: ref -> master, 70b7c74b33, v1.2.1, ...
2020-09-14 03:37:09 +01:00
func ( c * Client ) GetArchive ( owner , repo , ref string , ext ArchiveType ) ( [ ] byte , * Response , error ) {
2021-03-21 20:20:32 +00:00
if err := escapeValidatePathSegments ( & owner , & repo ) ; err != nil {
return nil , nil , err
}
ref = pathEscapeSegments ( ref )
return c . getResponse ( "GET" , fmt . Sprintf ( "/repos/%s/%s/archive/%s%s" , owner , repo , ref , ext ) , nil , nil )
2020-09-06 23:14:39 +01:00
}
2021-01-17 17:14:07 +00:00
// GetArchiveReader gets a `git archive` for a particular tree-ish git reference
// such as a branch name (`master`), a commit hash (`70b7c74b33`), a tag
// (`v1.2.1`). The archive is returned as a byte stream in a ReadCloser. It is
// the responsibility of the client to close the reader.
func ( c * Client ) GetArchiveReader ( owner , repo , ref string , ext ArchiveType ) ( io . ReadCloser , * Response , error ) {
2021-03-21 20:20:32 +00:00
if err := escapeValidatePathSegments ( & owner , & repo ) ; err != nil {
return nil , nil , err
}
ref = pathEscapeSegments ( ref )
resp , err := c . doRequest ( "GET" , fmt . Sprintf ( "/repos/%s/%s/archive/%s%s" , owner , repo , ref , ext ) , nil , nil )
2021-01-17 17:14:07 +00:00
if err != nil {
return nil , resp , err
}
if _ , err := statusCodeToErr ( resp ) ; err != nil {
return nil , resp , err
}
return resp . Body , resp , nil
}