packages/solidity-devops/src/writer/DataWriter.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.12;
pragma experimental ABIEncoderV2;
import {Logger} from "../base/Logger.sol";
import {PathFinder} from "../base/PathFinder.sol";
import {StringUtils} from "../libs/StringUtils.sol";
import {stdJson} from "forge-std/StdJson.sol";
abstract contract DataWriter is PathFinder, Logger {
using stdJson for string;
using StringUtils for *;
/// @notice Writes a JSON data to a file, and prints a log message.
function writeJson(string memory descriptionLog, string memory path, string memory data) internal {
printLogWithIndent(descriptionLog);
createDirIfRequired(path);
data.write(path);
}
/// @notice Writes the deployment JSON for a contract on a given chain under the specified alias.
/// Example: contractName = "LinkedPool", contractAlias = "LinkedPool.USDC"
/// Note: writes the JSON file to the FRESH deployments directory. The written file needs to be moved
/// to the correct location outside of the deployment script.
/// Note: will not include the ABI in the output JSON.
function writeDeploymentArtifact(
string memory chain,
string memory contractAlias,
string memory artifact
)
internal
returns (string memory path)
{
// Use contract alias to determine the deployment path
path = getFreshDeploymentFN(chain, contractAlias);
// First write the deployment JSON without the ABI
writeJson(StringUtils.concat("Saving deployment for ", contractAlias, " on ", chain), path, artifact);
}
/// @notice Writes the deploy config for a contract on a given chain.
function writeDeployConfig(string memory chain, string memory contractName, string memory configData) internal {
writeJson(
StringUtils.concat("Saving deploy config for ", contractName, " on ", chain),
getDeployConfigFN(chain, contractName),
configData
);
}
/// @notice Writes the global deploy config that is shared across all chains for a contract.
function writeGlobalDeployConfig(
string memory contractName,
string memory environment,
string memory configData
)
internal
{
string memory environmentLabel = environment.equals(ENVIRONMENT_PROD) ? "production" : environment;
writeJson(
StringUtils.concat("Saving global config for ", contractName, " [", environmentLabel, "]"),
getGlobalDeployConfigFN(contractName, environment),
configData
);
}
/// @notice Writes the global deploy production config that is shared across all chains for a contract.
function writeGlobalDeployProdConfig(string memory contractName, string memory configData) internal {
writeGlobalDeployConfig(contractName, ENVIRONMENT_PROD, configData);
}
// ═══════════════════════════════════════════════════ UTILS ═══════════════════════════════════════════════════
/// @notice Creates a directory where the file will be saved if it doesn't exist yet.
function createDirIfRequired(string memory filePath) internal {
// Path to the directory is everything that comes before the last slash
uint256 lastSlash = filePath.lastIndexOf("/");
if (lastSlash == StringUtils.NOT_FOUND) {
return;
}
string memory dirPath = filePath.prefix(lastSlash);
if (!vm.exists(dirPath)) {
printLog(StringUtils.concat("Creating directory: ", dirPath));
vm.createDir({path: dirPath, recursive: true});
}
}
}