Skip to content

improved output for diff commands #62

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

Open
wants to merge 2 commits into
base: 13
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
35 changes: 13 additions & 22 deletions src/commands/diff-files.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
import { Command, flags } from '@oclif/command'
import chalk from 'chalk'
import { Command } from '@oclif/command'

import { diffLists, listPart } from '../blobs/file-list'
import { DIFF_FLAGS, DiffList, printDiffList } from '../util/diff'
import { ALL_SYS_PARTITIONS } from '../util/partitions'

export default class DiffFiles extends Command {
static description = 'find missing system files compared to a reference system'

static flags = {
help: flags.help({ char: 'h' }),
all: flags.boolean({
char: 'a',
description: 'show all differences, not only missing/removed files',
default: false,
}),
}
static flags = DIFF_FLAGS

static args = [
{ name: 'sourceRef', description: 'path to root of reference system', required: true },
Expand All @@ -23,10 +16,12 @@ export default class DiffFiles extends Command {

async run() {
let {
flags: { all },
flags: { type },
args: { sourceRef, sourceNew },
} = this.parse(DiffFiles)

let diffs = []

for (let partition of ALL_SYS_PARTITIONS) {
let filesRef = await listPart(partition, sourceRef)
if (filesRef == null) {
Expand All @@ -35,17 +30,13 @@ export default class DiffFiles extends Command {

let filesNew = (await listPart(partition, sourceNew)) ?? []

this.log(chalk.bold(partition))

let newAdded = diffLists(filesRef, filesNew)
let newRemoved = diffLists(filesNew, filesRef)

newRemoved.forEach(f => this.log(chalk.red(` ${f}`)))
if (all) {
newAdded.forEach(f => this.log(chalk.green(` ${f}`)))
}

this.log()
diffs.push({
partition,
added: diffLists(filesRef, filesNew),
removed: diffLists(filesNew, filesRef),
} as DiffList)
}

printDiffList(diffs, type, this.log)
}
}
36 changes: 11 additions & 25 deletions src/commands/diff-props.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Command, flags } from '@oclif/command'
import chalk from 'chalk'

import { diffPartitionProps, loadPartitionProps, PartitionProps } from '../blobs/props'
import { DIFF_FLAGS, DiffMap, printDiffMap } from '../util/diff'

const BUILD_KEY_PATTERN = /^ro(?:\.(?:system|system_ext|product|vendor|odm|vendor_dlkm|odm_dlkm))?\.build\..+$/

Expand All @@ -15,25 +15,12 @@ function removeBuildProps(partProps: PartitionProps) {
}
}

function forEachPropLine(props: Map<string, string>, callback: (prop: string) => void) {
for (let [key, value] of props.entries()) {
callback(`${key}=${chalk.bold(value)}`)
}
}

function forEachPropLineModified(props: Map<string, Array<string>>, callback: (prop: string) => void) {
for (let [key, [refValue, newValue]] of props.entries()) {
callback(`${key}=${chalk.bold(refValue)} -> ${chalk.bold(chalk.blue(newValue))}`)
}
}

export default class DiffProps extends Command {
static description = 'find missing and different properties compared to a reference system'

static flags = {
help: flags.help({ char: 'h' }),
all: flags.boolean({ char: 'a', description: 'show all differences, not only missing props', default: false }),
includeBuild: flags.boolean({ char: 'b', description: 'include build props', default: false }),
...DIFF_FLAGS
}

static args = [
Expand All @@ -43,7 +30,7 @@ export default class DiffProps extends Command {

async run() {
let {
flags: { all, includeBuild },
flags: { type, includeBuild },
args: { sourceRef, sourceNew },
} = this.parse(DiffProps)

Expand All @@ -58,16 +45,15 @@ export default class DiffProps extends Command {

let partChanges = diffPartitionProps(propsRef, propsNew)

for (let [partition, changes] of partChanges.entries()) {
this.log(chalk.bold(partition))

forEachPropLine(changes.removed, p => this.log(chalk.red(` ${p}`)))
if (all) {
forEachPropLine(changes.added, p => this.log(chalk.green(` ${p}`)))
forEachPropLineModified(changes.modified, p => this.log(` ${p}`))
}
let diffs = []

this.log()
for (let [partition, changes] of partChanges.entries()) {
diffs.push({
partition,
...changes
} as DiffMap)
}

printDiffMap(diffs, type, this.log)
}
}
32 changes: 13 additions & 19 deletions src/commands/diff-vintf.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
import { Command, flags } from '@oclif/command'
import { Command } from '@oclif/command'
import { promises as fs } from 'fs'
import chalk from 'chalk'

import { diffVintfHals, getHalFqNames, loadPartVintfInfo, serializeVintfHals } from '../blobs/vintf'
import { DIFF_FLAGS, DiffList, printDiffList } from '../util/diff'
import { EXT_PARTITIONS } from '../util/partitions'

export default class DiffVintf extends Command {
static description = 'find missing vintf declarations compared to a reference system'

static flags = {
help: flags.help({ char: 'h' }),
all: flags.boolean({
char: 'a',
description: 'show all differences, not only missing/removed HALs',
default: false,
}),
}
static flags = DIFF_FLAGS

static args = [
{ name: 'sourceRef', description: 'path to root of reference system', required: true },
Expand All @@ -25,13 +18,15 @@ export default class DiffVintf extends Command {

async run() {
let {
flags: { all },
flags: { type },
args: { sourceRef, sourceNew, outPath },
} = this.parse(DiffVintf)

let vintfRef = await loadPartVintfInfo(sourceRef)
let vintfNew = await loadPartVintfInfo(sourceNew)

let diffs = []

for (let partition of EXT_PARTITIONS) {
let halsRef = vintfRef.get(partition)?.manifest
if (halsRef == null) {
Expand All @@ -40,22 +35,21 @@ export default class DiffVintf extends Command {

let halsNew = vintfNew.get(partition)?.manifest ?? []

this.log(chalk.bold(partition))

let newAdded = diffVintfHals(halsRef, halsNew)
let newRemoved = diffVintfHals(halsNew, halsRef)

getHalFqNames(newRemoved).forEach(f => this.log(chalk.red(` ${f}`)))
if (all) {
getHalFqNames(newAdded).forEach(f => this.log(chalk.green(` ${f}`)))
}
diffs.push({
partition,
added: getHalFqNames(newAdded),
removed: getHalFqNames(newRemoved),
} as DiffList)

if (outPath != undefined) {
let outManifest = serializeVintfHals(newRemoved)
await fs.writeFile(outPath, outManifest)
}

this.log()
}

printDiffList(diffs, type, this.log)
}
}
103 changes: 103 additions & 0 deletions src/util/diff.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { flags } from "@oclif/command"
import chalk from "chalk"

const JSON_INDENT = 2

export enum DiffTypes {
ALL = 'all',
ADDED = 'added',
REMOVED = 'removed',
JSON = 'json',
}

export interface DiffList {
partition: string
added: Array<string>
removed: Array<string>
}

export interface DiffMap {
partition: string
added: Map<string, string>
modified: Map<string, Array<string>>
removed: Map<string, string>
}

export const DIFF_FLAGS = {
help: flags.help({ char: 'h' }),
type: flags.enum({
char: 't',
description: 'output type of diff',
options: Object.values(DiffTypes),
default: DiffTypes.ALL,
}),
}

function stringify(object: object) {
return JSON.stringify(
object,
(_key, value) => value instanceof Map ? Object.fromEntries(value) : value,
JSON_INDENT,
)
}

export function printDiffList(
diffs: DiffList[],
type: DiffTypes,
callback: (message?: string) => void,
) {
if (type === DiffTypes.JSON) {
callback(stringify(diffs))
return
}

let showAdded = [DiffTypes.ALL, DiffTypes.ADDED].includes(type)
let showRemoved = [DiffTypes.ALL, DiffTypes.REMOVED].includes(type)

for (let diff of diffs) {
callback(chalk.bold(diff.partition))

if (showAdded) {
diff.added.forEach((value) => callback(chalk.green(`+ ${value}`)))
}
if (showRemoved) {
diff.removed.forEach((value) => callback(chalk.red(`- ${value}`)))
}

callback()
}
}

export function printDiffMap(
diffs: DiffMap[],
type: DiffTypes,
callback: (message?: string) => void,
) {
if (type === DiffTypes.JSON) {
callback(stringify(diffs))
return
}

let showAddedAndModified = [DiffTypes.ALL, DiffTypes.ADDED].includes(type)
let showRemoved = [DiffTypes.ALL, DiffTypes.REMOVED].includes(type)

for (let diff of diffs) {
callback(chalk.bold(diff.partition))

if (showAddedAndModified) {
diff.added.forEach((value, key) => {
callback(chalk.green(`+ ${key}=${chalk.bold(value)}`))
})
diff.modified.forEach(([oldValue, newValue], key) => {
callback(`${key}=${chalk.bold(oldValue)} -> ${chalk.bold(chalk.bold.blue(newValue))}`)
})
}
if (showRemoved) {
diff.removed.forEach((value, key) => {
callback(chalk.red(`- ${key}=${chalk.bold(value)}`))
})
}

callback()
}
}