Skip to content

Commit 8aaae79

Browse files
authored
Merge pull request #1722 from hbontempo-br/feature/keep_repos_up_to_date
Adds routine to keep repo up to date
2 parents a2e13a0 + 2c30b6f commit 8aaae79

File tree

7 files changed

+127
-21
lines changed

7 files changed

+127
-21
lines changed

app/models/github_fetcher/resource.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ def success?
5656
false
5757
end
5858

59+
def not_found?
60+
status == 404 ? true : false
61+
end
62+
5963
def bad_token?
6064
if status == 401 && response.body.match?(/Bad credentials/)
6165
@error = @error_message = "Bad credentials"

app/models/repo.rb

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def fetcher
3737
end
3838

3939
def fetcher_json
40-
fetcher.as_json
40+
@fetcher_json ||= fetcher.as_json
4141
end
4242

4343
def issues_fetcher
@@ -192,12 +192,27 @@ def self.exists_with_name?(name)
192192
end
193193

194194
def update_from_github
195-
json = fetcher.as_json
196-
self.update(
197-
language: json.fetch('language', language),
198-
description: json.fetch('description', description)&.first(255),
199-
stars_count: json.fetch('stargazers_count', stars_count)
200-
)
195+
if fetcher.not_found?
196+
self.update!(removed_from_github: true)
197+
elsif fetcher.success?
198+
repo_full_name = fetcher_json.fetch('full_name', full_name)
199+
200+
if repo_full_name != full_name && self.class.exists_with_name?(repo_full_name)
201+
# TODO: Add deduplication step
202+
return
203+
end
204+
205+
repo_user_name, repo_name = repo_full_name.split("/")
206+
self.update!(
207+
name: repo_name,
208+
user_name: repo_user_name,
209+
language: fetcher_json.fetch('language', language),
210+
description: fetcher_json.fetch('description', description)&.first(255),
211+
full_name: repo_full_name,
212+
removed_from_github: false,
213+
archived: fetcher_json.fetch('archived', archived)
214+
)
215+
end
201216
end
202217

203218
def repo_path
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class AddArchivedColumnToRepo < ActiveRecord::Migration[7.0]
2+
def change
3+
add_column :repos, :archived, :boolean, default: false
4+
add_index :repos, :archived
5+
end
6+
end

db/schema.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

13-
ActiveRecord::Schema[7.0].define(version: 2022_10_10_011048) do
13+
ActiveRecord::Schema[7.0].define(version: 2022_10_13_212959) do
1414
# These are extensions that must be enabled in order to support this database
1515
enable_extension "pg_stat_statements"
1616
enable_extension "plpgsql"
@@ -155,6 +155,8 @@
155155
t.integer "subscribers_count", default: 0
156156
t.integer "docs_subscriber_count", default: 0
157157
t.boolean "removed_from_github", default: false
158+
t.boolean "archived", default: false
159+
t.index ["archived"], name: "index_repos_on_archived"
158160
t.index ["full_name"], name: "index_repos_on_full_name"
159161
t.index ["issues_count"], name: "index_repos_on_issues_count"
160162
t.index ["language"], name: "index_repos_on_language"

lib/tasks/schedule.rake

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,12 @@ namespace :schedule do
3838
return GithubFetcher::Repo.new(user_name: "rails", name: "rails").success?
3939
end
4040

41-
desc "Checks if repos have been deleted on GitHub"
42-
task mark_removed_repos: :environment do
41+
desc "Update repos information"
42+
task update_repos: :environment do
4343
raise "GITHUB API APPEARS TO BE DOWN" unless github_api_up?
4444

45-
Repo.select(:id, :user_name, :name).find_each(batch_size: 100) do |repo|
46-
fetcher = GithubFetcher::Repo.new(user_name: repo.user_name, name: repo.name)
47-
fetcher.call(retry_on_bad_token: 5)
48-
49-
if fetcher.response.status == 404
50-
repo.update!(removed_from_github: true)
51-
end
45+
Repo.find_each(batch_size: 100) do |repo|
46+
repo.update_repo_info!
5247
end
5348
end
5449

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,74 @@
11
# frozen_string_literal: true
22

33
require 'test_helper'
4-
54
class UpdateRepoInfoJobTest < ActiveJob::TestCase
6-
# test "the truth" do
7-
# assert true
8-
# end
5+
test 'repo deleted or made private' do
6+
GithubFetcher::Resource.any_instance.stubs(:status).returns(404)
7+
repo = repos(:node)
8+
assert_changes -> {
9+
[
10+
repo.removed_from_github,
11+
]
12+
} do
13+
UpdateRepoInfoJob.perform_now(repo)
14+
repo.reload
15+
end
16+
assert repo.removed_from_github
17+
end
18+
19+
test 'repo with information updated' do
20+
GithubFetcher::Resource.any_instance.stubs(:status).returns(200)
21+
GithubFetcher::Resource.any_instance.stubs(:as_json).returns(
22+
{
23+
'full_name' => 'test_owner/test_repo',
24+
'language' => 'test_language',
25+
'description' => 'test_description',
26+
'archived' => true
27+
}
28+
)
29+
repo = repos(:node)
30+
assert_changes -> {
31+
[
32+
repo.full_name,
33+
repo.name,
34+
repo.user_name,
35+
repo.language,
36+
repo.description,
37+
repo.archived
38+
]
39+
} do
40+
UpdateRepoInfoJob.perform_now(repo)
41+
repo.reload
42+
end
43+
assert_equal false, repo.removed_from_github
44+
assert_equal 'test_owner/test_repo', repo.full_name
45+
assert_equal 'test_repo', repo.name
46+
assert_equal 'test_owner', repo.user_name
47+
assert_equal 'test_language', repo.language
48+
assert_equal 'test_description', repo.description
49+
assert_equal true, repo.archived
50+
end
51+
52+
test 'repo rename conflict' do
53+
GithubFetcher::Resource.any_instance.stubs(:status).returns(200)
54+
GithubFetcher::Resource.any_instance.stubs(:as_json).returns(
55+
{
56+
'full_name' => 'sinatra/sinatra',
57+
}
58+
)
59+
repo = repos(:node)
60+
assert_no_changes -> {
61+
[
62+
repo.full_name,
63+
repo.name,
64+
repo.user_name,
65+
repo.language,
66+
repo.description,
67+
repo.archived
68+
]
69+
} do
70+
UpdateRepoInfoJob.perform_now(repo)
71+
repo.reload
72+
end
73+
end
974
end
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# frozen_string_literal: true
2+
3+
require 'test_helper'
4+
5+
class GithubFetcher::ResourceTest < ActiveSupport::TestCase
6+
def status_validation(mocked_status, method, expected_response)
7+
GithubFetcher::Resource.any_instance.stubs(:status).returns(mocked_status)
8+
resource = GithubFetcher::Resource.new({})
9+
assert_equal expected_response, resource.send(method)
10+
end
11+
12+
test '#not_found? is true on 404 status responses' do
13+
status_validation(404, :not_found?, true)
14+
end
15+
16+
test '#not_found? is false on non 404 status responses' do
17+
[200, 201, 204, 400, 403, 500, 502].each { |status| status_validation(status, :not_found?, false) }
18+
end
19+
end

0 commit comments

Comments
 (0)