diff --git a/README.md b/README.md index f8fbabd..b45a6ed 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ GitHub Action Usage Example: https://github.com/ksimuk/codio-test-publish/blob/m Truncate pages from project. This method creates in the `dstDir` reduced version of the project, which contains only pages specified in `sections: string[]` and files specified in `paths: string[]` ``` - await codio.v1.tools.reduce(srcDir, dstDir, sections, paths) + await codio.v1.tools.reduce(srcDir, dstDir, sections, paths, sectionsConfig) ``` ## Reduce Publish @@ -74,6 +74,7 @@ Similar to reduce but publishes generated projects as assignments. `assignmentName` - or name of the assignment to publish `section` - section name or array of paths to the section `paths` - an array of files that needs to be exported, `.guides` is exported fully to all assignments +`withChildren` - boolean - preserve children structure, `true` by default ``` - assignment: @@ -86,6 +87,10 @@ Similar to reduce but publishes generated projects as assignments. - assignmentName: section: Section 1 +- assignmentName: + section: Section 2 + withChildren: false + ``` GitHub Action: https://github.com/codio/codio-assignment-publish-action diff --git a/package.json b/package.json index 02b7f68..d135f77 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codio-api-js", - "version": "0.17.1", + "version": "0.18.0", "description": "JS client to Codio API", "repository": "https://github.com/codio/codio-api-js", "author": "Max Kraev ", diff --git a/src/lib/assignment.ts b/src/lib/assignment.ts index 43340e0..cfe263c 100644 --- a/src/lib/assignment.ts +++ b/src/lib/assignment.ts @@ -20,6 +20,15 @@ type YamlRaw = { assignmentName: string | undefined paths: (string | PathMap)[] | undefined section: string | string[] + withChildren: boolean | undefined +} + +export type SectionConfig = { + withChildren: boolean +} + +export function sectionToKey(section: string[]) { + return section.join('\n') } type Yaml = { @@ -27,6 +36,7 @@ type Yaml = { assignmentName: string | undefined paths: (string | PathMap)[] section: string[][] + sectionConfig: Map } export type TimeExtension = { @@ -192,6 +202,7 @@ function validityState(ymls: YamlRaw[]): Yaml[] { if (assignmentId === undefined) { throw new Error('assignment and assignmentName does not exist') } + const withChildren = yml.withChildren !== false if (map.has(assignmentId)) { const item = map.get(assignmentId) if (!item) { @@ -199,12 +210,16 @@ function validityState(ymls: YamlRaw[]): Yaml[] { } item.section.push(section) item.paths = item.paths.concat(yml.paths || []) + item.sectionConfig.set(sectionToKey(section), {withChildren: withChildren}) } else { + const sectionConfig: Map = new Map() + sectionConfig.set(sectionToKey(section), {withChildren: withChildren}) map.set(assignmentId, { assignment: yml.assignment, assignmentName: yml.assignmentName, paths: yml.paths || [], - section: [section] + section: [section], + sectionConfig: sectionConfig }) } } @@ -228,12 +243,14 @@ function validateYmlCfg(ymls: Yaml[]): Yaml[] { } item.section = item.section.concat(section) item.paths = item.paths.concat(yml.paths || []) + item.sectionConfig = yml.sectionConfig } else { map.set(assignmentId, { assignment: yml.assignment, assignmentName: yml.assignmentName, paths: yml.paths || [], - section: section + section: section, + sectionConfig: yml.sectionConfig }) } } @@ -296,7 +313,7 @@ async function reducePublish(courseId: string, srcDir: string, yamlDir: string, if (!item.assignment) { throw new Error(`assignment not found with name "${item.assignmentName}"`) } - await tools.reduce(srcDir, tmpDstDir, item.section, _.compact(paths)) + await tools.reduce(srcDir, tmpDstDir, item.section, _.compact(paths), item.sectionConfig) await assignment.publish(courseId, item.assignment, tmpDstDir, changelogOrOptions) fs.rmSync(tmpDstDir, {recursive: true}) } diff --git a/src/lib/tools.ts b/src/lib/tools.ts index a10af07..30ca286 100644 --- a/src/lib/tools.ts +++ b/src/lib/tools.ts @@ -7,7 +7,7 @@ import {excludePaths} from './config' import tar from 'tar' import { ZSTDCompress } from 'simple-zstd' import config from './config' -import { PathMap } from './assignment' +import { PathMap, SectionConfig, sectionToKey } from './assignment' const CONVERTER_VERSION = '4ca4944ddf9d4fe4df9697bec06cbd0a6c170419' const GUIDES_CONTENT_DIR = '.guides/content' @@ -22,13 +22,15 @@ export async function fixGuidesVersion(projectPath: string) { } export async function reduce( - srcDir: string, dstDir: string, yaml_sections: string[][], paths: (string | PathMap)[]): Promise { + srcDir: string, dstDir: string, yaml_sections: string[][], + paths: (string | PathMap)[], sectionsConfig: Map = new Map() +): Promise { await fixGuidesVersion(srcDir) const contentDir = path.join(srcDir, GUIDES_CONTENT_DIR) const rootMetadataPath = path.join(contentDir, INDEX_METADATA_FILE) const rootMetadata = readMetadataFile(rootMetadataPath) const guidesStructure = getGuidesStructure(rootMetadata, srcDir, '') - const filter = collectFilter(guidesStructure, _.cloneDeep(yaml_sections)) + const filter = collectFilter(guidesStructure, _.cloneDeep(yaml_sections), sectionsConfig) const strippedStructure = stripStructure(guidesStructure, filter) const strippedSectionsIds = getStrippedSectionIds(strippedStructure) const excludePaths = getExcludedPaths(guidesStructure, strippedSectionsIds) @@ -83,7 +85,7 @@ const DEFAULT_ALL_SECTION: Section = { children: {} } -function collectFilter(guidesStructure, yaml_sections) { +function collectFilter(guidesStructure, yaml_sections: string[][], sectionsConfig: Map) { const filterMap = { all: false, children: {} @@ -93,7 +95,9 @@ function collectFilter(guidesStructure, yaml_sections) { if (sectionPath.length === 0) { continue } - const section = traverseItems(guidesStructure, sectionPath, filterMap) + const key = sectionToKey(sectionPath) + const withChildren = sectionsConfig.has(key) ? sectionsConfig.get(key)?.withChildren : true + const section = traverseItems(guidesStructure, sectionPath, filterMap, withChildren??true) if (!section) { throw new Error(`${section} not found`) } @@ -105,7 +109,7 @@ function collectFilter(guidesStructure, yaml_sections) { return filterMap } -function traverseItems(structure, sectionPath: string[], filterMap: Section) { +function traverseItems(structure, sectionPath: string[], filterMap: Section, withChildren: boolean) { const sectionName = sectionPath.shift() if (!sectionName) { return @@ -122,9 +126,9 @@ function traverseItems(structure, sectionPath: string[], filterMap: Section) { } if (sectionPath.length > 0) { // fill-in filterMap - traverseItems(section.children, sectionPath, filterMap.children[section.id]) + traverseItems(section.children, sectionPath, filterMap.children[section.id], withChildren) } else { - filterMap.children[section.id].all = true + filterMap.children[section.id].all = withChildren } return section }