1// Copyright 2013 The go-github AUTHORS. All rights reserved.
2//
3// Use of this source code is governed by a BSD-style
4// license that can be found in the LICENSE file.
5
6package github
7
8import (
9	"context"
10	"fmt"
11
12	"encoding/json"
13)
14
15// RepositoryListForksOptions specifies the optional parameters to the
16// RepositoriesService.ListForks method.
17type RepositoryListForksOptions struct {
18	// How to sort the forks list. Possible values are: newest, oldest,
19	// watchers. Default is "newest".
20	Sort string `url:"sort,omitempty"`
21
22	ListOptions
23}
24
25// ListForks lists the forks of the specified repository.
26//
27// GitHub API docs: https://developer.github.com/v3/repos/forks/#list-forks
28func (s *RepositoriesService) ListForks(ctx context.Context, owner, repo string, opt *RepositoryListForksOptions) ([]*Repository, *Response, error) {
29	u := fmt.Sprintf("repos/%v/%v/forks", owner, repo)
30	u, err := addOptions(u, opt)
31	if err != nil {
32		return nil, nil, err
33	}
34
35	req, err := s.client.NewRequest("GET", u, nil)
36	if err != nil {
37		return nil, nil, err
38	}
39
40	// TODO: remove custom Accept header when topics API fully launches.
41	req.Header.Set("Accept", mediaTypeTopicsPreview)
42
43	var repos []*Repository
44	resp, err := s.client.Do(ctx, req, &repos)
45	if err != nil {
46		return nil, resp, err
47	}
48
49	return repos, resp, nil
50}
51
52// RepositoryCreateForkOptions specifies the optional parameters to the
53// RepositoriesService.CreateFork method.
54type RepositoryCreateForkOptions struct {
55	// The organization to fork the repository into.
56	Organization string `url:"organization,omitempty"`
57}
58
59// CreateFork creates a fork of the specified repository.
60//
61// This method might return an *AcceptedError and a status code of
62// 202. This is because this is the status that GitHub returns to signify that
63// it is now computing creating the fork in a background task. In this event,
64// the Repository value will be returned, which includes the details about the pending fork.
65// A follow up request, after a delay of a second or so, should result
66// in a successful request.
67//
68// GitHub API docs: https://developer.github.com/v3/repos/forks/#create-a-fork
69func (s *RepositoriesService) CreateFork(ctx context.Context, owner, repo string, opt *RepositoryCreateForkOptions) (*Repository, *Response, error) {
70	u := fmt.Sprintf("repos/%v/%v/forks", owner, repo)
71	u, err := addOptions(u, opt)
72	if err != nil {
73		return nil, nil, err
74	}
75
76	req, err := s.client.NewRequest("POST", u, nil)
77	if err != nil {
78		return nil, nil, err
79	}
80
81	fork := new(Repository)
82	resp, err := s.client.Do(ctx, req, fork)
83	if err != nil {
84		// Persist AcceptedError's metadata to the Repository object.
85		if aerr, ok := err.(*AcceptedError); ok {
86			if err := json.Unmarshal(aerr.Raw, fork); err != nil {
87				return fork, resp, err
88			}
89
90			return fork, resp, err
91		}
92		return nil, resp, err
93	}
94
95	return fork, resp, nil
96}
97