-
-
Notifications
You must be signed in to change notification settings - Fork 159
Expand file tree
/
Copy pathsync_practice_exercise.rb
More file actions
126 lines (105 loc) · 4.59 KB
/
sync_practice_exercise.rb
File metadata and controls
126 lines (105 loc) · 4.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
class Git::SyncPracticeExercise < Git::Sync
include Mandate
def initialize(exercise, force_sync: false)
super(exercise.track, exercise.synced_to_git_sha)
@exercise = exercise
@force_sync = force_sync
end
def call
return exercise.update_columns(synced_to_git_sha: head_git_exercise.synced_git_sha) unless force_sync || exercise_needs_updating?
exercise.update!(
slug: exercise_config[:slug],
title: exercise_config[:name].presence,
status: exercise_config[:status] || :active,
difficulty: exercise_config[:difficulty],
icon_name: head_git_exercise.icon_name,
blurb: head_git_exercise.blurb,
position: exercise_position,
git_sha: head_git_exercise.synced_git_sha,
synced_to_git_sha: head_git_exercise.synced_git_sha,
prerequisites: find_concepts(exercise_config_prerequisites),
practiced_concepts: find_concepts(exercise_config[:practices]),
has_test_runner: head_git_exercise.has_test_runner?,
representer_version: head_git_exercise.representer_version
)
Git::SyncExerciseAuthors.(exercise)
Git::SyncExerciseContributors.(exercise)
Git::SyncExerciseApproaches.(exercise)
Git::SyncExerciseArticles.(exercise)
::Exercise::UpdateHasApproaches.(exercise)
SiteUpdates::ProcessNewExerciseUpdate.(exercise)
localize!(:exercise_instructions, exercise.instructions, exercise)
localize!(:exercise_introduction, exercise.introduction, exercise)
localize!(:exercise_title, exercise.title, exercise)
localize!(:exercise_blurb, exercise.blurb, exercise)
localize!(:exercise_source, exercise.source, exercise)
end
private
attr_reader :exercise, :force_sync
def localize!(type, content, exercise)
return unless content.present?
Localization::Text::AddToLocalization.defer(type, content, exercise)
end
def exercise_needs_updating?
track_config_exercise_modified? || exercise_config_modified? || exercise_files_modified?
end
def track_config_exercise_modified?
return false unless track_config_modified?
exercise_position != exercise.position ||
exercise_config[:slug] != exercise.slug ||
exercise_config[:name] != exercise.title ||
(exercise_config[:status] || :active) != exercise.status ||
exercise_config[:difficulty] != exercise.difficulty ||
exercise_config_prerequisites.sort != exercise.prerequisites.map(&:slug).sort ||
exercise_config[:practices].to_a.sort != exercise.practiced_concepts.map(&:slug).sort
end
def exercise_config_modified?
return false unless filepath_in_diff?(head_git_exercise.config_absolute_filepath)
head_git_exercise.blurb != exercise.blurb ||
head_git_exercise.icon_name != exercise.icon_name ||
head_git_exercise.authors.to_a.sort != exercise.authors.map(&:github_username).sort ||
head_git_exercise.contributors.to_a.sort != exercise.contributors.map(&:github_username).sort ||
head_git_exercise.has_test_runner? != exercise.has_test_runner? ||
head_git_exercise.representer_version != exercise.representer_version?
end
def exercise_files_modified?
filepaths = head_git_exercise.tooling_absolute_filepaths +
head_git_exercise.important_absolute_filepaths +
head_git_exercise.approaches.absolute_filepaths +
head_git_exercise.articles.absolute_filepaths
filepaths.any? { |filepath| filepath_in_diff?(filepath) }
end
def find_concepts(slugs)
slugs.to_a.map do |slug|
concept_config = head_git_track.concepts.find { |e| e[:slug] == slug }
::Concept.find_by!(uuid: concept_config[:uuid])
rescue StandardError
# TODO: (Optional) Remove this rescue when configlet works
end.compact
end
memoize
def exercise_position
# The hello-world exercise is always the first exercise
return 0 if exercise_config[:slug] == 'hello-world'
# Offset by 1 to account for the hello-world exercise always
# being the very first exercise and offset by the number of concept
# exercises to position practice exercises after concept exercises
exercise_index + 1 + head_git_track.concept_exercises.length
end
memoize
def exercise_index
head_git_track.practice_exercises.find_index { |e| e[:uuid] == exercise.uuid }
end
memoize
def exercise_config
head_git_track.practice_exercises[exercise_index]
end
memoize
def exercise_config_prerequisites
head_git_track.taught_concept_slugs & exercise_config[:prerequisites].to_a
end
memoize
def head_git_exercise
Git::Exercise.new(exercise_config[:slug], exercise.git_type, git_repo.head_sha, repo: git_repo)
end
end