Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bootcamp syncer #7274

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions app/commands/git/sync_bootcamp_content.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
class Git::SyncBootcampContent
include Mandate

queue_as :default

def call
repo.update!

repo.levels.each do |data|
level = Bootcamp::Level.find_or_create_by!(idx: data.idx) do |l|
l.title = data.title
l.description = data.description
l.content_markdown = data.content
end
level.update(
title: data.title,
description: data.description,
content_markdown: data.content
)
rescue StandardError => e
raise if Rails.env.development?

Bugsnag.notify(e)
end

repo.concepts.each do |data|
concept = Bootcamp::Concept.find_or_create_by!(uuid: data.uuid) do |c|
c.slug = data.slug
c.title = data.title
c.description = data.description
c.level_idx = data.level
c.apex = data.apex
end
concept.update(
slug: data.slug,
title: data.title,
description: data.description,
level_idx: data.level,
apex: data.apex
)
rescue StandardError => e
raise if Rails.env.development?

Bugsnag.notify(e)
end
end

private
delegate :head_commit, to: :repo

memoize
def repo = Git::BootcampContent.new
end
40 changes: 40 additions & 0 deletions app/models/git/bootcamp_content.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
class Git::BootcampContent
extend Mandate::Memoize

DEFAULT_REPO_URL = "[email protected]:exercism/bootcamp-content.git".freeze

attr_reader :repo

def self.update! = new.update!

def initialize(repo_url: DEFAULT_REPO_URL, repo: nil)
@repo = repo || Git::Repository.new(repo_url:)
end

def update! = repo.fetch!

memoize
def levels
Git::BootcampContent::Levels.new(repo:)
end

memoize
def projects
project_dir_entries.map do |entry|
Git::BootcampContent::Project.new(entry[:name], repo:)
end
end

memoize
def concepts
Git::BootcampContent::Concepts.new(repo:)
end

private
delegate :head_commit, to: :repo

memoize
def project_dir_entries
repo.fetch_tree(repo.head_commit, "projects").select { |entry| entry[:type] == :tree }
end
end
41 changes: 41 additions & 0 deletions app/models/git/bootcamp_content/concept.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
class Git::BootcampContent::Concept
extend Mandate::Memoize
extend Mandate::InitializerInjector
extend Git::HasGitFilepath

delegate :head_sha, :lookup_commit, :head_commit, to: :repo

attr_reader :config

def initialize(config, repo_url: Git::BootcampContent::DEFAULT_REPO_URL, repo: nil)
@repo = repo || Git::Repository.new(repo_url:)
@config = config
end

memoize
def uuid = config[:uuid]
def slug = config[:slug]
def title = config[:title]
def description = config[:description]
def level = config[:level]
def apex = !!config[:apex]
def content = read_file_blob("#{slug}.md")

private
attr_reader :repo

def absolute_filepath(filepath) = "#{dir}/#{filepath}"

memoize
def commit = repo.lookup_commit(repo.head_sha)

memoize
def absolute_filepaths = filepaths.map { |filepath| absolute_filepath(filepath) }
def filepaths = file_entries.map { |defn| defn[:full] }
def dir = "concepts"

def read_file_blob(filepath)
mapped = file_entries.map { |f| [f[:full], f[:oid]] }.to_h
mapped[filepath] ? repo.read_blob(mapped[filepath]) : nil
end
end
45 changes: 45 additions & 0 deletions app/models/git/bootcamp_content/concepts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
class Git::BootcampContent::Concepts
extend Mandate::Memoize
extend Mandate::InitializerInjector
extend Git::HasGitFilepath

delegate :head_sha, :lookup_commit, :head_commit, to: :repo

git_filepath :config, file: "config.json"

def initialize(repo_url: Git::BootcampContent::DEFAULT_REPO_URL, repo: nil)
@repo = repo || Git::Repository.new(repo_url:)
end

memoize
def concepts
concept_documents.map do |entry|
concept_config = config.find { |config| config[:slug] == File.basename(entry[:name], ".*") }
Git::BootcampContent::Concept.new(
concept_config,
repo:
)
end
end

def each(&block) = concepts.each(&block)

private
delegate :head_commit, to: :repo
attr_reader :repo

memoize
def concept_documents
repo.fetch_tree(repo.head_commit, dir).select { |entry| entry[:type] == :blob && File.extname(entry[:name]) == ".md" }
end

def absolute_filepath(filepath) = "#{dir}/#{filepath}"

memoize
def commit = repo.lookup_commit(repo.head_sha)

memoize
def absolute_filepaths = filepaths.map { |filepath| absolute_filepath(filepath) }
def filepaths = file_entries.map { |defn| defn[:full] }
def dir = "concepts"
end
34 changes: 34 additions & 0 deletions app/models/git/bootcamp_content/level.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
class Git::BootcampContent::Level
extend Mandate::Memoize
extend Mandate::InitializerInjector
extend Git::HasGitFilepath

delegate :head_sha, :lookup_commit, :head_commit, to: :repo

git_filepath :content, file: "content.md"

attr_reader :idx, :config

def initialize(idx, config, repo_url: Git::BootcampContent::DEFAULT_REPO_URL, repo: nil)
@repo = repo || Git::Repository.new(repo_url:)
@idx = idx
@config = config
end

memoize
def title = config[:title]
def description = config[:description]

private
attr_reader :repo

def absolute_filepath(filepath) = "#{dir}/#{filepath}"

memoize
def commit = repo.lookup_commit(repo.head_sha)

memoize
def absolute_filepaths = filepaths.map { |filepath| absolute_filepath(filepath) }
def filepaths = file_entries.map { |defn| defn[:full] }
def dir = "levels/#{idx}"
end
46 changes: 46 additions & 0 deletions app/models/git/bootcamp_content/levels.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
class Git::BootcampContent::Levels
extend Mandate::Memoize
extend Mandate::InitializerInjector
extend Git::HasGitFilepath

delegate :head_sha, :lookup_commit, :head_commit, to: :repo

git_filepath :config, file: "config.json"

def initialize(repo_url: Git::BootcampContent::DEFAULT_REPO_URL, repo: nil)
@repo = repo || Git::Repository.new(repo_url:)
end

memoize
def levels
level_dir_entries.map do |entry|
level_config = config.find { |config| config[:idx] == entry[:name].to_i }
Git::BootcampContent::Level.new(
entry[:name],
level_config,
repo:
)
end
end

def each(&block) = levels.each(&block)

private
delegate :head_commit, to: :repo
attr_reader :repo

memoize
def level_dir_entries
repo.fetch_tree(repo.head_commit, "levels").select { |entry| entry[:type] == :tree }
end

def absolute_filepath(filepath) = "#{dir}/#{filepath}"

memoize
def commit = repo.lookup_commit(repo.head_sha)

memoize
def absolute_filepaths = filepaths.map { |filepath| absolute_filepath(filepath) }
def filepaths = file_entries.map { |defn| defn[:full] }
def dir = "levels"
end
2 changes: 1 addition & 1 deletion app/models/git/problem_specifications/exercise.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def file_entries
tree.walk(:preorder).map do |root, entry|
next if entry[:type] == :tree

entry[:full] = "#{root}#{entry[:name]}"
entry[:full] = "#{root}#yentry[:name]}"
entry
end.compact
rescue Rugged::TreeError
Expand Down
34 changes: 0 additions & 34 deletions bootcamp_content/levels/1.md

This file was deleted.

7 changes: 0 additions & 7 deletions bootcamp_content/levels/2.md

This file was deleted.

Empty file removed bootcamp_content/levels/3.md
Empty file.
Empty file removed bootcamp_content/levels/4.md
Empty file.
18 changes: 0 additions & 18 deletions bootcamp_content/levels/config.json

This file was deleted.

14 changes: 14 additions & 0 deletions db/migrate/20250109171959_add_uuids_to_bootcamp.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class AddUuidsToBootcamp < ActiveRecord::Migration[7.0]
def change
return if Rails.env.production?

add_column :bootcamp_concepts, :uuid, :string, null: true
add_column :bootcamp_projects, :uuid, :string, null: true
add_column :bootcamp_exercises, :uuid, :string, null: true

# change_column_null :bootcamp_concepts, :uuid, false
# change_column_null :bootcamp_projects, :uuid, false
# change_column_null :bootcamp_exercises, :uuid, false

end
end
Loading
Loading