Skip to content
Merged
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
1 change: 1 addition & 0 deletions stasis/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"src/loaders/foundry.js",
"src/loaders/rust.js",
"src/loaders/solidity.js",
"src/loaders/toml.js",
"src/loaders/php.js",
"src/lockfile.js",
"src/metro.js",
Expand Down
2 changes: 1 addition & 1 deletion stasis/src/cmd/bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ function solidityManifests(baseDir, sources, configFiles, classifyDep) {
}
if (!isUtf8(buf)) throw new Error(`Solidity manifest is not valid UTF-8: ${rel}`)
const text = buf.toString('utf8')
out.set(rel, rel.endsWith('.toml') ? redactFoundryToml(text) : scrubUrlCredentials(text))
out.set(rel, rel.endsWith('.toml') ? redactFoundryToml(text, rel) : scrubUrlCredentials(text))
}
return out
}
Expand Down
290 changes: 57 additions & 233 deletions stasis/src/loaders/cargo.js

Large diffs are not rendered by default.

21 changes: 12 additions & 9 deletions stasis/src/loaders/foundry.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import { posix, resolve } from 'node:path'

import { toPosix } from '@exodus/stasis-core/util'
import { isDir } from '../resolve-typescript.js'
import { readFileOrNull, tomlEntries } from './cargo.js'
import { readFileOrNull } from './cargo.js'
import { tomlEntries } from './toml.js'

export const FOUNDRY_TOML = 'foundry.toml'
export const REMAPPINGS_TXT = 'remappings.txt'
Expand Down Expand Up @@ -408,13 +409,14 @@ const STANDALONE_SECTIONS = new Set([
// names lowercased, keys snake_cased as forge does) from the `[profile.<name>]` tables and the
// legacy top-level `[<name>]` ones forge still reads, the former winning key by key; sub-tables
// other than `extends` are skipped. `topLevel` holds keys set outside any table (forge rejects
// those; a `--mapping` file may list its `remappings` there).
function parseFoundryToml(text) {
// those; a `--mapping` file may list its `remappings` there). Throws a TomlError naming `file` on
// text that isn't TOML, as forge refuses the file.
function parseFoundryToml(text, file = null) {
const current = new Map()
const legacy = new Map()
const topLevel = new Map()
const dictOf = (map, name) => map.get(name) ?? map.set(name, new Map()).get(name)
for (const { path, header, value } of tomlEntries(text)) {
for (const { path, header, value } of tomlEntries(text, { file })) {
let map
let rest
if (path[0] === 'profile' && path.length >= 2) {
Expand Down Expand Up @@ -464,7 +466,7 @@ function mergeExtended(base, local, strategy) {
function readFoundryProfiles(file, profile, { confineTo } = {}) {
const text = readFileOrNull(file)
if (text === null) return { profiles: new Map(), topLevel: new Map(), files: [] }
let { profiles, topLevel } = parseFoundryToml(text)
let { profiles, topLevel } = parseFoundryToml(text, file)
const files = [file]
const ext = profiles.get(profile)?.get('extends')
const extPath = typeof ext === 'string' ? ext : ext?.path
Expand All @@ -476,7 +478,7 @@ function readFoundryProfiles(file, profile, { confineTo } = {}) {
}
const baseText = readFileOrNull(baseFile)
if (baseText === null) throw new Error(`${file}: the inherited config file does not exist: ${extPath}`)
const base = parseFoundryToml(baseText).profiles
const base = parseFoundryToml(baseText, baseFile).profiles
if (base.get(profile)?.has('extends')) {
throw new Error(`${file}: nested inheritance is not allowed (${extPath} has an 'extends' field in profile '${profile}')`)
}
Expand Down Expand Up @@ -828,10 +830,11 @@ export const scrubUrlCredentials = (text) => text.replaceAll(/\b([a-z][a-z0-9+.-

// A foundry.toml without its credentials: a SECRET_TABLES table goes whole (every line up to the
// next header), a pair under one or keyed like a secret goes line for line, and URLs lose their
// user info. Everything else is kept verbatim.
export function redactFoundryToml(text) {
// user info. Everything else is kept verbatim. Throws a TomlError naming `file` on text that
// isn't TOML: what can't be read can't be redacted.
export function redactFoundryToml(text, file = null) {
const lines = text.split('\n')
const entries = [...tomlEntries(text)]
const entries = tomlEntries(text, { file })
const drop = new Set()
const isSecretTable = (segs) => segs.some((seg) => SECRET_TABLES.has(seg))
entries.forEach((e, idx) => {
Expand Down
3 changes: 2 additions & 1 deletion stasis/src/loaders/rust.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import { readFile } from 'node:fs/promises'
import { dirname, extname, isAbsolute, join, posix, relative, resolve } from 'node:path'

import { assertRealPathWithinBase } from '@exodus/stasis-core/util'
import { VENDOR_DIR, createCargoContext, isFile, isTestTargetPath, matchClose, normName, normalizeRel, splitTopLevel } from './cargo.js'
import { VENDOR_DIR, createCargoContext, isFile, isTestTargetPath, normName, normalizeRel } from './cargo.js'
import { matchClose, splitTopLevel } from './toml.js'

// Leads of the expression-position paths anchored on the module tree rather than on a name.
const PATH_KEYWORDS = new Set(['crate', 'self', 'super'])
Expand Down
Loading
Loading