Skip to content

Commit 6441dcf

Browse files
committed
Improve --help, rename --owner, add short flags
1 parent bacfd45 commit 6441dcf

File tree

2 files changed

+113
-64
lines changed

2 files changed

+113
-64
lines changed

README.md

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Gets the list of Mullvad servers with the best latency according to `ping`.
44

5-
## Install
5+
## Running
66

77
1. First
88
[install Deno](https://docs.deno.com/runtime/manual/getting_started/installation),
@@ -14,25 +14,31 @@ Gets the list of Mullvad servers with the best latency according to `ping`.
1414
deno run --allow-net=api.mullvad.net,deno.land --allow-run=ping https://raw.githubusercontent.com/grant0417/mullvad-ping/v0.7.0/script.ts
1515
```
1616

17+
3. Alternatively, you can download a compiled release from the
18+
[releases page](https://github.com/grant0417/mullvad-ping/releases/).
19+
1720
Note: The Windows version of `ping` is somewhat more limited than that of Linux
1821
or Mac so the times are less precice and the script will take ~5x longer.
1922

20-
## Usage
23+
## CLI Usage
2124

2225
```
23-
Usage: script [OPTION]
24-
--country <code> the country you want to query (eg. us, gb, de)
25-
--list lists the available servers
26-
--list-countries lists the available countries
27-
--list-providers lists the available providers
28-
--type <type> the type of server to query (openvpn, bridge, wireguard, all)
29-
--count <n> the number of pings to the server (default 5)
30-
--top <n> the number of top servers to show, (0=all, default 5)
31-
--port-speed <n> only show servers with at least n Gigabit port speed
32-
--provider <name> only show servers from the given provider
33-
--owned <true|false> only show servers owned by Mullvad
34-
--run-mode <type> only show servers running from (all, ram, disk)
35-
--include-inactive include inactive servers
36-
--json output the results in JSON format
37-
--help, -h display this help and exit
26+
Usage: mullvad-ping [OPTIONS]
27+
28+
Options:
29+
-c, --country <CODE> the country you want to query (eg. us, gb, de)
30+
-l, --list lists the available servers
31+
--list-countries lists the available countries
32+
--list-providers lists the available providers
33+
-t, --type <TYPE> the type of server to query (openvpn, bridge, wireguard, all)
34+
-C, --count <COUNT> the number of pings to the server (default 5)
35+
-n, --top <TOPN> the number of top servers to show, (0=all, default 5)
36+
-s, --port-speed <SPEED> only show servers with at least n Gbps port speed
37+
-p, --provider <NAME> only show servers from the given provider
38+
--owner <OWNER> only show servers by owner (mullvad, rented, all)
39+
--run-mode <TYPE> only show servers running from (ram, disk, all)
40+
--include-inactive include inactive servers
41+
-j, --json output the results in JSON format
42+
-h, --help display this help and exit
43+
-V, --version display version information and exit
3844
```

script.ts

Lines changed: 90 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import {
66
red,
77
} from "https://deno.land/[email protected]/fmt/colors.ts";
88

9+
const CLI_NAME = "mullvad-ping";
10+
const VERSION = "v0.8.0";
11+
912
type ServerData = {
1013
hostname: string;
1114
country_code: string;
@@ -36,24 +39,17 @@ function error(...message: unknown[]) {
3639
Deno.exit(1);
3740
}
3841

39-
function checkRunMode(stboot: boolean, runMode: string) {
40-
if (runMode === "all") {
41-
return true;
42-
} else if (runMode === "ram" && stboot === true) {
43-
return true;
44-
} else if (runMode === "disk" && stboot === false) {
45-
return true;
46-
}
47-
return false;
48-
}
49-
5042
const serverTypes = ["openvpn", "bridge", "wireguard", "all"];
51-
const runTypes = ["all", "ram", "disk"];
43+
const ownerTypes = ["mullvad", "rented", "all"];
44+
const runTypes = ["ram", "disk", "all"];
5245

5346
const INTERVAL_DEFAULT = 0.2;
5447
const COUNT_DEFAULT = 5;
5548
const TOP_DEFAULT = 5;
5649
const PORT_SPEED_DEFAULT = 0;
50+
const RUN_MODE_DEFAULT = "all";
51+
const OWNER_DEFAULT = "all";
52+
const TYPE_DEFAULT = "all";
5753

5854
const args = parseArgs(Deno.args, {
5955
"--": false,
@@ -63,7 +59,7 @@ const args = parseArgs(Deno.args, {
6359
"interval",
6460
"count",
6561
"top",
66-
"owned",
62+
"owner",
6763
"port-speed",
6864
"provider",
6965
"run-mode",
@@ -75,43 +71,70 @@ const args = parseArgs(Deno.args, {
7571
"list-providers",
7672
"include-inactive",
7773
"json",
74+
"version",
7875
],
7976
alias: {
77+
c: "country",
78+
l: "list",
79+
t: "type",
80+
C: "count",
81+
n: "top",
82+
s: "port-speed",
83+
p: "provider",
84+
j: "json",
8085
h: "help",
86+
V: "version",
8187
},
8288
default: {
8389
interval: `${INTERVAL_DEFAULT}`,
8490
count: `${COUNT_DEFAULT}`,
8591
top: `${TOP_DEFAULT}`,
8692
"port-speed": `${PORT_SPEED_DEFAULT}`,
87-
"run-mode": "all",
88-
"type": "all",
93+
"run-mode": RUN_MODE_DEFAULT,
94+
owner: OWNER_DEFAULT,
95+
"type": TYPE_DEFAULT,
8996
},
9097
unknown: (arg) => {
9198
error(`Unknown argument ${arg}`);
9299
},
93100
});
94101

95102
if (args.help) {
96-
console.log(`Usage: script [OPTION]
97-
--country <code> the country you want to query (eg. us, gb, de)
98-
--list lists the available servers
99-
--list-countries lists the available countries
100-
--list-providers lists the available providers
101-
--type <type> the type of server to query (${
102-
serverTypes.join(", ")
103-
})
104-
--count <n> the number of pings to the server (default ${COUNT_DEFAULT})
105-
--top <n> the number of top servers to show, (0=all, default ${TOP_DEFAULT})
106-
--port-speed <n> only show servers with at least n Gigabit port speed
107-
--provider <name> only show servers from the given provider
108-
--owned <true|false> only show servers owned by Mullvad
109-
--run-mode <type> only show servers running from (${
110-
runTypes.join(", ")
111-
})
112-
--include-inactive include inactive servers
113-
--json output the results in JSON format
114-
--help, -h display this help and exit`);
103+
const serverTypesStr = serverTypes.join(", ");
104+
const ownerTypesStr = ownerTypes.join(", ");
105+
const runTypesStr = runTypes.join(", ");
106+
107+
// This help is formatted like cargo's help
108+
console.log(
109+
`Gets the list of Mullvad servers with the best latency according to ping
110+
111+
${green(bold("Usage:"))} ${cyan(bold(CLI_NAME))} ${cyan("[OPTIONS]")}
112+
113+
${green(bold("Options:"))}
114+
-c, --country <CODE> the country you want to query (eg. us, gb, de)
115+
-l, --list lists the available servers
116+
--list-countries lists the available countries
117+
--list-providers lists the available providers
118+
-t, --type <TYPE> the type of server to query (${serverTypesStr})
119+
-C, --count <COUNT> the number of pings to the server (default ${COUNT_DEFAULT})
120+
-n, --top <TOPN> the number of top servers to show, (0=all, default ${TOP_DEFAULT})
121+
-s, --port-speed <SPEED> only show servers with at least n Gbps port speed
122+
-p, --provider <NAME> only show servers from the given provider
123+
--owner <OWNER> only show servers by owner (${ownerTypesStr})
124+
--run-mode <TYPE> only show servers running from (${runTypesStr})
125+
--include-inactive include inactive servers
126+
-j, --json output the results in JSON format
127+
-h, --help display this help and exit
128+
-V, --version display version information and exit`
129+
.replace(/(--?[a-zA-Z-]+)/g, cyan(bold("$1")))
130+
.replace(/(<[^>]+>)/g, cyan("$1")),
131+
);
132+
133+
Deno.exit(0);
134+
}
135+
136+
if (args.version) {
137+
console.log(CLI_NAME, VERSION);
115138
Deno.exit(0);
116139
}
117140

@@ -133,25 +156,23 @@ const count = parseInt(args.count) || COUNT_DEFAULT;
133156
const topN = parseInt(args.top) || TOP_DEFAULT;
134157
const portSpeed = parseInt(args["port-speed"]) || PORT_SPEED_DEFAULT;
135158

159+
const owned = args.owner.toLowerCase();
160+
if (!ownerTypes.includes(owned)) {
161+
error(`Invalid owner, allowed types are: ${ownerTypes.join(", ")}`);
162+
}
163+
136164
const runMode = args["run-mode"].toLowerCase();
137165
if (!runTypes.includes(runMode)) {
138166
error(
139167
`Invalid run-mode, allowed types are: ${runTypes.join(", ")}`,
140168
);
141169
}
142170

143-
let owned: boolean | undefined;
144-
if (typeof args.owned === "string") {
145-
const argOwner = args.owned.toLowerCase();
146-
if (argOwner === "true") {
147-
owned = true;
148-
} else if (argOwner === "false") {
149-
owned = false;
150-
} else {
151-
error(
152-
"Invalid value for owned, must be true or false. Example: --owned true",
153-
);
154-
}
171+
// ensure that no more than 1 of list, list-countries, list-providers is set
172+
const listCount = [args.list, args["list-countries"], args["list-providers"]]
173+
.filter((e) => e).length;
174+
if (listCount > 1) {
175+
error("Only one of list, list-countries, list-providers can be set");
155176
}
156177

157178
const provider = args.provider;
@@ -176,14 +197,36 @@ if (fetchingSpinner) {
176197
console.log();
177198
}
178199

200+
function checkRunMode(stboot: boolean, runMode: string) {
201+
if (runMode === "all") {
202+
return true;
203+
} else if (runMode === "ram" && stboot === true) {
204+
return true;
205+
} else if (runMode === "disk" && stboot === false) {
206+
return true;
207+
}
208+
return false;
209+
}
210+
211+
function checkOwnership(owned: string, server: ServerData) {
212+
if (owned === "all") {
213+
return true;
214+
} else if (owned === "mullvad" && server.owned) {
215+
return true;
216+
} else if (owned === "rented" && !server.owned) {
217+
return true;
218+
}
219+
return false;
220+
}
221+
179222
const json: Array<ServerData> = await response.json();
180223

181224
const servers = json.filter((server) =>
182225
(country === undefined || country === server.country_code) &&
183226
(server.network_port_speed >= portSpeed) &&
184227
checkRunMode(server.stboot, runMode) &&
185228
(provider === undefined || provider === server.provider) &&
186-
(owned === undefined || owned === server.owned) &&
229+
checkOwnership(owned, server) &&
187230
(args["include-inactive"] || server.active)
188231
);
189232

0 commit comments

Comments
 (0)