ApeWorX / ape

The smart contract development tool for Pythonistas, Data Scientists, and Security Professionals
https://apeworx.io
Apache License 2.0
850 stars 128 forks source link

Load a Project from a Manifest #1113

Closed fubuloubu closed 1 month ago

fubuloubu commented 1 year ago

Overview

I have a package manifest, I would love to be able to load it via Project.from_manifest(manifest: ethpm.PackageManifest) -> Project

Specification

In the ape namespace, there is a class re-import of ProjectManager called Project, so we would add a method from_manifest that would be able to load from a manifest type.


Upon further investigation, it turns out that the internal structure of the project manager isn't set up well to replicate this type of use case. Here is one suggestion for a set of changes to make in order to better support these kinds of use cases:

  1. Use ProjectType sub-types (ApeProject, BrownieProject, etc.) to parse out a manifest from dependencies (assuming they are not going to change)
  2. Change ProjectManager to be a superclass of ApeProject, and add methods for managing an active local project's cached manifest
  3. Replicate structure of a project with dependencies by having each dependency be a ProjectType with a finalized manifest that the local ProjectManager can work with

NOTE: Only ProjectManager superclass can mutate it's encapsulated project. Dependencies would recursively build a final manifest for themselves (e.g. dependencies of dependencies would build a finalized manifest including linking extra manifests) so that the local project was working against a final set of dependency files

NOTE: A ProjectManager may not actually have any local contracts/ files to work with, which is okay. ethPM supports this use case of dependency-only manifests (which we can store in local cache, but never deploy)

Dependencies

n/a

antazoey commented 1 year ago

What are the types of thing you would do with the project you get from Project.from_manifest()?

antazoey commented 1 year ago

We can actually achieve pretty straightforwardly by adding a method to ProjectManager. I am not sure about the proposed changes.

antazoey commented 1 year ago

Plugins, like compiler implementations, are driven by config values. For example, you setup remappings there and even compiler versions.

Somehow, those needs to be captured and used without the need of config_manager in order to have several instances of ProjectAPI classes without switching the active project context.

fubuloubu commented 1 year ago

What are the types of thing you would do with the project you get from Project.from_manifest()?

I am definitely for not making it more complex than it needs to be, probably not the greatest to try to redesign the system if it's not exactly broken (just works differnetly from what I expected)

Most important thing is to be able to load a project from a cached manifest on-disk and get contract types from it without having to recompile anything (this is part of the reason why I had the JSON file compiler built into core)