-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathbash2pwsh.js
122 lines (99 loc) · 3 KB
/
bash2pwsh.js
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
// You can edit this file.
// This is a simple conversion script which uses Regular Expression.
// If additional conversions are required, please add it as you wish.
const fs = require("fs");
const BASH_ROOT = "C:/msys64";
const BASH_HOME = "C:/msys64/home/owner";
const src = process.argv[2];
const dest = process.argv[3];
try {
const bash = fs.readFileSync(src, "utf8");
let pwsh = convert(bash);
pwsh =
`\
# This file is auto generated by bash2pwsh.js
` + pwsh;
fs.writeFileSync(dest, pwsh);
console.log(`"${dest}" was created Successfully!`);
} catch (err) {
console.log("Error : " + err.message);
}
/**
* Convert bash script to powershell script.
* @param {String} bash bash script body
* @returns powershell script body
*/
function convert(bash) {
// bash & powershell:
// "$a" > variables are expaneded
// '$a' > variables are not expanded
// bash : export vs alias
// > One difference between the two is that aliases are only a shell feature.
// > Environment variables are inherited by all subprocesses (unless deliberately cleared).
// https://unix.stackexchange.com/a/129609
//
// export diray='C:/'
// echo $diary
//
// alias diary='C:/'
// echo diary
// bash : variable vs alias
// https://stackoverflow.com/a/7342780/14820021
// export d_diary='C:/Ws/diary'
// >>>
// $d_diary='C:/Dev'
bash = bash.replace(/export (\w+)=(['"].*?['"])/g, "$$$1=$2");
// alias which does not contains command or variables
// alias code='C:/Dev/VSCode/Code.exe'
// >>>
// Set-Alias -Name code -Value 'cd $d_diary'
bash = bash.replace(
/alias (\w+)=(['"](?!\w{1,4} )[^$$]+?['"])/g,
"Set-Alias -Name $1 -Value $2"
);
// ## alias which contains command or variables
// alias cd_diary="cd $d_diary"
// >>>
// function cd_diary() { cd $d_diary }
bash = bash.replace(/alias (\w+)=['"](.+?)['"]/g, "function $1() { $2 }");
// EDITOR='code'
// >>>
// $EDITOR='code'
bash = bash.replace(/(^(?:\s+)?)(\w+)=(['"].*?['"])$/gm, "$1$$$2=$3");
// export PATH=$PATH:/usr/bin
// >>>
// $env:Path += ";C:/msys64/usr/bin"
bash = bash.replace(
/(?<=[:"'])\/(bin|dev|etc|home|mingw|msys|opt|tmp|usr|var)/g,
`${BASH_ROOT}/$1`
);
bash = bash.replace(/export (\w+)=\$\w+:([\w:/\\]+)/g, '$env:$1 += ";$2"');
// ~/.bashrc
// >>>
// C:/msys64/.bashrc
bash = bash.replace(/~\//g, `${BASH_HOME}/`);
// $@
// >>>
// $args
bash = bash.replace(/\$@/g, "$$args");
// bash/zsh arg numbers are different from powershell
// $1
// >>>
// $args[0]
for (let i = 0; i < 10; i++) {
bash = bash.replace(new RegExp("$" + (i + 1), "g"), "$$args[" + i + "]");
}
// local some_variable
// >>>
// $some_variable
bash = bash.replace(/^\s+local\s+(\w+)/gm, "$$$1");
// /c/Program Files/
// >>>
// C:/Program Files
bash = bash.replace(/(?:\s|^)\/([cdefghijk])\//im, "$1:/");
// $args >& $outfile
// >>>
// $args Out-File -FilePath $outFile
bash = bash.replace(/(\S+)\s*>&\s*(\S+)/g, "$1 | Out-File -FilePath $2");
return bash;
}