From bf846bde74a5dd635fa7896a282b0af2e19a256f Mon Sep 17 00:00:00 2001 From: redowan Date: Fri, 15 Mar 2024 19:58:24 +0100 Subject: [PATCH] Fetch forked repos by modification date, refs #3 --- README.md | 28 ++++++++++++++-------------- src/cli.go | 23 +++++++++++------------ src/cli_test.go | 25 +++++++++++++------------ 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index c469b72..a3accbb 100644 --- a/README.md +++ b/README.md @@ -49,20 +49,20 @@ Remove unused GitHub forks ```txt Usage of fork-sweeper: - -delete - Delete forked repos - -max-page int - Maximum number of pages to fetch (default 100) - -older-than-days int - Fetch forked repos older than this number of days (default 60) - -owner string - GitHub repo owner (required) - -per-page int - Number of forked repos fetched per page (default 100) - -token string - GitHub access token (required) - -version - Print version + -delete + Delete forked repos + -max-page int + Maximum number of pages to fetch (default 100) + -older-than-days int + Fetch forked repos modified more than n days ago (default 60) + -owner string + GitHub repo owner (required) + -per-page int + Number of forked repos fetched per page (default 100) + -token string + GitHub access token (required) + -version + Print version ``` - List forked repos older than `n` days. By default, it'll fetch all repositories that diff --git a/src/cli.go b/src/cli.go index 497fba2..4f37765 100644 --- a/src/cli.go +++ b/src/cli.go @@ -27,7 +27,7 @@ type repo struct { Owner struct { Name string `json:"name"` } `json:"owner"` - CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } var httpClientPool = sync.Pool{ @@ -57,10 +57,8 @@ func fetchForkedReposPage( return nil, err } - req.Header.Add("Authorization", "Bearer "+token) - var repos []repo - if err := doRequest(req, &repos); err != nil { + if err := doRequest(req, token, &repos); err != nil { return nil, err } @@ -69,7 +67,7 @@ func fetchForkedReposPage( cutOffDate := time.Now().AddDate(0, 0, -olderThanDays) for _, repo := range repos { - if repo.IsFork && repo.CreatedAt.Before(cutOffDate) { + if repo.IsFork && repo.UpdatedAt.Before(cutOffDate) { forkedRepos = append(forkedRepos, repo) } } @@ -110,10 +108,13 @@ func fetchForkedRepos( return allRepos, nil } -func doRequest(req *http.Request, v any) error { +func doRequest(req *http.Request, token string, result any) error { httpClient := httpClientPool.Get().(*http.Client) defer httpClientPool.Put(httpClient) + req.Header.Add("Authorization", "Bearer "+token) + req.Header.Add("Accept", "application/vnd.github.v3+json") + resp, err := httpClient.Do(req) if err != nil { return err @@ -124,8 +125,8 @@ func doRequest(req *http.Request, v any) error { return fmt.Errorf("API request failed with status: %d", resp.StatusCode) } - if v != nil { - if err := json.NewDecoder(resp.Body).Decode(v); err != nil { + if result != nil { + if err := json.NewDecoder(resp.Body).Decode(result); err != nil { return err } } @@ -138,10 +139,8 @@ func deleteRepo(ctx context.Context, baseURL, owner, name, token string) error { if err != nil { return err } - req.Header.Add("Authorization", "Bearer "+token) - req.Header.Add("Accept", "application/vnd.github.v3+json") - return doRequest(req, nil) + return doRequest(req, token, nil) } func deleteRepos(ctx context.Context, baseURL, token string, repos []repo) error { @@ -263,7 +262,7 @@ func (c *cliConfig) CLI(args []string) int { &olderThanDays, "older-than-days", 60, - "Fetch forked repos older than this number of days") + "Fetch forked repos modified more than n days ago") fs.BoolVar(&version, "version", false, "Print version") fs.BoolVar(&delete, "delete", false, "Delete forked repos") diff --git a/src/cli_test.go b/src/cli_test.go index 58b5a28..7c55bc9 100644 --- a/src/cli_test.go +++ b/src/cli_test.go @@ -25,7 +25,7 @@ func TestUnmarshalRepo(t *testing.T) { "owner": { "name": "example" }, - "created_at": "2020-01-01T00:00:00Z" + "updated_at": "2020-01-01T00:00:00Z" }` // Expected repo object based on the JSON string @@ -38,7 +38,7 @@ func TestUnmarshalRepo(t *testing.T) { }{ Name: "example", }, - CreatedAt: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC), + UpdatedAt: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC), } // Unmarshal the JSON string into a repo struct @@ -67,7 +67,7 @@ func TestFetchForkedReposPage(t *testing.T) { w, `[{"full_name": "example/forkedrepo",`+ `"html_url": "https://github.com/example/forkedrepo", "fork": true,`+ - `"owner": {"name": "example"}, "created_at": "2020-01-01T00:00:00Z"}]`) + `"owner": {"name": "example"}, "updated_at": "2020-01-01T00:00:00Z"}]`) })) defer mockServer.Close() @@ -79,7 +79,7 @@ func TestFetchForkedReposPage(t *testing.T) { Owner: struct { Name string `json:"name"` }{Name: "example"}, - CreatedAt: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC), + UpdatedAt: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC), }, } @@ -98,7 +98,7 @@ func TestFetchForkedReposPage(t *testing.T) { repo.URL != expected[i].URL || repo.IsFork != expected[i].IsFork || repo.Owner.Name != expected[i].Owner.Name || - !repo.CreatedAt.Equal(expected[i].CreatedAt) { + !repo.UpdatedAt.Equal(expected[i].UpdatedAt) { t.Errorf("Expected repo %+v, got %+v", expected[i], repo) } } @@ -114,11 +114,11 @@ func TestFetchForkedRepos(t *testing.T) { w, `[{"full_name": "example/forkedrepo",`+ `"html_url": "https://test.com/example/forkedrepo", "fork": true,`+ - `"owner": {"name": "example"}, "created_at": "2020-01-01T00:00:00Z"},`+ + `"owner": {"name": "example"}, "updated_at": "2020-01-01T00:00:00Z"},`+ `{"full_name": "example/forkedrepo2",`+ `"html_url": "https://test.com/example/forkedrepo2", "fork": true,`+ - `"owner": {"name": "example2"}, "created_at": "2020-01-01T00:00:00Z"}]`) + `"owner": {"name": "example2"}, "updated_at": "2020-01-01T00:00:00Z"}]`) })) @@ -132,7 +132,7 @@ func TestFetchForkedRepos(t *testing.T) { Owner: struct { Name string `json:"name"` }{Name: "example"}, - CreatedAt: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC), + UpdatedAt: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC), }, { Name: "example/forkedrepo2", @@ -141,7 +141,7 @@ func TestFetchForkedRepos(t *testing.T) { Owner: struct { Name string `json:"name"` }{Name: "example2"}, - CreatedAt: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC), + UpdatedAt: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC), }, } @@ -166,7 +166,7 @@ func TestFetchForkedRepos(t *testing.T) { repo.URL != expected[i].URL || repo.IsFork != expected[i].IsFork || repo.Owner.Name != expected[i].Owner.Name || - !repo.CreatedAt.Equal(expected[i].CreatedAt) { + !repo.UpdatedAt.Equal(expected[i].UpdatedAt) { t.Errorf("Expected repo %+v, got %+v", expected[i], repo) } } @@ -219,9 +219,10 @@ func TestDoRequest(t *testing.T) { // Attempt to decode into this variable var result map[string]interface{} + var token string // Call doRequest with the mock server's URL - err := doRequest(req, &result) + err := doRequest(req, token, &result) // Check for error existence if (err != nil) != tt.wantErr { @@ -390,7 +391,7 @@ func TestCLI_Success(t *testing.T) { withFlagErrorHandling(mockFlagErrorHandler) // Execute the CLI - args := []string{"--owner", "testOwner", "--token", "testToken", "--older-than", "30"} + args := []string{"--owner", "testOwner", "--token", "testToken", "--older-than-days", "30"} exitCode := cliConfig.CLI(args)