chore(CI): add super-linter to help lint workspace (#137)

This commit is contained in:
Miraculous Owonubi 2022-02-16 05:40:55 +01:00 committed by GitHub
parent 980c9af668
commit d5a736008c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 253 additions and 196 deletions

View File

@ -19,6 +19,10 @@
"plugins": [
"prettier"
],
"ignorePatterns": [
"**/*.json",
"**/*.json5"
],
"rules": {
"prettier/prettier": [
1,

5
.github/FUNDING.yml vendored
View File

@ -1,4 +1,7 @@
custom: ['https://commerce.coinbase.com/checkout/466d703a-fbd7-41c9-8366-9bdd3e240755']
---
custom:
- https://commerce.coinbase.com/checkout/466d703a-fbd7-41c9-8366-9bdd3e240755
ko_fi: miraclx
liberapay: miraclx
patreon: miraclx

10
.github/linters/.jscpd.json vendored Normal file
View File

@ -0,0 +1,10 @@
{
"threshold": 0,
"reporters": [
"consoleFull"
],
"ignore": [
"**/.github/workflows/tests.yml"
],
"absolute": true
}

18
.github/workflows/ci-prep.sh vendored Normal file → Executable file
View File

@ -1,10 +1,12 @@
#!/usr/bin/env bash
RG_SRC="$(which rg)"
rg() {
printf "rg: pattern: /$*/" > /dev/stderr
printf 'rg: pattern: %s' "/$*/" >/dev/stderr
if $RG_SRC --fixed-strings --passthru "$@"; then
echo " (matched)" > /dev/stderr
echo " (matched)" >/dev/stderr
else
echo " (failed to match)" > /dev/stderr
echo " (failed to match)" >/dev/stderr
return 1
fi
}
@ -16,7 +18,7 @@ freyr() {
i=$($RG_SRC -n '.' .freyr_log | $RG_SRC --fixed-strings '[•] Embedding Metadata' | cut -d':' -f1)
if [[ $i ]]; then
echo "::group::[$attempts/3] View Download Status"
tail +$i .freyr_log
tail +"$i" .freyr_log
echo "::endgroup::"
fi
}
@ -25,9 +27,9 @@ exec_retry() {
cmd="$(cat)" && attempts=1
until eval "$cmd"; do
echo "::endgroup::"
if (( attempts < 3 )); then
if ((attempts < 3)); then
echo "::warning::[$attempts/3] Download failed, retrying.."
: $(( attempts += 1 ))
: $((attempts += 1))
else
echo "::error::[$attempts/3] Download failed."
return 1
@ -36,7 +38,7 @@ exec_retry() {
echo "::endgroup::"
echo "::group::View Files"
STAGE=$(realpath --relative-to=../.. .) && cd ../..
tree -sh $STAGE
tree -sh "$STAGE"
echo "::endgroup::"
}
@ -45,5 +47,5 @@ validate() {
res=$(<.freyr_log)
for arg in "[•] Collation Complete" "$@"; do
res=$(echo "$res" | rg "$arg") || return 1
done > /dev/null
done >/dev/null
}

View File

@ -1,3 +1,4 @@
---
name: publish
on:

View File

@ -1,3 +1,4 @@
---
name: tests
on:
@ -238,3 +239,28 @@ jobs:
- name: Test Docker Build
run: docker build -t freyrcli/freyrjs .
linter:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v2
with:
# Full git history is needed to get a proper list of changed files within `super-linter`
fetch-depth: 0
- name: Install Dependencies
run: npm ci
- name: Lint Code Base
uses: github/super-linter@v4
env:
VALIDATE_ALL_CODEBASE: false
DEFAULT_BRANCH: master
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
LINTER_RULES_PATH: /
JAVASCRIPT_ES_CONFIG_FILE: .eslintrc
JSCPD_CONFIG_FILE: .github/linters/.jscpd.json
VALIDATE_JAVASCRIPT_STANDARD: false

View File

@ -5,6 +5,7 @@ LABEL maintainer="Miraculous Owonubi <omiraculous@gmail.com>" \
tag="alpine"
# Install dependencies and clean cache
# hadolint ignore=DL3018
RUN apk add \
--no-cache \
git \
@ -26,6 +27,7 @@ RUN mkdir /bins \
ENV PATH "/bins:$PATH"
# Create freyr user and group
# hadolint ignore=DL4006
RUN addgroup -g 1000 freyr \
&& adduser -DG freyr freyr \
&& echo freyr:freyr | chpasswd

View File

@ -85,7 +85,7 @@
macOS + Linux: [nvm](https://github.com/nvm-sh/nvm) recommended.
``` bash
```bash
# install node with this nvm command
# freyr works with a minimum of v12
$ nvm install --lts
@ -99,7 +99,9 @@
<details>
<summary>ffmpeg >= v0.9</summary>
<!-- textlint-disable -->
Download for your individual platforms here <https://ffmpeg.org/download.html>
<!-- textlint-enable -->
- Windows + macOS:
- Ensure to extract the `ffmpeg` binary from the compressed file, if it's in one.
@ -145,7 +147,7 @@ First start by ensuring all requirements listed above are satisfied. Thereafter,
- <details>
<summary>Or you can build from source</summary>
``` bash
```bash
git clone https://github.com/miraclx/freyr-js.git freyr
cd freyr
```
@ -165,13 +167,13 @@ Image Size: [![Docker Image Size](https://img.shields.io/docker/image-size/freyr
#### Usage (docker)
``` bash
```bash
docker run -it --rm -v $PWD:/data freyrcli/freyrjs [options, arguments and queries...]
```
You can also create a handy alias to skip remembering that whole line everytime
``` bash
```bash
alias freyr='docker run -it --rm -v $PWD:/data freyrcli/freyrjs'
```
@ -186,7 +188,7 @@ alias freyr='docker run -it --rm -v $PWD:/data freyrcli/freyrjs'
### Usage
``` text
```text
Usage: freyr [options] [query...]
Usage: freyr [options] [subcommand]
```
@ -201,7 +203,7 @@ Usage: freyr [options] [subcommand]
*The `get` subcommand is implicit and default.
``` text
```text
Usage: freyr [options] get [options] [query...]
Usage: freyr [options] [query...]
```
@ -209,7 +211,8 @@ Usage: freyr [options] [query...]
<details>
<summary> <code>freyr get --help</code> </summary>
``` console
<!-- editorconfig-checker-disable -->
```console
____
/ __/_______ __ _______
/ /_/ ___/ _ \/ / / / ___/
@ -294,6 +297,7 @@ Info:
their respective folders. However, a m3u8 playlist file is generated in
the base directory with the name of the playlist that lists the tracks
```
<!-- editorconfig-checker-enable -->
</details>
@ -302,7 +306,8 @@ Info:
<details>
<summary> <code>freyr spotify:track:5FNS5Vj69AhRGJWjhrAd01</code> </summary>
``` console
<!-- editorconfig-checker-disable -->
```console
____
/ __/_______ __ _______
/ /_/ ___/ _ \/ / / / ___/
@ -353,6 +358,7 @@ Checking directory permissions...[done]
[•] Output bitrate: 320k
===============================
```
<!-- editorconfig-checker-enable -->
</details>
@ -361,7 +367,8 @@ Checking directory permissions...[done]
<details>
<summary> <code> freyr https://music.apple.com/us/album/im-sorry-im-not-sorry-ep/1491795443 </code> </summary>
``` console
<!-- editorconfig-checker-disable -->
```console
____
/ __/_______ __ _______
/ /_/ ___/ _ \/ / / / ___/
@ -436,6 +443,7 @@ Checking directory permissions...[done]
[•] Output bitrate: 320k
===============================
```
<!-- editorconfig-checker-enable -->
</details>
@ -444,7 +452,8 @@ Checking directory permissions...[done]
<details>
<summary> <code> freyr https://www.deezer.com/us/artist/14808825 </code> </summary>
``` console
<!-- editorconfig-checker-disable -->
```console
____
/ __/_______ __ _______
/ /_/ ___/ _ \/ / / / ___/
@ -503,6 +512,7 @@ Checking directory permissions...[done]
[•] Output bitrate: 320k
===============================
```
<!-- editorconfig-checker-enable -->
</details>
@ -512,7 +522,7 @@ Checking directory permissions...[done]
Queries can be collated to be processed at once.
``` bash
```bash
freyr query1 query2 ... queryN
```
@ -523,7 +533,7 @@ Queries should be on separate lines.
Lines starting with a `#` are treated as comments and ignored. comments can also be inlined with everything following the `#` character ignored.
``` text
```text
# ./queue.txt
# Hailee Steinfeld
@ -534,7 +544,7 @@ https://open.spotify.com/track/7GCVboEDzfL3NKp1NrAgHR # (track) Wrong Direction
https://open.spotify.com/album/3stadz88XVpHcXnVYMHc4J
```
``` bash
```bash
freyr -i ./queue.txt
```
@ -582,7 +592,7 @@ Creating freyr-compatible queue output.
<details>
<summary> <code> freyr urify https://open.spotify.com/album/2D23kwwoy2JpZVuJwzE42B --no-header --no-logo --no-tag </code> </summary>
``` text
```text
spotify:album:2D23kwwoy2JpZVuJwzE42B
[+] Urify complete
```
@ -592,7 +602,7 @@ spotify:album:2D23kwwoy2JpZVuJwzE42B
<details>
<summary> <code> freyr urify -i queue_of_urls.txt -o queue_of_uris.txt --no-header --no-logo </code> </summary>
``` text
```text
[+] Urify complete
Successfully written to [queue_of_uris.txt]
```
@ -683,7 +693,7 @@ Defaults are in the [conf.json](https://github.com/miraclx/freyr-js/blob/master/
<details>
<summary>Example JSON</summary>
``` json
```json
{
"server": {
"hostname": "localhost",
@ -752,7 +762,7 @@ An invalid `refreshToken`, when specified, would fallback to requesting account
- `storefront`: \<string\>
- `developerToken`: \<string\>
This library already includes a pre-defined developer token that should work at will. This developer token is the default token, extracted off the Apple Music website. While this developer token could expire over time, we'll try to update with the most recent developer token as time goes on.
This library already includes a predefined developer token that should work at will. This developer token is the default token, extracted off the Apple Music site. While this developer token could expire over time, we'll try to update with the most recent developer token as time goes on.
To create a custom developer token, please refer to the Apple Music documentation on this topic.
@ -848,7 +858,7 @@ To preview filter rules specification, use the `filter` subcommand.
<details>
<summary> <code> freyr filter title="all*good girls*hell",artist="*eilish",trackn="4..=5" --no-header --no-logo </code> </summary>
``` text
```text
[
{
"query": "*",
@ -870,7 +880,7 @@ To preview filter rules specification, use the `filter` subcommand.
| [Spotify](https://github.com/miraclx/freyr-js/blob/master/src/services/spotify.js) | ✔ | ✔ | ✔ | ✔ | `spotify:` |
| [Apple Music](https://github.com/miraclx/freyr-js/blob/master/src/services/apple_music.js) | ✔ | ✔ | ✔ | ✔ | `apple_music:` |
| [Deezer](https://github.com/miraclx/freyr-js/blob/master/src/services/deezer.js) | ✔ | ✔ | ✔ | ✔ | `deezer:` |
| Youtube Music (See [#6](https://github.com/miraclx/freyr-js/issues/6)) | ✗ | ✗ | ✗ | ✗ | ✗ |
| YouTube Music (See [#6](https://github.com/miraclx/freyr-js/issues/6)) | ✗ | ✗ | ✗ | ✗ | ✗ |
| Tidal (See [#33](https://github.com/miraclx/freyr-js/issues/33)) | ✗ | ✗ | ✗ | ✗ | ✗ |
### Metadata Availability
@ -1031,14 +1041,14 @@ To preview filter rules specification, use the `filter` subcommand.
Feel free to clone and use in adherance to the [license](#license). Pull requests are very much welcome.
``` bash
```bash
git clone https://github.com/miraclx/freyr-js.git freyr
cd freyr
```
- If using [NPM](https://github.com/npm/cli):
``` bash
```bash
npm install
# to have access to the freyr command globally
@ -1047,7 +1057,7 @@ cd freyr
- If using [Yarn](https://github.com/yarnpkg/yarn):
``` bash
```bash
yarn install
# to have access to the freyr command globally
@ -1058,7 +1068,7 @@ cd freyr
The default provided [Dockerfile](https://github.com/miraclx/freyr-js/raw/master/Dockerfile) builds minimal alpine images. Average build network usage is ~ 80 MB and disk usage is ~ 180 MB.
``` bash
```bash
git clone https://github.com/miraclx/freyr-js.git freyr
cd freyr
docker build -t freyr-dev .
@ -1066,7 +1076,7 @@ docker build -t freyr-dev .
Afterwards, you can drop into the container by explicitly defining the entrypoint
``` bash
```bash
docker run -it --entrypoint bash freyr-dev
# Alternatively, create a handy alias
@ -1082,7 +1092,7 @@ Optionally, you can use these interesting flags to customize the experience.
The freyr source would be available in the `/freyr` directory within the container along with a globally registered command `freyr` for calling the script.
For more information and documentation about docker, please refer to its official website:
For more information and documentation about docker, please refer to its official site:
- <https://www.docker.com/>
- <https://docs.docker.com/>

View File

@ -51,7 +51,6 @@
},
"license": "Apache-2.0",
"dependencies": {
"@babel/eslint-parser": "^7.17.0",
"@miraclx/apple-music": "^0.4.0",
"async": "^3.2.0",
"axios": "^0.26.0",
@ -90,6 +89,7 @@
"yt-search": "^2.10.3"
},
"devDependencies": {
"@babel/eslint-parser": "^7.17.0",
"eslint": "8.9.0",
"eslint-plugin-prettier": "4.0.0",
"prettier": "2.5.1"

View File

@ -70,12 +70,14 @@ function initTest() {
console.log(parseBlock.parsed);
values.forEach(value => console.log(`[${value.toString().padStart(2)}] ${parseBlock.check(value)}`));
}
// jscpd:ignore-start
function test_time(spec, values) {
console.log('%j', spec);
const parseBlock = parseRange.time(spec);
console.log(parseBlock.parsed);
values.forEach(value => console.log(`[${value.toString().padStart(2)}] ${parseBlock.check(value)}`));
}
// jscpd:ignore-end
test_num(' ', [1, 2, 3]);
test_num('7 ', [6, 7, 8]);

View File

@ -290,10 +290,10 @@ class AppleMusic {
(await this.getArtist(uris)).albums.map(album => `apple_music:album:${album}`),
100,
store,
async (items, storefront) =>
Promise.mapSeries(
(await this.#store.core.albums.get(`?ids=${items.map(item => item.refID).join(',')}`, {storefront})).data,
album => this.wrapAlbumData(album),
(items, storefront) =>
this.getAlbum(
items.map(item => item.uri),
storefront,
),
);
}

View File

@ -20,6 +20,18 @@ class YouTubeSearchError extends Error {
}
}
function _getSearchArgs(artists, track, duration) {
if (typeof track === 'number') [track, duration] = [, track];
if (!Array.isArray(artists))
if (track && artists) artists = [artists];
else [artists, track] = [[], artists || track];
if (typeof track !== 'string') throw new Error('<track> must be a valid string');
if (artists.some(artist => typeof artist !== 'string'))
throw new Error('<artist>, if defined must be a valid array of strings');
if (duration && typeof duration !== 'number') throw new Error('<duration>, if defined must be a valid number');
return [artists, track, duration];
}
/**
* @typedef {(
* {
@ -276,14 +288,7 @@ class YouTubeMusic {
* @returns {YouTubeSearchResult} YouTubeMusicSearchResults
*/
async search(artists, track, duration) {
if (typeof track === 'number') [track, duration] = [, track];
if (!Array.isArray(artists))
if (track && artists) artists = [artists];
else [artists, track] = [[], artists || track];
if (typeof track !== 'string') throw new Error('<track> must be a valid string');
if (artists.some(artist => typeof artist !== 'string'))
throw new Error('<artist>, if defined must be a valid array of strings');
if (duration && typeof duration !== 'number') throw new Error('<duration>, if defined must be a valid number');
[artists, track, duration] = _getSearchArgs(artists, track, duration);
const results = await this.#search({query: [track, ...artists].join(' ')});
const strippedMeta = textUtils.stripText([...track.split(' '), ...artists]);
@ -384,14 +389,7 @@ class YouTube {
* @returns {YouTubeSearchResult} YouTubeSearchResults
*/
async search(artists, track, duration) {
if (typeof track === 'number') [track, duration] = [, track];
if (!Array.isArray(artists))
if (track && artists) artists = [artists];
else [artists, track] = [[], artists || track];
if (typeof track !== 'string') throw new Error('<track> must be a valid string');
if (artists.some(artist => typeof artist !== 'string'))
throw new Error('<artist>, if defined must be a valid array of strings');
if (duration && typeof duration !== 'number') throw new Error('<duration>, if defined must be a valid number');
[artists, track, duration] = _getSearchArgs(artists, track, duration);
const strippedArtists = textUtils.stripText(artists);
const strippedMeta = [...textUtils.stripText(track.split(' ')), ...strippedArtists];

View File

@ -182,8 +182,7 @@ class StackLogger {
* @param {...any} msgs Messages to write out
*/
error(...msgs) {
this._write(this.getText(this.#store.indent, msgs).concat('\n'), process.stderr, true);
return this.#store.autoTick ? this.tick(this.#store.indentSize) : this;
return this.warn(...msgs);
}
/**