in intellij-plugin/educational-core/src/com/jetbrains/edu/learning/yaml/YamlDeepLoader.kt [37:102]
fun loadCourse(project: Project): Course? {
val projectDir = project.courseDir
@NonNls
val errorMessageToLog = "Course yaml config cannot be null"
val courseConfig = projectDir.findChild(YamlConfigSettings.COURSE_CONFIG) ?: error(errorMessageToLog)
// the initial mapper has no idea whether the course is in the CC or in the Student mode
val initialMapper = YamlMapper.basicMapper()
initialMapper.setupForMigration(project)
val deserializedCourse = deserializeItemProcessingErrors(courseConfig, project, mapper=initialMapper) as? Course ?: return null
val needMigration = YamlMigrator(initialMapper).needMigration()
// this mapper already respects course mode, it will be used to deserialize all other course items
val mapper = deserializedCourse.mapper()
mapper.setupForMigration(project)
mapper.setEduValue(YAML_VERSION_MAPPER_KEY, initialMapper.getEduValue(YAML_VERSION_MAPPER_KEY))
deserializedCourse.items = deserializedCourse.deserializeContent(project, deserializedCourse.items, mapper)
deserializedCourse.items.forEach { deserializedItem ->
when (deserializedItem) {
is Section -> {
// set parent to correctly obtain dirs in deserializeContent method
deserializedItem.parent = deserializedCourse
deserializedItem.items = deserializedItem.deserializeContent(project, deserializedItem.items, mapper)
deserializedItem.lessons.forEach {
it.parent = deserializedItem
it.items = it.deserializeContent(project, it.taskList, mapper)
}
}
is Lesson -> {
// set parent to correctly obtain dirs in deserializeContent method
deserializedItem.parent = deserializedCourse
deserializedItem.items = deserializedItem.deserializeContent(project, deserializedItem.taskList, mapper)
addNonEditableFilesToCourse(deserializedItem, deserializedCourse, project)
deserializedItem.removeNonExistingTaskFiles(project)
}
}
}
if (needMigration) {
project.invokeLater {
// After migration, we save all YAMLs back to disk.
// In theory, com.jetbrains.edu.learning.yaml.YamlLoader.loadItem() could be fired before the migrated YAMLs are saved,
// and that could lead to incorrectly read YAML.
// One of the dangerous places: the FileEditorManagerListener calls loadItem() to refresh editor notifications for
// YAML files, and this happens right after the project is loaded.
YamlFormatSynchronizer.saveAll(project)
}
}
// we initialize course before setting description and remote info, as we have to set parent item
// to obtain description/remote config file to set info from
deserializedCourse.init(true)
deserializedCourse.loadRemoteInfoRecursively(project)
if (deserializedCourse is HyperskillCourse) {
project.isHyperskillProject = true
return null
}
if (!deserializedCourse.isStudy) {
deserializedCourse.setDescriptionInfo(project)
}
return deserializedCourse
}