Repository navigation
Expand file tree
/
Copy pathinstall.js
More file actions
158 lines (137 loc) · 5.39 KB
/
Copy pathinstall.js
File metadata and controls
158 lines (137 loc) · 5.39 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
#!/usr/bin/env node
const fs = require('fs-extra')
const path = require('path')
/**
* Installation script for core-book-modules
* Syncs folders to the parent package and creates .gitignore files
*/
// Folders to sync to parent package.
// The shared _sass folder ships only the common `template` styles; each parent
// keeps its book-specific `theme` styles in `_sass-custom/theme`.
const FOLDERS_TO_SYNC = ['_tools', '_webpack', '_docs', '_app', '_sass', '_includes']
let moduleRoot
let parentRoot
async function install () {
const logMessages = []
function log (message, level) {
// Only collect error messages for log file
if (level === 'error') {
const timestamp = new Date().toISOString()
const logEntry = `[${timestamp}] ${level.toUpperCase()}: ${message}`
logMessages.push(logEntry)
console.error(message)
}
}
try {
// Get the path to the parent package (where this package is installed)
moduleRoot = __dirname
parentRoot = path.resolve(moduleRoot, '../../..')
// Skip syncing when this package is not installed as a dependency
// (e.g. developing the repo itself). Dependency installs live under
// node_modules (npm/pnpm) or .yalc (yalc); without either ancestor the
// parent-root fallback resolves to the drive root, which is not writable.
if (!moduleRoot.includes('node_modules') && !moduleRoot.includes('.yalc')) {
console.log('core-book-modules: not installed as a dependency; skipping module sync.')
return
}
// Standard npm install: node_modules/@electricbookworks/core-book-modules
if (moduleRoot.includes('node_modules')) {
// Find the node_modules directory and get the project root
const nodeModulesIndex = moduleRoot.lastIndexOf('node_modules')
if (nodeModulesIndex !== -1) {
parentRoot = moduleRoot.substring(0, nodeModulesIndex - 1) // Remove trailing slash before node_modules
}
}
// Validate parent root exists and is writable
if (!await fs.pathExists(parentRoot)) {
const errorMsg = `Parent directory does not exist: ${parentRoot}`
log(errorMsg, 'error')
process.exit(1)
}
try {
await fs.access(parentRoot, fs.constants.W_OK)
} catch (accessError) {
const errorMsg = `No write permission to parent directory: ${parentRoot}`
log(errorMsg, 'error')
process.exit(1)
}
for (const folder of FOLDERS_TO_SYNC) {
try {
// Source and destination paths
const sourcePath = path.join(moduleRoot, folder)
const destPath = path.join(parentRoot, folder)
const gitignorePath = path.join(destPath, '.gitignore')
// Check if source folder exists
if (!await fs.pathExists(sourcePath)) {
continue // Skip this folder but continue with others
}
// Empty the destination folder before copying
if (await fs.pathExists(destPath)) {
await fs.emptyDir(destPath)
}
// Copy the folder
await fs.copy(sourcePath, destPath, {
overwrite: true,
preserveTimestamps: true,
errorOnExist: false
})
// Create .gitignore file in the copied folder
const gitignoreContent = `# Electric Book ${folder}
# This folder is managed by @electricbookworks/core-book-modules
# Do not track any files in this folder
*
!.gitignore
`
await fs.writeFile(gitignorePath, gitignoreContent, 'utf8')
} catch (folderError) {
log(`Error processing ${folder}: ${folderError.message}`, 'error')
// Continue with other folders instead of exiting
}
}
// Sync custom folders from parent (e.g. _tools-custom -> _tools,
// or _sass-custom/theme -> _sass/theme)
for (const folder of FOLDERS_TO_SYNC) {
try {
const customFolderPath = path.join(parentRoot, `${folder}-custom`)
const folderDestPath = path.join(parentRoot, folder)
if (await fs.pathExists(customFolderPath)) {
await fs.copy(customFolderPath, folderDestPath, {
overwrite: true,
preserveTimestamps: true,
errorOnExist: false
})
}
} catch (customError) {
log(`Error syncing ${folder}-custom: ${customError.message}`, 'error')
}
}
// Create gulpfile.js in parent root
try {
const gulpfilePath = path.join(parentRoot, 'gulpfile.js')
const gulpfileContent = 'module.exports = require(\'./_tools/gulpfile\')\n'
await fs.writeFile(gulpfilePath, gulpfileContent, 'utf8')
} catch (gulpfileError) {
log(`Error creating gulpfile.js: ${gulpfileError.message}`, 'error')
}
if (logMessages.length > 0) {
const logPath = path.join(parentRoot, 'core-book-modules-install.log')
await fs.writeFile(logPath, logMessages.join('\n'), 'utf8')
}
} catch (error) {
const errorMsg = `Error during installation: ${error.message}`
try {
const logPath = path.join(parentRoot, 'core-book-modules-install.log')
logMessages.push(`[${new Date().toISOString()}] ERROR: ${errorMsg}`)
await fs.writeFile(logPath, logMessages.join('\n'), 'utf8')
} catch (logError) {
// If we can't write the log, at least show the original error
console.error('Failed to write log file:', logError.message)
}
process.exit(1)
}
}
// Run the installation if this script is executed directly
if (require.main === module) {
install()
}
module.exports = install