/
requirements.go
162 lines (139 loc) · 4.11 KB
/
requirements.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package instances
import (
"context"
"fmt"
"github.com/Masterminds/semver/v3"
"github.com/minepkg/minepkg/internals/commands"
"github.com/minepkg/minepkg/pkg/manifest"
)
var (
// ErrNoFabricLoader is returned if the wanted fabric version was not found
ErrNoFabricLoader = &commands.CliError{
Text: "Could not find fabric loader for wanted Minecraft version",
Suggestions: []string{
"Check if fabric is compatible with the Minecraft version in your minepkg.toml",
"Check your requirements.fabric field",
"Try again later",
},
}
// ErrNoFabricMapping is returned if the wanted fabric mapping was not found
ErrNoFabricMapping = &commands.CliError{
Text: "Could not find fabric mapping for wanted Minecraft version",
Suggestions: []string{
"Check if fabric is compatible with the Minecraft version in your minepkg.toml",
"Check your requirements.fabric field",
"Try again later",
},
}
)
// UpdateLockfileRequirements updates the internal lockfile manifest with `VanillaLock`, `FabricLock` or `ForgeLock`
// containing the resolved requirements (semver requirement to actual version)
func (i *Instance) UpdateLockfileRequirements(ctx context.Context) error {
if i.Lockfile == nil {
i.Lockfile = manifest.NewLockfile()
}
switch i.Platform() {
case PlatformFabric:
lock, err := i.resolveFabricRequirement(ctx)
if err != nil {
return err
}
i.Lockfile.Fabric = lock
case PlatformForge:
fmt.Println("forge is not supported for now")
case PlatformVanilla:
version, err := i.resolveVanillaRequirement(ctx)
if err != nil {
return err
}
i.Lockfile.Vanilla = &manifest.VanillaLock{Minecraft: version.ID}
}
return nil
}
func (i *Instance) resolveVanillaRequirement(ctx context.Context) (*MinecraftRelease, error) {
constraint, _ := semver.NewConstraint(i.Manifest.Requirements.Minecraft)
res, err := GetMinecraftReleases(ctx)
if err != nil {
return nil, err
}
// find newest compatible version
for _, v := range res.Versions {
// TODO: some versions contain spaces
semverVersion, err := semver.NewVersion(v.ID)
// skip non-parsable minecraft versions
if err != nil || constraint == nil {
// fallback to string compare
if v.ID == i.Manifest.Requirements.Minecraft {
return &v, nil
}
continue
}
if constraint.Check(semverVersion) {
return &v, nil
}
}
return nil, nil
}
func (i *Instance) resolveFabricRequirement(ctx context.Context) (*manifest.FabricLock, error) {
reqMc := i.Manifest.Requirements.Minecraft
// latest is the same as '*' for this logic (it will return the latest version)
if reqMc == "latest" {
reqMc = "*"
}
reqFabric := i.Manifest.Requirements.FabricLoader
// latest is the same as '*' for this logic (it will return the latest version)
if reqFabric == "latest" {
reqFabric = "*"
}
// TODO: check for invalid semver
MCconstraint, _ := semver.NewConstraint(reqMc)
FabricLoaderConstraint, _ := semver.NewConstraint(reqFabric)
// mcVersions, err := GetMinecraftReleases(ctx)
fabricMappings, err := getFabricMappingVersions(ctx)
if err != nil {
return nil, err
}
fabricLoaders, err := getFabricLoaderVersions(ctx)
if err != nil {
return nil, err
}
var foundMapping *fabricMappingVersion
// find newest compatible version
for _, v := range fabricMappings {
// TODO: some versions contain spaces
semverVersion, err := semver.NewVersion(v.GameVersion)
// skip unparsable minecraft versions
if err != nil {
continue
}
if MCconstraint.Check(semverVersion) {
foundMapping = &v
break
}
}
if foundMapping == nil {
return nil, ErrNoFabricMapping
}
var foundLoader *fabricLoaderVersion
// find newest compatible version
for _, v := range fabricLoaders {
// TODO: some versions contain spaces
semverVersion, err := semver.NewVersion(v.Version)
// skip unparsable minecraft versions
if err != nil {
continue
}
if FabricLoaderConstraint.Check(semverVersion) {
foundLoader = &v
break
}
}
if foundLoader == nil {
return nil, ErrNoFabricLoader
}
return &manifest.FabricLock{
Minecraft: foundMapping.GameVersion,
Mapping: foundMapping.Version,
FabricLoader: foundLoader.Version,
}, nil
}