@sequencemedia/music-library 1.0.2 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ . "$(dirname "$0")/_/husky.sh"
3
+
4
+ npm run post-commit
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ . "$(dirname "$0")/_/husky.sh"
3
+
4
+ npm run pre-commit
package/app.mjs CHANGED
@@ -22,6 +22,10 @@ const {
22
22
  }
23
23
  } = watch
24
24
 
25
+ const log = debug('@sequencemedia/music-library')
26
+
27
+ log('`music-library` is awake')
28
+
25
29
  const NAME = 'ml.App'
26
30
  process.title = NAME
27
31
 
@@ -48,28 +52,25 @@ async function app () {
48
52
  pid
49
53
  } = a.find(({ pid }) => pid !== PID)
50
54
 
51
- const log = debug('music-library:process:log')
55
+ const log = debug('@sequencemedia/music-library:process:log')
52
56
 
53
57
  log(`Killing application "${name}" in process ${pid}.`)
54
58
 
55
59
  process.kill(pid)
56
60
  }
57
61
  } catch ({ message }) {
58
- const error = debug('music-library:process:error')
62
+ const error = debug('@sequencemedia/music-library:process:error')
59
63
 
60
64
  error(message)
61
65
  return
62
66
  }
63
67
 
64
- const log = debug('@sequencemedia/music-library')
65
-
66
68
  const {
67
69
  pid,
68
70
  argv,
69
71
  env: {
70
- JAR,
71
- XML,
72
- DESTINATION
72
+ TRACKS = false,
73
+ PLAYLISTS = false
73
74
  }
74
75
  } = process
75
76
 
@@ -79,54 +80,69 @@ async function app () {
79
80
  version
80
81
  } = PACKAGE
81
82
 
82
- commander
83
- .version(version)
84
- .option('-j, --jar [jar]', 'Path to Saxon PE/EE JAR')
85
- .option('-x, --xml [xml]', 'Path to iTunes Library XML')
86
- .option('-d, --destination [destination]', 'Destination path for M3Us')
87
- .option('-t, --tracks', 'Parse all tracks')
88
- .option('-p, --playlists', 'Parse all playlists')
89
- .parse(argv)
83
+ try {
84
+ commander
85
+ .version(version)
86
+ .exitOverride()
87
+ .requiredOption('-j, --jar [jar]', 'Path to Saxon PE/EE JAR')
88
+ .requiredOption('-x, --xml [xml]', 'Path to iTunes Library XML')
89
+ .requiredOption('-d, --destination [destination]', 'Destination path for M3Us')
90
+ .option('-t, --tracks', 'Parse all tracks')
91
+ .option('-p, --playlists', 'Parse all playlists')
92
+ .parse(argv)
93
+ } catch (e) {
94
+ const {
95
+ code
96
+ } = e
97
+
98
+ const error = debug('@sequencemedia/music-library:commander:error')
99
+
100
+ if (code !== 'commander.missingMandatoryOptionValue') error(e)
101
+
102
+ error(`Halting application "${name}" in process ${pid}.`)
103
+ return
104
+ }
90
105
 
91
106
  const {
92
- jar = JAR,
93
- xml = XML,
94
- destination = DESTINATION,
95
- tracks: t = false,
96
- playlists: p = false
107
+ jar,
108
+ xml,
109
+ destination,
110
+ tracks: t = TRACKS,
111
+ playlists: p = PLAYLISTS
97
112
  } = commander.opts()
98
113
 
99
- const l = (
100
- (t && p) || (!t && !p)
101
- )
114
+ log({
115
+ jar,
116
+ xml,
117
+ destination
118
+ })
102
119
 
103
- if (l) {
104
- log(`Application "${name}" in process ${pid} watching Library.`)
120
+ try {
121
+ const l = (
122
+ (t && p) || (!t && !p)
123
+ )
105
124
 
106
- log({ jar, xml, destination })
125
+ if (l) {
126
+ log(`Application "${name}" in process ${pid} watching Library.`)
107
127
 
108
- return (
109
- library
110
- .toM3U(jar, xml, destination)
111
- )
112
- } else {
113
- if (t) {
114
- log(`Application "${name}" in process ${pid} watching Tracks.`)
115
-
116
- return (
117
- tracks
118
- .toM3U(jar, xml, destination)
119
- )
120
- }
128
+ await library.toM3U(jar, xml, destination)
129
+ } else {
130
+ if (t) {
131
+ log(`Application "${name}" in process ${pid} watching Tracks.`)
121
132
 
122
- if (p) {
123
- log(`Application "${name}" in process ${pid} watching Playlists.`)
133
+ await tracks.toM3U(jar, xml, destination)
134
+ } else {
135
+ if (p) {
136
+ log(`Application "${name}" in process ${pid} watching Playlists.`)
124
137
 
125
- return (
126
- playlists
127
- .toM3U(jar, xml, destination)
128
- )
138
+ await playlists.toM3U(jar, xml, destination)
139
+ }
140
+ }
129
141
  }
142
+ } catch ({ message }) {
143
+ const error = debug('@sequencemedia/music-library:error')
144
+
145
+ error(message)
130
146
  }
131
147
  }
132
148
 
@@ -0,0 +1,48 @@
1
+ import debug from 'debug'
2
+
3
+ import {
4
+ readFile
5
+ } from 'fs/promises'
6
+
7
+ import {
8
+ exec
9
+ } from 'child_process'
10
+
11
+ const OPTIONS = {
12
+ maxBuffer: 1024 * 500
13
+ }
14
+
15
+ const log = debug('@sequencemedia/music-library:build:gulp:post-commit')
16
+ const error = debug('@sequencemedia/music-library:build:gulp:post-commit:error')
17
+
18
+ log('`@sequencemedia/music-library` is awake')
19
+
20
+ export async function getPackageVersion () {
21
+ log('getPackageVersion')
22
+
23
+ const {
24
+ version = '0.0.0'
25
+ } = JSON.parse(await readFile('./package.json', 'utf8'))
26
+
27
+ return version
28
+ }
29
+
30
+ export function gitTag (a = '0.0.0', m = `v${a}`) {
31
+ log('gitTag')
32
+
33
+ return (
34
+ new Promise((resolve, reject) => {
35
+ exec(`git tag -a v${a} -m "${m}"`, OPTIONS, (e, v) => (!e) ? resolve(v) : reject(e))
36
+ })
37
+ )
38
+ }
39
+
40
+ export default async function postCommit () {
41
+ log('post-commit')
42
+
43
+ try {
44
+ await gitTag(await getPackageVersion())
45
+ } catch ({ code = 'NONE', message = 'No error message defined' }) {
46
+ error({ code, message })
47
+ }
48
+ }
@@ -0,0 +1,144 @@
1
+ import debug from 'debug'
2
+
3
+ import {
4
+ exec
5
+ } from 'child_process'
6
+
7
+ const log = debug('@sequencemedia/music-library:build:gulp:pre-commit')
8
+
9
+ log('`@sequencemedia/music-library` is awake')
10
+
11
+ const PACKAGE_VERSION_CHANGES = /\-+\s+"version":\s+"(\d+\.\d+\.\d+)",+\s+\++\s+"version":\s+"(\d+\.\d+\.\d+)",+\s+/ /* eslint-disable-line no-useless-escape */
12
+
13
+ const HAS_STAGED_CHANGES = /Changes to be committed/s
14
+
15
+ const NOT_STAGED_CHANGES = /Changes not staged for commit/s
16
+
17
+ const OPTIONS = {
18
+ maxBuffer: 1024 * 500
19
+ }
20
+
21
+ const BRANCH = 'master'
22
+
23
+ const trim = (v) => v.split('\n').map((v) => v.trimEnd()).join('\n').trim()
24
+
25
+ function use (key) {
26
+ const log = debug(`@sequencemedia/music-library:${key}`)
27
+
28
+ return function use (v) {
29
+ log(trim(v))
30
+ }
31
+ }
32
+
33
+ export function getGitRemoteShowOriginHeadBranch () {
34
+ log('getGitRemoteShowOriginHeadBranch')
35
+
36
+ return (
37
+ new Promise((resolve, reject) => {
38
+ const command = 'git remote show origin | awk \'/HEAD branch/ {print $NF}\''
39
+
40
+ const {
41
+ stdout,
42
+ stderr
43
+ } = exec(command, OPTIONS, (e, v = '') => (!e) ? resolve(trim(v)) : reject(e))
44
+
45
+ stdout.on('data', use('git-remote-show-origin-head-branch'))
46
+ stderr.on('data', use('git-remote-show-origin-head-branch'))
47
+ })
48
+ )
49
+ }
50
+
51
+ export function hasPackageVersionChanges (branch = BRANCH) {
52
+ log('hasPackageVersionChanges')
53
+
54
+ return (
55
+ new Promise((resolve, reject) => {
56
+ exec(`git diff HEAD origin/${branch} package.json`, OPTIONS, (e, v) => (!e) ? resolve(PACKAGE_VERSION_CHANGES.test(v)) : reject(e))
57
+ })
58
+ )
59
+ }
60
+
61
+ export function notPackageVersionChanges (branch = BRANCH) {
62
+ log('notPackageVersionChanges')
63
+
64
+ return (
65
+ new Promise((resolve, reject) => {
66
+ exec(`git diff HEAD origin/${branch} package.json`, OPTIONS, (e, v) => (!e) ? resolve(PACKAGE_VERSION_CHANGES.test(v) !== true) : reject(e))
67
+ })
68
+ )
69
+ }
70
+
71
+ export function hasStagedChanges () {
72
+ log('hasStagedChanges')
73
+
74
+ return (
75
+ new Promise((resolve, reject) => {
76
+ exec('git status', OPTIONS, (e, v) => (!e) ? resolve(HAS_STAGED_CHANGES.test(v)) : reject(e))
77
+ })
78
+ )
79
+ }
80
+
81
+ export function notStagedChanges () {
82
+ log('notStagedChanges')
83
+
84
+ return (
85
+ new Promise((resolve, reject) => {
86
+ exec('git status', OPTIONS, (e, v) => (!e) ? resolve(NOT_STAGED_CHANGES.test(v)) : reject(e))
87
+ })
88
+ )
89
+ }
90
+
91
+ export function notPushedChanges (branch = BRANCH) {
92
+ log('notPushedChanges')
93
+
94
+ return (
95
+ new Promise((resolve, reject) => {
96
+ exec(`git log origin/${branch}..HEAD`, OPTIONS, (e, v) => (!e) ? resolve(!!v) : reject(e))
97
+ })
98
+ )
99
+ }
100
+
101
+ export function patchPackageVersion () {
102
+ log('patchPackageVersion')
103
+
104
+ return (
105
+ new Promise((resolve, reject) => {
106
+ exec('npm version patch -m %s -n --no-git-tag-version --no-verify', OPTIONS, (e) => (!e) ? resolve() : reject(e))
107
+ })
108
+ )
109
+ }
110
+
111
+ export function addPackageVersionChanges () {
112
+ log('addPackageVersionChanges')
113
+
114
+ return (
115
+ new Promise((resolve, reject) => {
116
+ exec('git add package.json package-lock.json', OPTIONS, (e) => (!e) ? resolve() : reject(e))
117
+ })
118
+ )
119
+ }
120
+
121
+ export default async function preCommit () {
122
+ log('pre-commit')
123
+
124
+ try {
125
+ /**
126
+ * Not changes added, exit
127
+ */
128
+ if (await notStagedChanges()) return
129
+ /**
130
+ * Has changes added, continue
131
+ */
132
+ if (await hasStagedChanges()) {
133
+ /**
134
+ * Not package version changes, continue
135
+ */
136
+ if (await notPackageVersionChanges(await getGitRemoteShowOriginHeadBranch())) {
137
+ await patchPackageVersion()
138
+ await addPackageVersionChanges()
139
+ }
140
+ }
141
+ } catch ({ code = 'NONE', message = 'No error message defined' }) {
142
+ log({ code, message })
143
+ }
144
+ }
package/gulpfile.mjs ADDED
@@ -0,0 +1,13 @@
1
+ import gulp from 'gulp'
2
+
3
+ import preCommit from '#build/gulp/pre-commit'
4
+ import postCommit from '#build/gulp/post-commit'
5
+
6
+ gulp
7
+ .task('pre-commit', preCommit)
8
+
9
+ gulp
10
+ .task('post-commit', postCommit)
11
+
12
+ gulp
13
+ .task('default', gulp.series('pre-commit'))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sequencemedia/music-library",
3
- "version": "1.0.2",
3
+ "version": "1.0.6",
4
4
  "description": "Watch Apple Music Library XML and parse to JSON, JS, ES, or M3U",
5
5
  "keywords": [
6
6
  "music",
@@ -35,7 +35,11 @@
35
35
  "lint": "eslint . --ext .mjs --ext .cjs",
36
36
  "lint:fix": "npm run lint -- --fix",
37
37
  "start": "cross-env DEBUG=@sequencemedia/music-library,@sequencemedia/music-library:*,@sequencemedia/music-library-parser,@sequencemedia/music-library-parser:* NODE_ENV=production node .",
38
- "start:dev": "cross-env DEBUG=@sequencemedia/music-library,@sequencemedia/music-library:*,@sequencemedia/music-library-parser,@sequencemedia/music-library-parser:* NODE_ENV=development node ."
38
+ "dev": "cross-env DEBUG=@sequencemedia/music-library,@sequencemedia/music-library:*,@sequencemedia/music-library-parser,@sequencemedia/music-library-parser:* NODE_ENV=development node .",
39
+ "gulp": "gulp --color",
40
+ "pre-commit": "npm run lint && cross-env DEBUG=@sequencemedia/music-library,@sequencemedia/music-library:* npm run gulp -- pre-commit",
41
+ "post-commit": "cross-env DEBUG=@sequencemedia/music-library,@sequencemedia/music-library:* npm run gulp -- post-commit",
42
+ "prepare": "husky install"
39
43
  },
40
44
  "dependencies": {
41
45
  "@sequencemedia/music-library-parser": "1.0.2",
@@ -57,21 +61,27 @@
57
61
  "core-js": "^3.20.1",
58
62
  "eslint": "7.32.0",
59
63
  "eslint-config-standard": "^16.0.3",
60
- "eslint-import-resolver-babel-module": "^5.3.1",
61
64
  "eslint-plugin-import": "^2.25.3",
62
65
  "eslint-plugin-node": "^11.1.0",
63
66
  "eslint-plugin-promise": "5.2.0",
64
- "rimraf": "^3.0.2"
67
+ "gulp": "^4.0.2",
68
+ "husky": "^7.0.4"
65
69
  },
66
70
  "imports": {
67
71
  "#music-library/common/normalise": "./src/common/normalise.mjs",
68
72
  "#music-library/library": "./src/library/index.mjs",
73
+ "#music-library/library/transform": "./src/library/transform/index.mjs",
74
+ "#music-library/library/playlists": "./src/library/playlists/index.mjs",
75
+ "#music-library/library/playlists/transform": "./src/library/playlists/transform/index.mjs",
76
+ "#music-library/library/tracks": "./src/library/tracks/index.mjs",
77
+ "#music-library/library/tracks/transform": "./src/library/tracks/transform/index.mjs",
69
78
  "#music-library/watch": "./src/watch/index.mjs",
70
79
  "#music-library/watch/library": "./src/watch/library/index.mjs",
71
80
  "#music-library/watch/library/transform": "./src/watch/library/transform/index.mjs",
72
81
  "#music-library/watch/library/playlists": "./src/watch/library/playlists/index.mjs",
73
82
  "#music-library/watch/library/playlists/transform": "./src/watch/library/playlists/transform/index.mjs",
74
83
  "#music-library/watch/library/tracks": "./src/watch/library/tracks/index.mjs",
75
- "#music-library/watch/library/tracks/transform": "./src/watch/library/tracks/transform/index.mjs"
84
+ "#music-library/watch/library/tracks/transform": "./src/watch/library/tracks/transform/index.mjs",
85
+ "#build/gulp/*": "./build/gulp/*.mjs"
76
86
  }
77
87
  }
@@ -2,8 +2,10 @@ import {
2
2
  homedir
3
3
  } from 'os'
4
4
 
5
- import path from 'path'
5
+ import {
6
+ resolve
7
+ } from 'path'
6
8
 
7
- const normalise = (p) => path.resolve(p.trim().replace(/^~/, homedir()))
9
+ const normalise = (p = '') => resolve(String(p).trim().replace(/^~/, homedir()))
8
10
 
9
11
  export default normalise
@@ -1,6 +1,6 @@
1
1
  import debug from 'debug'
2
2
 
3
- import * as musicLibraryParser from '@sequencemedia/music-library-parser'
3
+ import musicLibraryParser from '@sequencemedia/music-library-parser'
4
4
 
5
5
  import normalise from '#music-library/common/normalise'
6
6
 
@@ -1,6 +1,6 @@
1
1
  import debug from 'debug'
2
2
 
3
- import * as musicLibraryParser from '@sequencemedia/music-library-parser'
3
+ import musicLibraryParser from '@sequencemedia/music-library-parser'
4
4
 
5
5
  import normalise from '#music-library/common/normalise'
6
6
 
@@ -34,4 +34,4 @@ export async function toM3U (jar, xml, destination) {
34
34
  }
35
35
  }
36
36
 
37
- export * as transform from './transform'
37
+ export * as transform from '#music-library/library/playlists/transform'
@@ -1,6 +1,6 @@
1
1
  import debug from 'debug'
2
2
 
3
- import * as musicLibraryParser from '@sequencemedia/music-library-parser'
3
+ import musicLibraryParser from '@sequencemedia/music-library-parser'
4
4
 
5
5
  import normalise from '#music-library/common/normalise'
6
6
 
@@ -1,6 +1,6 @@
1
1
  import debug from 'debug'
2
2
 
3
- import * as musicLibraryParser from '@sequencemedia/music-library-parser'
3
+ import musicLibraryParser from '@sequencemedia/music-library-parser'
4
4
 
5
5
  import normalise from '#music-library/common/normalise'
6
6
 
@@ -34,4 +34,4 @@ export async function toM3U (jar, xml, destination) {
34
34
  }
35
35
  }
36
36
 
37
- export * as transform from './transform'
37
+ export * as transform from '#music-library/library/tracks/transform'
@@ -1,6 +1,6 @@
1
1
  import debug from 'debug'
2
2
 
3
- import * as musicLibraryParser from '@sequencemedia/music-library-parser'
3
+ import musicLibraryParser from '@sequencemedia/music-library-parser'
4
4
 
5
5
  import normalise from '#music-library/common/normalise'
6
6
 
@@ -1,6 +1,6 @@
1
1
  import debug from 'debug'
2
2
 
3
- import * as musicLibraryParser from '@sequencemedia/music-library-parser'
3
+ import musicLibraryParser from '@sequencemedia/music-library-parser'
4
4
 
5
5
  import normalise from '#music-library/common/normalise'
6
6