This repository was archived by the owner on Aug 8, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathcopyright.js
More file actions
executable file
Β·159 lines (133 loc) Β· 5.43 KB
/
copyright.js
File metadata and controls
executable file
Β·159 lines (133 loc) Β· 5.43 KB
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
#!/usr/bin/env node
/* * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Copyright (c) 2017 Mobify Research & Development Inc. All rights reserved. */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * */
const glob = require('glob')
const fs = require('fs')
const path = require('path')
const red = '\x1b[31m'
const green = '\x1b[32m'
const yellow = '\x1b[33m'
const magenta = '\x1b[35m'
const cyan = '\x1b[36m'
const blackBG = '\x1b[40m'
const defaultBG = '\x1b[49m'
const defaultFG = '\x1b[39m'
const currentYear = new Date().getFullYear()
const langs = {}
let lintMode = true
let updateMode = false
let error = false
// we don't want to pass node and copyright.js directories to the glob
const args = process.argv.filter((arg) => {
return !/node|copyright/.test(arg)
})
/**
* getHeaderText - retrieve appropriate header file context from langs{} object
* @param {String} ext file extension of desired header file
* @return {String} content of appropriate header file
*/
const getHeaderText = (ext) => {
if (!langs[ext]) {
console.log(`${red}${blackBG}ERROR${defaultBG} - ${ext} is not supported (yet)`)
process.exit(1)
}
return langs[ext]
}
/**
* buildSupportedExtensions - initializes the langs{} object with the supported
* extensions, as well as their respective (c) header content
* @return {undefined} - populates the langs{} object
*/
const buildSupportedExtensions = () => {
const headerDir = path.join(__dirname, './headers')
fs
.readdirSync(headerDir)
.forEach((file) => {
const extension = file.match(/\.[0-9a-z]+$/i)[0]
const textPath = path.join(headerDir, file)
const content = fs
.readFileSync(textPath)
.toString()
.replace('year', currentYear)
langs[extension] = content
})
}
/**
* Removes extra \n characters from the top of any files
* to ensure more consistent spacing between copyright headers
* @param {String} content original file to edit
* @return {String} new file with no leading \n
*/
const removeLeadingNewlines = (content) => {
if (content[0] !== '') {
return content
}
content.shift()
return removeLeadingNewlines(content)
}
if (args.length === 0 || args.indexOf('--help') >= 0) {
console.log(`
Usage: node copyright.js [options] 'glob' ['additional globs']
If your glob is not targetting all nested directories, ensure that the glob string is wrapped in single quotes
Example:
${yellow}node copyright.js --fix${defaultFG} 'src/**/*.js'
Options:
--fix run in fix mode
--update update the year in existing headers
Visit ${cyan}https://github.com/mobify/mobify-code-style${defaultFG} to learn more.
`)
process.exit(0)
}
// Sets fix flag if the user provides --fix command line arg
if (args.indexOf('--fix') >= 0) {
args.splice(args.indexOf('--fix'), 1)
lintMode = false
}
if (args.indexOf('--update') >= 0) {
args.splice(args.indexOf('--update'), 1)
updateMode = true
}
buildSupportedExtensions()
args
.map((folder) => glob.sync(folder)) // build array of files matching glob pattern
.reduce((a, b) => a.concat(b)) // flatten array of arrays
.forEach((file) => {
const content = fs.readFileSync(file)
const hasCopyrightHeader = content.includes('Copyright (c)')
const ext = file.match(/\.[0-9a-z]+$/i)[0]
let newData = ''
if (hasCopyrightHeader && updateMode) {
let previousHeaderYear = content.toString().match(/(?:\(c\))(?:\s)(\d{4})/)[1]
if (previousHeaderYear !== currentYear.toString()) {
newData = content.toString().replace(`(c) ${previousHeaderYear}`, `(c) ${currentYear}`)
fs.writeFileSync(file, newData)
console.log(`${green}Copyright header succesfully updated from ${previousHeaderYear} to ${currentYear} in ${magenta}${file}`)
}
}
if (!hasCopyrightHeader) {
if (lintMode) {
console.log(`${yellow}${file} ${red}missing copyright header`)
error = true
} else {
let contentStr = content.toString().split('\n')
// accomodate for shebang and insert before header
if (contentStr[0].indexOf('#!') >= 0) {
const shebang = contentStr.shift()
contentStr = removeLeadingNewlines(contentStr).join('\n')
newData = shebang + '\n' + getHeaderText(ext) + '\n' + contentStr // eslint-disable-line prefer-template
} else {
contentStr = removeLeadingNewlines(contentStr).join('\n')
newData = getHeaderText(ext) + `\n${contentStr}` // eslint-disable-line prefer-template
}
fs.writeFileSync(file, newData)
console.log(`${green}Copyright header succesfully written into ${magenta}${file}`)
}
}
})
if (error) {
console.log(`${red}${blackBG}ERROR${defaultBG} - Some source files are missing copyright headers. Please run 'copyright --fix' on these files. Mobify projects are configured with an npm run task named 'copyright:fix' that you can use to do this.`)
process.exit(1)
} else {
console.log(`${cyan}Copyright headers are present in target files`)
}