Skip to content

Commit 2ac381d

Browse files
authored
feat: Add support for legacy files (#13)
1 parent 5b49c46 commit 2ac381d

File tree

5 files changed

+174
-95
lines changed

5 files changed

+174
-95
lines changed

Diff for: .github/workflows/release.yml

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ on:
44
workflow_run:
55
workflows: [Build]
66
types: [completed]
7+
branches: [main]
78

89
concurrency:
910
group: release

Diff for: README.md

+8
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,14 @@ devShells.default = pkgs.mkShell {
127127
`packagesFromVersionsFile` is of the form `{ “<plugin-1>” = <package-1>;
128128
"<plugin-2>" = <package-2>; ... }`.
129129

130+
## Version Files
131+
132+
As of version `2.1.0`, asdf2nix now supports legacy version files in the same
133+
way that
134+
[asdf](https://asdf-vm.com/manage/configuration.html#legacy-version-file) does.
135+
Check the version files [test suite](tests/version_files_test.nix) for more
136+
information on how this feature works.
137+
130138
## Plugins
131139

132140
In an asdf2nix context, a plugin’s primary goal is to determine whether a

Diff for: flake.nix

+46-14
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
in
88
{
99
lib.packagesFromVersionsFile =
10-
{ versionsFile
10+
{ versionsFile ? null
11+
, legacyVersionFiles ? { }
1112
, system ? builtins.currentSystem
1213
, plugins ? { }
1314
, skipMissingPlugins ? false
@@ -22,10 +23,46 @@
2223
in
2324
{
2425
name = builtins.elemAt pluginAndVersion 0;
25-
version = builtins.elemAt pluginAndVersion 1;
26+
value = builtins.elemAt pluginAndVersion 1;
2627
});
27-
filterPlugins = builtins.filter
28-
({ name, ... }:
28+
toolVersions =
29+
if versionsFile == null
30+
then { }
31+
else
32+
builtins.listToAttrs
33+
(parseVersions
34+
(removeComments
35+
(fileLines versionsFile)));
36+
legacyVersions =
37+
builtins.mapAttrs
38+
(_: file: lib.fileContents file)
39+
legacyVersionFiles;
40+
versions =
41+
lib.throwIf (versionsFile == null && legacyVersionFiles == { })
42+
''
43+
No version files provided. Try with `versionsFile`:
44+
45+
```
46+
packagesFromVersionsFile {
47+
versionsFile = ./.tool-versions;
48+
...
49+
}
50+
```
51+
52+
Or `legacyVersionFiles`:
53+
54+
```
55+
packagesFromVersionsFile {
56+
legacyVersionFiles = {
57+
python = ./.python-version;
58+
};
59+
...
60+
}
61+
```
62+
''
63+
toolVersions // legacyVersions;
64+
filterPlugins = lib.filterAttrs
65+
(name: _:
2966
let
3067
hasPlugin = builtins.hasAttr name plugins;
3168
in
@@ -56,8 +93,8 @@
5693
lib.warnIf
5794
(!hasPlugin) "Skipping \"${name}\" plugin"
5895
hasPlugin);
59-
findPackages = builtins.map
60-
({ name, version }:
96+
findPackages = builtins.mapAttrs
97+
(name: version:
6198
let
6299
plugin = plugins.${name};
63100
in
@@ -70,18 +107,13 @@
70107
> nix flake lock --update-input <asdf2nix-${name}>
71108
```
72109
''
110+
plugin.packageFromVersion
73111
{
74-
inherit name;
75-
value = plugin.packageFromVersion { inherit system version; };
112+
inherit system version;
76113
}
77114
);
78115
in
79-
builtins.listToAttrs
80-
(findPackages
81-
(filterPlugins
82-
(parseVersions
83-
(removeComments
84-
(fileLines versionsFile)))));
116+
findPackages (filterPlugins versions);
85117

86118
templates = {
87119
default = {

Diff for: tests/lib_test.nix

+30-81
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,12 @@ let
22
lib = (builtins.getFlake (builtins.toString ./..)).lib;
33
in
44
[
5+
# comments
56
{
6-
name = "Ignores comment lines";
7-
actual = lib.packagesFromVersionsFile {
8-
versionsFile = builtins.toFile ".tool-versions" ''
9-
# This is a comment
10-
python 3.12.0
11-
# This is another comment
12-
terraform 1.6.3
13-
'';
14-
plugins = {
15-
python = {
16-
hasVersion = _: true;
17-
packageFromVersion = { version, ... }: version;
18-
};
19-
terraform = {
20-
hasVersion = _: true;
21-
packageFromVersion = { version, ... }: version;
22-
};
23-
};
24-
};
25-
expected = { python = "3.12.0"; terraform = "1.6.3"; };
26-
}
27-
{
28-
name = "Ignores inline comments";
7+
name = ''
8+
When versionsFile contain comments, then it ignores those during the
9+
parsing
10+
'';
2911
actual = lib.packagesFromVersionsFile {
3012
versionsFile = builtins.toFile ".tool-versions" ''
3113
# This is a comment
@@ -48,14 +30,8 @@ in
4830
# skipMissingPlugins = false
4931
{
5032
name = ''
51-
Given:
52-
- A versions file referencing some plugins
53-
- A set of plugins matching only one of them
54-
- A feature flag to skip missing plugins
55-
When:
56-
- The matching plugin provides a package for the requested version
57-
Then:
58-
- Returns a set with the retrieved package
33+
When skipMissingPlugins is enabled and some plugins are missing, then
34+
returns packages only for the ones matching
5935
'';
6036
actual = lib.packagesFromVersionsFile {
6137
versionsFile = builtins.toFile ".tool-versions" ''
@@ -74,15 +50,8 @@ in
7450
}
7551
{
7652
name = ''
77-
Given:
78-
- A versions file referencing some plugins
79-
- A set of plugins matching only one of them
80-
- A feature flag to skip missing plugins
81-
When:
82-
- The matching plugin does not provide a package for the requested
83-
version
84-
Then:
85-
- Throws an error
53+
When skipMissingPlugins is enabled and all plugins are provided, then it
54+
returns all the packages
8655
'';
8756
actual = builtins.tryEval (
8857
(lib.packagesFromVersionsFile {
@@ -96,20 +65,14 @@ in
9665
};
9766
};
9867
skipMissingPlugins = true;
99-
})
68+
}).python
10069
);
10170
expected = { success = false; value = false; };
10271
}
10372
{
10473
name = ''
105-
Given:
106-
- A versions file referencing some plugins
107-
- A set of empty plugins
108-
- A feature flag to skip missing plugins
109-
When:
110-
- There are no plugins available
111-
Then:
112-
- Returns an empty set
74+
When skipMissingPlugins is enabled and no plugins are provided, then
75+
returns an empty set
11376
'';
11477
actual = lib.packagesFromVersionsFile {
11578
versionsFile = builtins.toFile ".tool-versions" ''
@@ -123,13 +86,8 @@ in
12386
# skipMissingPlugins = false
12487
{
12588
name = ''
126-
Given:
127-
- A versions file referencing some plugins
128-
- A set of plugins matching all of them
129-
When:
130-
- The matching plugins provide packages for the requested versions
131-
Then:
132-
- Returns a set with the retrieved packages
89+
When skipMissingPlugins is disabled and all plugins are provided, then
90+
returns all packages
13391
'';
13492
actual = lib.packagesFromVersionsFile {
13593
versionsFile = builtins.toFile ".tool-versions" ''
@@ -149,39 +107,30 @@ in
149107
};
150108
expected = { python = "3.12.0"; terraform = "1.6.3"; };
151109
}
110+
# hasVersions
152111
{
153112
name = ''
154-
Given:
155-
- A versions file referencing some plugins
156-
- A set of plugins matching all of them
157-
When:
158-
- The matching plugin does not provide a package for the requested
159-
version
160-
Then:
161-
- Throws an error
113+
When the provided plugin does not contain the requested version, then
114+
throws an error
162115
'';
163-
actual = builtins.tryEval (lib.packagesFromVersionsFile {
164-
versionsFile = builtins.toFile ".tool-versions" ''
165-
python 3.12.0
166-
'';
167-
plugins = {
168-
python = {
169-
hasVersion = _: false;
170-
packageFromVersion = { version, ... }: version;
116+
actual = builtins.tryEval (
117+
(lib.packagesFromVersionsFile {
118+
versionsFile = builtins.toFile ".tool-versions" ''
119+
python 3.12.0
120+
'';
121+
plugins = {
122+
python = {
123+
hasVersion = _: false;
124+
packageFromVersion = { version, ... }: version;
125+
};
171126
};
172-
};
173-
});
127+
}).python
128+
);
174129
expected = { success = false; value = false; };
175130
}
176131
{
177132
name = ''
178-
Given:
179-
- A versions file referencing some plugins
180-
- A set of empty plugins
181-
When:
182-
- There are no plugins available
183-
Then:
184-
- Throws an error
133+
When no plugins are provided, then throws an error
185134
'';
186135
actual = builtins.tryEval (lib.packagesFromVersionsFile {
187136
versionsFile = builtins.toFile ".tool-versions" ''

Diff for: tests/version_files_test.nix

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
let
2+
lib = (builtins.getFlake (builtins.toString ./..)).lib;
3+
in
4+
[
5+
{
6+
name = ''
7+
When neither versionsFile nor legacyVersionFiles are provided, then
8+
throws an error
9+
'';
10+
actual = builtins.tryEval (lib.packagesFromVersionsFile { });
11+
expected = { success = false; value = false; };
12+
}
13+
{
14+
name = ''
15+
When only legacyVersionFiles is provided, then returns the package
16+
matching the requested version
17+
'';
18+
actual = lib.packagesFromVersionsFile {
19+
legacyVersionFiles = {
20+
python = builtins.toFile ".python-version" ''
21+
3.12.0
22+
'';
23+
};
24+
plugins = {
25+
python = {
26+
hasVersion = _: true;
27+
packageFromVersion = { version, ... }: version;
28+
};
29+
};
30+
};
31+
expected = { python = "3.12.0"; };
32+
}
33+
{
34+
name = ''
35+
When both versionsFile and legacyVersionFiles are provided and the
36+
plugins does not overlap, then returns packages specified in both files
37+
'';
38+
actual = lib.packagesFromVersionsFile {
39+
versionsFile = builtins.toFile ".tool-versions" ''
40+
terraform 1.6.3
41+
'';
42+
legacyVersionFiles = {
43+
python = builtins.toFile ".python-version" ''
44+
3.12.0
45+
'';
46+
};
47+
plugins = {
48+
python = {
49+
hasVersion = _: true;
50+
packageFromVersion = { version, ... }: version;
51+
};
52+
terraform = {
53+
hasVersion = _: true;
54+
packageFromVersion = { version, ... }: version;
55+
};
56+
};
57+
};
58+
expected = { python = "3.12.0"; terraform = "1.6.3"; };
59+
}
60+
{
61+
name = ''
62+
When both versionsFile and legacyVersionFiles are provided and the
63+
plugins overlap, then the version of the tool coming from the legacy file
64+
takes more precedence
65+
'';
66+
actual = lib.packagesFromVersionsFile {
67+
versionsFile = builtins.toFile ".tool-versions" ''
68+
python 2.7.6
69+
terraform 1.6.3
70+
'';
71+
legacyVersionFiles = {
72+
python = builtins.toFile ".python-version" ''
73+
3.12.0
74+
'';
75+
};
76+
plugins = {
77+
python = {
78+
hasVersion = _: true;
79+
packageFromVersion = { version, ... }: version;
80+
};
81+
terraform = {
82+
hasVersion = _: true;
83+
packageFromVersion = { version, ... }: version;
84+
};
85+
};
86+
};
87+
expected = { python = "3.12.0"; terraform = "1.6.3"; };
88+
}
89+
]

0 commit comments

Comments
 (0)