-
Notifications
You must be signed in to change notification settings - Fork 139
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
341 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package brownie | ||
|
||
import ( | ||
"github.com/tenderly/tenderly-cli/providers" | ||
) | ||
|
||
type DeploymentProvider struct { | ||
} | ||
|
||
func NewDeploymentProvider() *DeploymentProvider { | ||
return &DeploymentProvider{} | ||
} | ||
|
||
var _ providers.DeploymentProvider = (*DeploymentProvider)(nil) | ||
|
||
func (*DeploymentProvider) GetProviderName() providers.DeploymentProviderName { | ||
return providers.BrownieDeploymentProvider | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package brownie | ||
|
||
import ( | ||
"fmt" | ||
"github.com/pkg/errors" | ||
"github.com/sirupsen/logrus" | ||
"github.com/tenderly/tenderly-cli/config" | ||
"github.com/tenderly/tenderly-cli/providers" | ||
"github.com/tenderly/tenderly-cli/userError" | ||
"gopkg.in/yaml.v3" | ||
"io/ioutil" | ||
"os" | ||
"path/filepath" | ||
"runtime" | ||
"strings" | ||
) | ||
|
||
type BrownieCompilerSettings struct { | ||
Compiler providers.Compiler `json:"compiler,omitempty" yaml:"compiler,omitempty"` | ||
} | ||
|
||
func (dp *DeploymentProvider) GetConfig(configName string, projectDir string) (*providers.Config, error) { | ||
browniePath := filepath.Join(projectDir, configName) | ||
|
||
logrus.Debugf("Trying Brownie config path: %s", browniePath) | ||
_, err := os.Stat(browniePath) | ||
if os.IsNotExist(err) { | ||
return nil, err | ||
} | ||
if err != nil { | ||
return nil, fmt.Errorf("cannot find %s, tried path: %s, error: %s", configName, browniePath, err) | ||
} | ||
|
||
if runtime.GOOS == "windows" { | ||
browniePath = strings.ReplaceAll(browniePath, `\`, `\\`) | ||
} | ||
|
||
data, err := ioutil.ReadFile(browniePath) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "read brownie config") | ||
} | ||
|
||
var brownieConfig providers.Config | ||
err = yaml.Unmarshal(data, &brownieConfig) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "parse brownie config") | ||
} | ||
|
||
return &providers.Config{ | ||
ProjectDirectory: projectDir, | ||
BuildDirectory: configName, | ||
ConfigType: configName, | ||
Compilers: brownieConfig.Compilers, | ||
}, nil | ||
} | ||
|
||
func (dp *DeploymentProvider) MustGetConfig() (*providers.Config, error) { | ||
projectDir, err := filepath.Abs(config.ProjectDirectory) | ||
brownieConfigFile := providers.BrownieConfigFile | ||
|
||
if err != nil { | ||
return nil, userError.NewUserError( | ||
fmt.Errorf("get absolute project dir: %s", err), | ||
"Couldn't get absolute project path", | ||
) | ||
} | ||
|
||
brownieConfig, err := dp.GetConfig(brownieConfigFile, projectDir) | ||
if err != nil { | ||
return nil, userError.NewUserError( | ||
fmt.Errorf("unable to fetch config: %s", err), | ||
"Couldn't read Brownie config file", | ||
) | ||
} | ||
|
||
return brownieConfig, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
package brownie | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"github.com/ethereum/go-ethereum/common/hexutil" | ||
"github.com/pkg/errors" | ||
"github.com/sirupsen/logrus" | ||
"github.com/tenderly/tenderly-cli/model" | ||
"github.com/tenderly/tenderly-cli/providers" | ||
"io/ioutil" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
) | ||
|
||
const ( | ||
BrownieContractDirectoryPath = "contracts" | ||
BrownieContractDeploymentPath = "deployments" | ||
BrownieContractMapFile = "map.json" | ||
|
||
BrownieDependencySeparator = "packages" | ||
) | ||
|
||
func (dp *DeploymentProvider) GetContracts( | ||
buildDir string, | ||
networkIDs []string, | ||
objects ...*model.StateObject, | ||
) ([]providers.Contract, int, error) { | ||
contractsPath := filepath.Join(buildDir, BrownieContractDirectoryPath) | ||
files, err := ioutil.ReadDir(contractsPath) | ||
if err != nil { | ||
return nil, 0, errors.Wrap(err, "failed listing build files") | ||
} | ||
|
||
networkIDFilterMap := make(map[string]bool) | ||
for _, networkID := range networkIDs { | ||
networkIDFilterMap[networkID] = true | ||
} | ||
objectMap := make(map[string]*model.StateObject) | ||
for _, object := range objects { | ||
if object.Code == nil || len(object.Code) == 0 { | ||
continue | ||
} | ||
objectMap[hexutil.Encode(object.Code)] = object | ||
} | ||
|
||
contractMap := make(map[string]*providers.Contract) | ||
var numberOfContractsWithANetwork int | ||
for _, contractFile := range files { | ||
if contractFile.IsDir() { | ||
dependencyPath := filepath.Join(contractsPath, contractFile.Name()) | ||
err = dp.resolveDependencies(dependencyPath, contractMap) | ||
if err != nil { | ||
logrus.Debug(fmt.Sprintf("Failed resolving dependencies at %s with error: %s", dependencyPath, err)) | ||
break | ||
} | ||
continue | ||
} | ||
if !strings.HasSuffix(contractFile.Name(), ".json") { | ||
continue | ||
} | ||
contractFilePath := filepath.Join(contractsPath, contractFile.Name()) | ||
data, err := ioutil.ReadFile(contractFilePath) | ||
if err != nil { | ||
logrus.Debug(fmt.Sprintf("Failed reading build file at %s with error: %s", contractFilePath, err)) | ||
break | ||
} | ||
|
||
var contractData providers.Contract | ||
err = json.Unmarshal(data, &contractData) | ||
if err != nil { | ||
logrus.Debug(fmt.Sprintf("Failed parsing build file at %s with error: %s", contractFilePath, err)) | ||
break | ||
} | ||
|
||
contractMap[contractData.Name] = &contractData | ||
} | ||
|
||
deploymentMapFile := filepath.Join(buildDir, BrownieContractDeploymentPath, BrownieContractMapFile) | ||
|
||
data, err := ioutil.ReadFile(deploymentMapFile) | ||
if err != nil { | ||
logrus.Debug(fmt.Sprintf("Failed reading map file at %s with error: %s", deploymentMapFile, err)) | ||
return nil, 0, errors.Wrap(err, "failed reading map file") | ||
} | ||
|
||
var deploymentMap map[string]map[string][]string | ||
err = json.Unmarshal(data, &deploymentMap) | ||
if err != nil { | ||
logrus.Debug(fmt.Sprintf("Failed parsing map file at %s with error: %s", deploymentMapFile, err)) | ||
return nil, 0, errors.Wrap(err, "failed unmarshaling map file") | ||
} | ||
for networkID, contractDeployments := range deploymentMap { | ||
for contractName, deploymentAddresses := range contractDeployments { | ||
if _, ok := contractMap[contractName]; !ok { | ||
continue | ||
} | ||
|
||
if len(networkIDFilterMap) > 0 && !networkIDFilterMap[networkID] { | ||
continue | ||
} | ||
|
||
if contractMap[contractName].Networks == nil { | ||
contractMap[contractName].Networks = make(map[string]providers.ContractNetwork) | ||
} | ||
//We only take the latest deployment to some network | ||
contractMap[contractName].Networks[networkID] = providers.ContractNetwork{ | ||
Address: deploymentAddresses[0], | ||
} | ||
numberOfContractsWithANetwork += 1 | ||
} | ||
} | ||
|
||
var contracts []providers.Contract | ||
for _, contract := range contractMap { | ||
contracts = append(contracts, *contract) | ||
} | ||
|
||
return contracts, numberOfContractsWithANetwork, nil | ||
} | ||
|
||
func (dp *DeploymentProvider) resolveDependencies(path string, contractMap map[string]*providers.Contract) error { | ||
info, err := os.Stat(path) | ||
if err != nil { | ||
logrus.Debugf("Failed reading dependency at %s", path) | ||
return errors.Wrap(err, "failed reading dependency files") | ||
} | ||
if info.IsDir() { | ||
files, err := ioutil.ReadDir(path) | ||
if err != nil { | ||
logrus.Debugf("Failed reading dependency at %s", path) | ||
return errors.Wrap(err, "failed reading dependency files") | ||
} | ||
|
||
for _, file := range files { | ||
newFilePath := filepath.Join(path, file.Name()) | ||
err = dp.resolveDependencies(newFilePath, contractMap) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
data, err := ioutil.ReadFile(path) | ||
if err != nil { | ||
logrus.Debug(fmt.Sprintf("Failed reading build file at %s with error: %s", path, err)) | ||
return errors.Wrap(err, "failed reading contract") | ||
} | ||
|
||
var contractData providers.Contract | ||
err = json.Unmarshal(data, &contractData) | ||
if err != nil { | ||
logrus.Debug(fmt.Sprintf("Failed parsing build file at %s with error: %s", path, err)) | ||
return errors.Wrap(err, "failed parsing contract") | ||
} | ||
|
||
sourcePath := strings.Split(contractData.SourcePath, BrownieDependencySeparator) | ||
contractData.SourcePath = strings.TrimPrefix(sourcePath[1], string(os.PathSeparator)) | ||
contractMap[contractData.Name] = &contractData | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package brownie | ||
|
||
import ( | ||
"os" | ||
"path" | ||
) | ||
|
||
var brownieFolders = []string{ | ||
"build", | ||
} | ||
|
||
func FindDirectories() []string { | ||
return []string{} | ||
} | ||
|
||
func (dp *DeploymentProvider) CheckIfProviderStructure(directory string) bool { | ||
for _, folder := range brownieFolders { | ||
folderPath := path.Join(directory, folder) | ||
if _, err := os.Stat(folderPath); err != nil { | ||
return false | ||
} | ||
} | ||
|
||
return true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.