-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
nurify.nu
212 lines (196 loc) · 8.83 KB
/
nurify.nu
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# Create nurfile from common task/command runner config
#
# Usage:
# > cd into/the/project/path
# > nurify # Will create nurfile
# > nur --help
#
# The generated nurfile is not meant to replace your current task/commend runner, instead it
# will create a nurfile allowing you to use nur instead of the projects task runner. nur
# will then still execute the original task runner.
# Still this allows you to gradually convert your project to nur by replacing your tasks
# bit by bit with new nur variants. When switching to nur this is the recommended method:
# Create new nurfile to run old tasks using the old task runner, then convert task for task.
def prepare-nurfile [] {
"# FILE GENERATED BY nurify COMMAND\n\n" | save -f nurfile
}
def nurify-from-b5 [] {
let global_tasks = (
if (glob ~/.b5/Taskfile | first | path exists) {
cat ~/.b5/Taskfile | lines | filter {
|it| $it starts-with "task:"
} | each {
|it| $it | parse --regex "^task:(?P<name>[^(]+).*" | get name | first
}
} else []
)
prepare-nurfile
b5 --quiet help --tasks | lines | filter {
|it| $it not-in $global_tasks
} | each {
|it| $"def --wrapped \"nur ($it | str replace --all ':' ' ')\" [...args] {\n ^b5 --quiet \"($it)\" ...$args\n}\n"
} | save -f -a nurfile
}
def nurify-from-just [] {
prepare-nurfile
^just --unsorted --dump --dump-format json
| from json
| get recipes
| transpose k v
| each {
|it| $"def --wrapped \"nur ($it.k)\" [...args] {\n ^just \"($it.k)\" ...$args\n}\n"
} | save -f -a nurfile
}
def nurify-from-package-json [] {
prepare-nurfile
open package.json
| get scripts
| transpose k v
| each {
|it| $"def --wrapped \"nur ($it.k)\" [...args] {\n ^npm run \"($it.k)\" ...$args\n}\n"
} | save -f -a nurfile
}
def nurify-from-makefile [] {
prepare-nurfile
open ( glob "[Mm]akefile" | first )
| lines
| find --regex '^[\w\.-]+\s*:'
| where ($it | str trim -l) == $it
| where ($it | str starts-with '.') == false
| split column ':' target
| get target
| str trim
| each {
|it| $"def --wrapped \"nur ($it)\" [...args] {\n ^make \"($it)\" ...$args\n}\n"
} | save -f -a nurfile
}
def nurify-from-toolkit-nu [] {
# Output warning as we cannot support all features and the conversion may not cover all cases
#
# Example of a case not convertable:
# We cannot handle (named) parameters of type "list<string>" as the nur call will not accept a list of
# strings. This is only possible with nu builtin or custom commands. But nur is neither of those, as it
# is a separate executable using the nu libraries. So we cannot handle this case. Basically nu shell will
# tell you that you cannot pass lists to external commands. 😉
print $"(ansi red)Conversion from toolkit.nu may not cover all cases, you might need to extend/fix the generated nurfile(ansi reset)"
print $"(ansi red)\(But be aware: Not all features nu shell commands would provide are available as nur is an external command\)(ansi reset)"
let toolkit_commands = (
nu -c "use toolkit.nu ; scope modules | where name == 'toolkit' | first | get commands | where name != 'toolkit' | each { |it| print $it.name } ; null"
) | lines
def get-toolkit-command-signature [command: string] {
let command_signature = (
nu -c $"use toolkit.nu ; scope commands | where type == 'custom' and name == 'toolkit ($command)' | first | get signatures | to nuon" | from nuon
)
$command_signature | transpose k v | get v | first
}
prepare-nurfile
"use toolkit.nu\n\n" | save -f -a nurfile
$toolkit_commands
| each {
|it|
let signatures = get-toolkit-command-signature $it
let arguments = $signatures | each {
|param|
let param_name = $param.parameter_name
mut param_type = if ($param.syntax_shape | is-not-empty) and $param.syntax_shape != 'any' { $': ($param.syntax_shape)' } else ''
if $param_type starts-with ': completable<' {
$param_type = $": ($param_type | str substring 14..(($param_type | str length) - 2))"
}
let param_docs = if ($param.description | is-not-empty) { $' # ($param.description)' }
match $param {
{parameter_type: "positional"} => $" ($param_name)($param_type)($param_docs)",
{parameter_type: "named"} => $" --($param_name)($param_type)($param_docs)",
{parameter_type: "switch"} => $" --($param_name)($param_docs)",
{parameter_type: "rest"} => $" ...($param_name | default 'rest')($param_type)($param_docs)",
}
} | str join "\n"
let call_arguments = $signatures | each {
|param|
let param_name = $param.parameter_name
match $param {
{parameter_type: "positional"} => $"$($param_name | str replace --all '-' '_')",
{parameter_type: "named"} => $"--($param_name) $($param_name | str replace --all '-' '_')",
{parameter_type: "switch"} => $"--($param_name)=$($param_name | str replace --all '-' '_')",
}
} | str join " "
let rest_arguments = $signatures | each {
|param|
let param_name = $param.parameter_name
match $param {
{parameter_type: "rest"} => $"...$($param_name | default 'rest' | str replace --all '-' '_')",
}
} | str join " "
let has_rest_arguments = $signatures | any {
|param| $param.parameter_type == "rest"
}
$"def( if $has_rest_arguments { ' --wrapped' }) \"nur ($it)\" [\n($arguments)\n] {\n toolkit ($it) ($call_arguments) (if $has_rest_arguments { $rest_arguments })\n}\n"
} | save -f -a nurfile
}
def nurify-from-lets [] {
prepare-nurfile
open lets.yaml
| get commands
| transpose k v
| each {
|it| $"def --wrapped \"nur ($it.k)\" [...args] {\n ^lets \"($it.k)\" ...$args\n}\n"
} | save -f -a nurfile
}
def nurify-from-task [] {
prepare-nurfile
open ( glob "[Tt]askfile.{yml,yaml}" | first )
| get tasks
| transpose k v
| each {
|it| $"def --wrapped \"nur ($it.k)\" [...args] {\n ^task \"($it.k)\" ...$args\n}\n"
} | save -f -a nurfile
}
def nurify-from-tusk [] {
prepare-nurfile
open tusk.yml
| get tasks
| transpose k v
| each {
|it| $"def --wrapped \"nur ($it.k)\" [...args] {\n ^tusk \"($it.k)\" ...$args\n}\n"
} | save -f -a nurfile
}
# Create nurfile from different task/command runners. The nurfile will contain tasks to wrap
# all tasks and then run original task/command runner. This can be used to gradually migrate to nur.
#
# Currently supports:
# * b5 task runner (when build/Taskfile is found)
# * just command runner (when justfile is found)
# * npm package.json scripts (when package.json is found)
# * make (when [Mm]akefile is found)
# * nu toolkit module (when toolkit.nu is found)
# * lets (when lets.yaml is found)
# * task (when [Tt]askfile.{yml,yaml} is found)
# * tusk (when tusk.yml is found)
export def main [] {
if ("build/Taskfile" | path exists) {
print $"(ansi cyan)Found build/Taskfile, converting from b5 task runner(ansi reset)"
nurify-from-b5
} else if ("justfile" | path exists) {
print $"(ansi cyan)Found justfile, converting from just command runner(ansi reset)"
nurify-from-just
} else if ("package.json" | path exists) {
print $"(ansi cyan)Found package.json, converting from npm script(ansi reset)"
nurify-from-package-json
} else if (glob "[Mm]akefile" | is-not-empty) {
print $"(ansi cyan)Found [Mm]akefile, converting from make(ansi reset)"
nurify-from-makefile
} else if ("toolkit.nu" | path exists) {
print $"(ansi cyan)Found toolkit.nu, converting from toolkit.nu(ansi reset)"
nurify-from-toolkit-nu
} else if ("lets.yaml" | path exists) {
print $"(ansi cyan)Found lets.yaml, converting from lets(ansi reset)"
nurify-from-lets
} else if (glob "[Tt]askfile.{yml,yaml}" | is-not-empty) {
print $"(ansi cyan)Found [Tt]askfile.{yml,yaml}, converting from task(ansi reset)"
nurify-from-task
} else if ("tusk.yml" | path exists) {
print $"(ansi cyan)Found tusk.yml, converting from tusk(ansi reset)"
nurify-from-tusk
} else {
error make {"msg": "Could not find any existing task/command runner, please run nurify in project root"}
}
}