Skip to content

Commit

Permalink
Start reworking systems
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky committed Dec 19, 2021
1 parent 5edd629 commit dea81b7
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 60 deletions.
4 changes: 3 additions & 1 deletion src/combination/dimensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ const DIMENSIONS = [
createdByUser: false,
},
{
isDimension: (propName) => propName.startsWith('system'),
isDimension: (propName) => propName.startsWith(SYSTEM_PREFIX),
createdByUser: true,
},
]

export const SYSTEM_PREFIX = 'system.'

// Retrieve several combinations' dimensions.
export const getCombsDimensions = function (combinations) {
return combinations.flatMap(getCombDimensions).filter(isUniqueCombDimension)
Expand Down
14 changes: 14 additions & 0 deletions src/combination/ids/get.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,17 @@ const getDimensionId = function (combination, dimension) {
const { id } = combination.dimensions[dimension.propName]
return { id, dimension }
}

// Rename the `id` of a dimensionId for a given combination's dimension
export const setDimensionId = function (
combination,
{ id, dimension: { propName } },
) {
return {
...combination,
dimensions: {
...combination.dimensions,
[propName]: { ...combination.dimensions[propName], id },
},
}
}
18 changes: 9 additions & 9 deletions src/combination/ids/namespace.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { setArrayElement } from '../../utils/set.js'

import { getCombsDimensionsIds, getCombDimensionsIds } from './get.js'
import {
getCombsDimensionsIds,
getCombDimensionsIds,
setDimensionId,
} from './get.js'
import { isSameDimension, hasCrossDimensionsIds, findSameId } from './has.js'
import { setDimensionId, syncDimensionIds } from './set.js'

// When a result is created, we ensure that two dimensions do not have the
// same ids, by throwing errors.
Expand Down Expand Up @@ -37,7 +40,10 @@ const namespaceRawResultIds = function (
namespaceDimensionsIds.bind(undefined, dimensionsIds),
rawResult.combinations,
)
const rawResultA = updateRawResult(rawResult, combinations)
const rawResultA =
rawResult.combinations === combinations
? rawResult
: { ...rawResult, combinations }
return setArrayElement(rawResults, index, rawResultA)
}

Expand Down Expand Up @@ -103,9 +109,3 @@ const addDimensionId = function (dimensionsIds, combDimensionId) {

return similarDimensionId
}

const updateRawResult = function (rawResult, combinations) {
return rawResult.combinations === combinations
? rawResult
: syncDimensionIds({ ...rawResult, combinations })
}
30 changes: 0 additions & 30 deletions src/combination/ids/set.js

This file was deleted.

19 changes: 11 additions & 8 deletions src/combination/list.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import mapObj from 'map-obj'

import { UserError } from '../error/main.js'
import { selectCombinations } from '../select/main.js'

Expand All @@ -10,18 +12,14 @@ import { listTasks } from './tasks/main.js'
export const listCombinations = async function ({
runners,
inputs,
systemId,
system,
select,
cwd,
}) {
const tasks = await listTasks(runners, cwd)
const inputsList = toInputsList(inputs)

const combinations = getCombinationsProduct({
tasks,
inputsList,
systemId,
})
const combinations = getCombinationsProduct({ tasks, inputsList, system })
validateCombinationsIds(combinations, inputsList)

const combinationsA = selectCombinations(combinations, select)
Expand All @@ -31,15 +29,20 @@ export const listCombinations = async function ({
// Get cartesian product of all combinations.
// `taskPath` is not set in `dimensions.task.path` because it used by the `init`
// stage before task dimension ids are known.
const getCombinationsProduct = function ({ tasks, inputsList, systemId }) {
const getCombinationsProduct = function ({ tasks, inputsList, system }) {
if (tasks.length === 0) {
throw new UserError(`Please specify some "tasks".`)
}

const systemDimensions = mapObj(system, getSystemDimension)
return tasks.map(({ id, taskPath, runner }) => ({
dimensions: { task: { id }, runner, system: { id: systemId } },
dimensions: { task: { id }, runner, ...systemDimensions },
taskPath,
inputsList,
stats: {},
}))
}

const getSystemDimension = function (propName, id) {
return { id }
}
8 changes: 5 additions & 3 deletions src/history/normalize/load.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import sortOn from 'sort-on'

import { namespaceDimensionIds } from '../../combination/ids/namespace.js'
import { selectRawResults } from '../../select/main.js'
import { renameAllSystemIds } from '../../system/rename.js'

import { decompressRawResult } from './compress.js'
import { migrateRawResults } from './migrate.js'
Expand All @@ -11,9 +12,10 @@ export const loadRawResults = function (rawResults, select, newCombinations) {
const rawResultsA = migrateRawResults(rawResults)
const rawResultsB = rawResultsA.map(decompressRawResult)
const rawResultsC = namespaceDimensionIds(rawResultsB, newCombinations)
const rawResultsD = selectRawResults(rawResultsC, select)
const rawResultsE = sortResults(rawResultsD)
return rawResultsE
const rawResultsD = renameAllSystemIds(rawResultsC)
const rawResultsE = selectRawResults(rawResultsD, select)
const rawResultsF = sortResults(rawResultsE)
return rawResultsF
}

const sortResults = function (rawResults) {
Expand Down
15 changes: 13 additions & 2 deletions src/report/normalize/titles_add.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import mapObj from 'map-obj'

import { getCombDimensions } from '../../combination/dimensions.js'

import { padTitles } from './titles_pad.js'
Expand Down Expand Up @@ -34,13 +36,22 @@ const addCombinationTitle = function ({
}
}

// Add `footer.systems[*].title`
// Add `footer.systems[*].dimensions[*].title`
export const addFooterTitles = function (footer, titles, showTitles) {
const titlesA = showTitles ? titles : {}
const systems = footer.systems.map((system) => addTitle(system, titlesA))
const systems = footer.systems.map((system) =>
addSystemTitles(system, titlesA),
)
return { ...footer, systems }
}

const addSystemTitles = function (system, titles) {
const dimensions = mapObj(system.dimensions, (propName, dimension) =>
addTitle(dimension, titles),
)
return { ...system, dimensions }
}

// Allow users to rename identifiers from any combination dimension: tasks,
// runners, systems, variations.
// Shown only in reporters. Computed during reporting, i.e. not persisted in
Expand Down
8 changes: 4 additions & 4 deletions src/system/create/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ import { getSystemVersions } from './versions.js'
// history results
export const createSystemInfo = async function (
combinations,
{ cwd, systemId, envInfo },
{ cwd, system: dimensions, envInfo },
) {
const id = uuidv4()
const timestamp = getTimestamp()
const system = await getSystem({ systemId, envInfo, combinations, cwd })
const system = await getSystem({ dimensions, envInfo, combinations, cwd })
return { id, timestamp, system }
}

const getSystem = async function ({ systemId, combinations, cwd }) {
const getSystem = async function ({ dimensions, combinations, cwd }) {
const versions = await getSystemVersions(combinations, cwd)
const machine = getMachine()
const { git, ci } = getEnvInfo(cwd)
return cleanObject({ id: systemId, machine, git, ci, versions })
return cleanObject({ dimensions, machine, git, ci, versions })
}

const getMachine = function () {
Expand Down
10 changes: 7 additions & 3 deletions src/system/merge.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { isDeepStrictEqual } from 'util'

// When merging results, we report all `systems`. This concatenates them.
// Systems with the same id are merged, with the most recent result having
// priority.
// Systems with all dimensions equal are merged, with the most recent result
// having priority.
// Order matters: we show more recent systems first, i.e. they must be first
// in the array.
// `system` objects should not contain `undefined`, so we can directly merge.
Expand All @@ -16,7 +18,9 @@ export const mergeSystems = function (result, previousResult) {
}

const appendSystem = function ({ systems }, { system: previousSystem }) {
const systemIndex = systems.findIndex(({ id }) => id === previousSystem.id)
const systemIndex = systems.findIndex(({ dimensions }) =>
isDeepStrictEqual(dimensions, previousSystem.dimensions),
)
return systemIndex === -1
? [...systems, previousSystem]
: [
Expand Down
37 changes: 37 additions & 0 deletions src/system/rename.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { SYSTEM_PREFIX } from '../combination/dimensions.js'

// Some logic updates `rawResult.combinations[*].dimensions[*].id`.
// System ids are persisted in two places: `rawResult.system.dimensions` and
// `rawResult.combinations[*].dimensions`.
// We need to update the former.
export const renameAllSystemIds = function (rawResults) {
return rawResults.map(renameSystemIds)
}

const renameSystemIds = function (rawResult) {
const [{ dimensions }] = rawResult.combinations
return Object.entries(dimensions)
.filter(isSystemDimension)
.reduce(renameSystemId, rawResult)
}

const isSystemDimension = function ([propName]) {
return propName.startsWith(SYSTEM_PREFIX)
}

const renameSystemId = function (rawResult, [propName, { id }]) {
const propNameA = unprefixPropName(propName)
return rawResult.system.dimensions[propNameA] === id
? rawResult
: {
...rawResult,
system: {
...rawResult.system,
dimensions: { ...rawResult.system.dimensions, [propNameA]: id },
},
}
}

const unprefixPropName = function (propName) {
return propName.slice(SYSTEM_PREFIX.length)
}

0 comments on commit dea81b7

Please sign in to comment.