Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dependency management #5

Merged
merged 13 commits into from
Nov 4, 2022
Merged

Dependency management #5

merged 13 commits into from
Nov 4, 2022

Conversation

you-win
Copy link
Member

@you-win you-win commented Aug 15, 2022

Godot is able to load resources in 2 different ways:

  1. preload(path) which allows for a relative path
  2. load(path) which requires an absolute path

The idea is to scan each package that's downloaded and, for every preload and load token found, take the path param and replace it with a new path that points to a versioned dependency.

The idea

Given the below manifests:

godot.package

{
    "packages": {
        "my_package": "0.1.0"
    }
}

package.json of my_package

{
    "name": "my_package",
    "version": "0.1.0",
    "... other fields ...": {},
    "dependencies": {
        "other_package": "1.0.0"
    }
}

Note that other_package is listed in the dependencies section


package.json of other_package

{
    "name": "other_package",
    "version": "1.0.0",
    "... other fields ...": {},
    "dependencies": {}
}

The following flow will be followed:

  1. The godot.package file will be parsed from the project's root directory
  2. The tar of my_package will be downloaded and extracted into the addons/ directory
  3. The package.json file located in addons/my_package/package.json will be parsed for dependencies
  4. other_package will be downloaded and extracted into a new addons/__gpm_deps/ directory
  5. The package.json file located in addons/__gpm_deps/other_package/1.0.0/package.json will be parsed for dependencies (notice that the package is versioned)
  6. Every single package will be scanned for load and preload funcs and have their paths modified
    • preload will be modified to use a relative path (preferred)
    • load will be modified to use an absolute path

@bend-n
Copy link
Member

bend-n commented Sep 12, 2022

What if the other_package is already installed as a direct dependency?

@you-win
Copy link
Member Author

you-win commented Sep 12, 2022

If other_package was manually installed, then there will be duplicate libraries in the project.

In the case where:

  1. other_package is defined as a direct dependency in godot.package
  2. Another dependency called A also depends on other_package

other_package should be located in the addons directory and A should be automatically modified to point at addons/other_package

@bend-n
Copy link
Member

bend-n commented Sep 12, 2022

And if they are different versions? Also, i dont see how duplicate librarys are ok. Godot doesnt like multiple classes with the same class names.

@you-win
Copy link
Member Author

you-win commented Sep 12, 2022

And if they are different versions?

Then the indirect dependency will be placed in the addons/__gpm_deps directory

Godot doesnt like multiple classes with the same class names

This is a limitation of Godot. Libraries for Godot shouldn't be defining class names anyways since they pollute Godot's class scope and slow down script parsing. See this issue for an example

Class names should only be used in user code (i.e. not a library/package) or in libraries that are not meant to be used in other libraries (e.g. Dialogic)

@bend-n
Copy link
Member

bend-n commented Sep 13, 2022

So how are you supposed to instantiate custom classesscripts?

@you-win
Copy link
Member Author

you-win commented Sep 13, 2022

via preload and load, which is how scripts used to work pre godot 3.2(?)

This is also something mentioned in the initial proposal:

Every single package will be scanned for load and preload funcs and have their paths modified

@bend-n
Copy link
Member

bend-n commented Oct 14, 2022

What about datastructure librarys and stuff, non nodes. What if I want to make a tree library, right, do people want to do

const Tree = preload("res://addons/treelib/tree.gd")

func _ready() -> void:
  var t = Tree.new("root")

Idk, it just seems like not using a good feature.

@you-win
Copy link
Member Author

you-win commented Oct 14, 2022

Unfortunately, that "good feature" creates namespace issues in Godot. You mentioned that yourself.

I have already laid out my plan for handling this problem in this thread. Do you have an alternate plan?

@bend-n
Copy link
Member

bend-n commented Oct 14, 2022

So if the main project needs a addon, its preload(addons/addon1/addon1.gd), but if a addon wants a addon, the preload paths get modified from what to what? from preload(res://addons/addon1/addon.gd -> preload(res://addons/__gpm_deps/other_package/1.0.0/addon.gd)?

@bend-n bend-n mentioned this pull request Oct 21, 2022
@you-win you-win marked this pull request as ready for review November 4, 2022 01:10
@you-win you-win merged commit 75faa50 into master Nov 4, 2022
@you-win you-win deleted the feature/dependency-management branch November 4, 2022 01:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants