Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
feat: handle comments porting
Browse files Browse the repository at this point in the history
chore: improve menu pages
docs: make comment more precise
feat: use raw config instead of VO
  • Loading branch information
sdlyy committed Feb 5, 2024
1 parent 15c89f0 commit 7d0214c
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 63 deletions.
34 changes: 34 additions & 0 deletions packages/discovery/src/discovery/config/ConfigReader.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { assert } from '@l2beat/backend-tools'
import { DiscoveryOutput } from '@l2beat/discovery-types'
import { parse as parseWithComments } from 'comment-json'
import { readdirSync } from 'fs'
import { readFile } from 'fs/promises'
import { parse, ParseError } from 'jsonc-parser'
Expand Down Expand Up @@ -119,4 +120,37 @@ export class ConfigReader {

return projects
}

async readRawConfigWithComments(
name: string,
chain: string,
): Promise<RawDiscoveryConfig> {
assert(
fileExistsCaseSensitive(`discovery/${name}`),
'Project not found, check if case matches',
)
assert(
fileExistsCaseSensitive(`discovery/${name}/${chain}`),
'Chain not found in project, check if case matches',
)

const contents = await readFile(
`discovery/${name}/${chain}/config.jsonc`,
'utf-8',
)
const parsed: unknown = parseWithComments(contents)

// Parsing via Zod would effectively remove symbols and thus comments
assertDiscoveryConfig(parsed)

assert(parsed.chain === chain, 'Chain mismatch in config.jsonc')

return parsed
}
}

function assertDiscoveryConfig(
config: unknown,
): asserts config is RawDiscoveryConfig {
RawDiscoveryConfig.parse(config)
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import { ContractParameters } from '@l2beat/discovery-types'
import { assign } from 'comment-json'

import { EthereumAddress } from '../../utils/EthereumAddress'
import { ContractOverrides, DiscoveryOverrides } from './DiscoveryOverrides'

export type MutableOverride = Pick<
ContractOverrides,
'ignoreDiscovery' | 'ignoreInWatchMode' | 'ignoreMethods'
'ignoreDiscovery' | 'ignoreInWatchMode' | 'ignoreMethods' | 'ignoreRelatives'
>

/**
* In-place overrides map with intention to be mutable
* since it is easier to do that this way instead of modification squash
* @notice Re-assignments made via comments-json `assign` which supports both entries with comments (JSONC) and with out them.
*/
export class MutableDiscoveryOverrides extends DiscoveryOverrides {
public set(contract: ContractParameters, override: MutableOverride): void {
const nameOrAddress = this.updateNameToAddress(contract)
Expand All @@ -22,31 +28,51 @@ export class MutableDiscoveryOverrides extends DiscoveryOverrides {
if (override.ignoreInWatchMode.length === 0) {
delete originalOverride.ignoreInWatchMode
} else {
originalOverride.ignoreInWatchMode = override.ignoreInWatchMode
assign(originalOverride, {
ignoreInWatchMode: override.ignoreInWatchMode,
})
}
}

if (override.ignoreMethods !== undefined) {
if (override.ignoreMethods.length === 0) {
delete originalOverride.ignoreMethods
} else {
originalOverride.ignoreMethods = override.ignoreMethods
assign(originalOverride, { ignoreMethods: override.ignoreMethods })
}
}

if (override.ignoreRelatives !== undefined) {
if (override.ignoreRelatives.length === 0) {
delete originalOverride.ignoreRelatives
} else {
assign(originalOverride, { ignoreRelatives: override.ignoreRelatives })
}
}

if (override.ignoreDiscovery !== undefined) {
if (!override.ignoreDiscovery) {
delete originalOverride.ignoreDiscovery
} else {
originalOverride.ignoreDiscovery = override.ignoreDiscovery
assign(originalOverride, { ignoreRelatives: override.ignoreRelatives })
}
}

// Pre-set overrides if they are not set
if (this.config.overrides === undefined) {
this.config.overrides = {}
}

this.config.overrides[identifier ?? nameOrAddress] = originalOverride
// Set override only if it is not empty
if (Object.keys(originalOverride).length > 0) {
assign(this.config.overrides, {
[identifier ?? nameOrAddress]: originalOverride,
})
// Remove override if it is empty
} else {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete this.config.overrides[identifier ?? nameOrAddress]
}
}

private getIdentifier(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,29 @@ export class InteractiveOverrides {

async run(): Promise<void> {
console.log(chalk.blue.bold('### Interactive mode ###'))

for (;;) {
const message = 'Options: '
const choices = [
{
name: 'Configure contract overrides',
name: '⚙️ Configure contract overrides',
value: 'configure',
},
{ name: 'Flush overrides', value: 'flush' },
{ name: '💾 Flush overrides & exit', value: 'flush' },
{ name: '🚪 Exit', value: 'exit' },
] as const

const choice = await select({
message,
choices,
})

if (choice === 'configure') {
await this.configureContract()
}

if (choice === 'flush') {
await this.iom.flushOverrides()
break
return
}
if (choice === 'exit') {
return
}
}
}
Expand Down Expand Up @@ -70,14 +70,16 @@ export class InteractiveOverrides {
name: `🔍 Watch Mode (${chalk.gray('ignoreInWatchMode')})`,
value: 'watchmode',
},
{
name: `📝 Ignore relatives (${chalk.gray('ignoreRelatives')})`,
value: 'relatives',
},
{
name: `⏭️ Ignore methods (${chalk.gray('ignoreMethods')})`,
value: 'methods',
},
{
name: `🛑 Ignore Discovery completely (${chalk.gray(
'ignoreDiscovery',
)})`,
name: `🛑 Ignore discovery (${chalk.gray('ignoreDiscovery')})`,
value: 'ignore',
},
] as const
Expand All @@ -88,6 +90,10 @@ export class InteractiveOverrides {
await this.configureWatchMode(contract)
}

if (choice === 'relatives') {
await this.configureIgnoredRelatives(contract)
}

if (choice === 'methods') {
await this.configureIgnoredMethods(contract)
}
Expand Down Expand Up @@ -116,7 +122,7 @@ export class InteractiveOverrides {
}))

if (choices.length === 0) {
noValuesWarning(true)
noValuesWarning({ withMethods: true })
return
}

Expand All @@ -130,16 +136,41 @@ export class InteractiveOverrides {
this.iom.setOverride(contract, { ignoreInWatchMode })
}

async configureIgnoredRelatives(contract: ContractParameters): Promise<void> {
const { possible, ignored } = this.iom.getIgnoredRelatives(contract)

const message = 'Ignored relatives (values in ignoreMethods are excluded):'

const choices = possible.map((property) => ({
name: property,
value: property,
checked: ignored.includes(property),
}))

if (choices.length === 0) {
noValuesWarning({ withMethods: true })
return
}

const ignoredRelatives = await checkbox({
loop: false,
pageSize: InteractiveOverrides.MAX_PAGE_SIZE,
message,
choices,
})

this.iom.setOverride(contract, { ignoreRelatives: ignoredRelatives })
}

async configureIgnoredMethods(contract: ContractParameters): Promise<void> {
const ignoredMethods = this.iom.getIgnoredMethods(contract)
const { possible, ignored } = this.iom.getIgnoredMethods(contract)

const message = 'Ignored methods: '

const choices = ignoredMethods.all.map((property) => ({
const choices = possible.map((property) => ({
name: property,
value: property,
// Sync already present configuration
checked: ignoredMethods.ignored.includes(property),
checked: ignored.includes(property),
}))

if (choices.length === 0) {
Expand Down Expand Up @@ -174,6 +205,7 @@ export class InteractiveOverrides {
choices,
})

// Checkbox with only one value, yet array is returned
const ignoreDiscovery = Boolean(choice.length > 0)

this.iom.setOverride(contract, { ignoreDiscovery })
Expand Down Expand Up @@ -203,7 +235,7 @@ async function selectWithBack<T>(
const choicesWithBack = [
...choices,
{
name: 'Back',
name: '🏃 Back',
value: 'back',
} as const,
]
Expand All @@ -218,13 +250,13 @@ async function selectWithBack<T>(
return answer
}

function noValuesWarning(full?: boolean): void {
function noValuesWarning(opts?: { withMethods: boolean }): void {
let msg = `
⚠️ OOPS - no values to manage - check following cases:
- Discovery is set to ignore this contract
- Contract has no values discovered`

if (full) {
if (opts?.withMethods) {
msg += '\n - All values are ignored via ignoreMethods'
}

Expand Down
Loading

0 comments on commit 7d0214c

Please sign in to comment.