From f46da40145f7a28eacce793d600258c59a9aed69 Mon Sep 17 00:00:00 2001 From: Erik Golinelli Date: Fri, 1 Dec 2023 22:26:38 +0100 Subject: [PATCH 1/7] WIP - Adding init command Refactor code to pass command line arguments to getConfig This change better organizes command line argument handling, by moving it from 'lib/utils.js' to 'lib/index.js'. This allows us to remove the dependence of the 'lib/utils.js' module on the 'yargs' package. This transition to explicitly pass command line arguments to the getConfig function enhances modularity and the cleanliness of our codebase. Moreover, similar changes were made to tests to reflect this change. Furthermore, we started to export WordPressInstaller using module.exports for consistency. --- lib/index.js | 40 +++++++++++++++++++--------- lib/init.js | 64 +++++++++++++++++++++++++++++++++++++++++++++ lib/install.js | 2 +- lib/utils.js | 6 ++--- tests/utils.test.js | 5 +++- 5 files changed, 99 insertions(+), 18 deletions(-) create mode 100644 lib/init.js diff --git a/lib/index.js b/lib/index.js index aaff857..6b185a6 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,24 +1,40 @@ #!/usr/bin/env node const { getConfig } = require('./utils'); const { WordPressInstaller } = require('./install'); +const WordPressConfigInitializer = require('./init.js'); -const config = getConfig(); +const yargs = require('yargs'); +const { hideBin } = require('yargs/helpers'); -// Install WordPress -const installer = new WordPressInstaller(config); +// Get the arguments from the command line +const argv = yargs(hideBin(process.argv)).argv; + +// Get the config +const config = getConfig(argv); // Start the timer const startTime = Date.now(); -installer.run().then(() => { - console.log('๐Ÿš€ WordPress installed successfully.'); +if (argv.init === true) { + const initializer = new WordPressConfigInitializer(this); + initializer.init().then(() => { + process.exit(0); + }); +} else { + // Install WordPress + const installer = new WordPressInstaller(config); + + installer.run().then(() => { + console.log('๐Ÿš€ WordPress installed successfully.'); + + // End the timer + const endTime = Date.now(); - // End the timer - const endTime = Date.now(); + // Calculate the time passed + const timePassed = endTime - startTime; + console.log(`๐Ÿ•’ Time passed: ${timePassed} milliseconds`); - // Calculate the time passed - const timePassed = endTime - startTime; - console.log(`๐Ÿ•’ Time passed: ${timePassed} milliseconds`); + process.exit(0); + }); +} - process.exit(0); -}); diff --git a/lib/init.js b/lib/init.js new file mode 100644 index 0000000..8c227fd --- /dev/null +++ b/lib/init.js @@ -0,0 +1,64 @@ +const fs = require('fs'); +const path = require('path'); + +class init { + constructor (installer) { + this.installer = installer; + this.themeFolder = installer.themeFolder; + this.pluginsFolder = installer.pluginsFolder; + } + + init () { + const themes = this.scanDirectory(this.themeFolder); + const plugins = this.scanDirectory(this.pluginsFolder); + + const result = { + name: this.installer.config.name, + wordpress: this.installer.config.wordpress, + themes, + plugins, + postInstall: [] + }; + + const outputPath = path.join(process.cwd(), 'wp-config.json'); + + fs.writeFileSync(outputPath, JSON.stringify(result, null, 2)); + console.log(`๐Ÿ†— Initialization completed. Configuration saved to ${outputPath}`); + } + + scanDirectory (directory) { + const items = fs.readdirSync(directory); + const result = []; + + for (const item of items) { + const fullPath = path.join(directory, item); + + if (fs.statSync(fullPath).isDirectory()) { + const stylePath = path.join(fullPath, 'style.css'); + if (fs.existsSync(stylePath)) { + const version = this.extractVersionFromStyleFile(stylePath); + result.push({ name: item, version }); + } + } else if (item.endsWith('.php')) { + const version = this.extractVersionFromPHPFile(fullPath); + result.push({ name: item, version }); + } + } + + return result; + } + + extractVersionFromStyleFile (filePath) { + const content = fs.readFileSync(filePath, 'utf8'); + const match = /Version:\s*([\d.]+)/i.exec(content); + return match ? match[1] : null; + } + + extractVersionFromPHPFile (filePath) { + const content = fs.readFileSync(filePath, 'utf8'); + const match = /Version:\s*([\d.]+)/i.exec(content); + return match ? match[1] : null; + } +} + +module.exports = init; diff --git a/lib/install.js b/lib/install.js index 8f5639c..9b9b0ad 100644 --- a/lib/install.js +++ b/lib/install.js @@ -101,4 +101,4 @@ class WordPressInstaller { } } -exports.WordPressInstaller = WordPressInstaller; +module.exports = WordPressInstaller; diff --git a/lib/utils.js b/lib/utils.js index 06c13da..d7b8868 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -3,8 +3,6 @@ const fs = require('fs'); const { exec } = require('node:child_process'); const extract = require('extract-zip'); const https = require('node:https'); -const yargs = require('yargs'); -const { hideBin } = require('yargs/helpers'); /** * Reads wp-package.json from the root folder and extracts the value of the --template option or uses the default. @@ -12,13 +10,13 @@ const { hideBin } = require('yargs/helpers'); * * @return {Object} The configuration object. */ -function getConfig () { +function getConfig (args) { // Read wp-package.json from the root folder const defaultConfigFile = path.join(process.cwd(), 'wp-package.json'); const defaultConfig = fs.existsSync(defaultConfigFile) ? JSON.parse(fs.readFileSync(defaultConfigFile, 'utf8')) : {}; // Extract the value of the --template option or use the default - const templatePath = yargs(hideBin(process.argv)).argv.template || 'wp-package.json'; + const templatePath = args.template || 'wp-package.json'; // The default config is used if no template is provided let config = defaultConfig; diff --git a/tests/utils.test.js b/tests/utils.test.js index 9fbf058..5b8323a 100644 --- a/tests/utils.test.js +++ b/tests/utils.test.js @@ -3,10 +3,13 @@ const defaultConfig = 'wp-package.json'; describe('getConfig', () => { it('should read wp-package.json from the root folder and return the default configuration if the file does not exist', () => { + const argv = {}; // Call the function - const config = getConfig(); + const config = getConfig(argv); // Assert the result expect(config).toBeInstanceOf(Object); + expect(config.name).toBe('wordpress'); + expect(config.plugins).toHaveLength(0); }); }); From cba218609dd83f9bc70112c267615a34716f01de Mon Sep 17 00:00:00 2001 From: Erik Golinelli Date: Sat, 2 Dec 2023 13:59:18 +0100 Subject: [PATCH 2/7] Add WordPress configuration dump tool Added new file `dump.js` for creating and saving a JSON dump of a WordPress configuration. This includes information about the WordPress version, installed themes and plugins. The dumped configuration is saved in a `wp-package.json` file in the root directory. This feature enables the user to easily retrieve and check the details of their WordPress configuration. --- lib/dump.js | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 lib/dump.js diff --git a/lib/dump.js b/lib/dump.js new file mode 100644 index 0000000..89140e6 --- /dev/null +++ b/lib/dump.js @@ -0,0 +1,92 @@ +const fs = require('fs'); +const path = require('path'); +const { geVarFromPHPFile } = require('./utils'); + +class dump { + constructor () { + this.wpFolder = process.cwd(); + this.themeFolder = path.join(this.wpFolder, 'wp-content', 'themes'); + this.pluginsFolder = path.join(this.wpFolder, 'wp-content', 'plugins'); + } + + init () { + console.log(this.wpFolder); + console.log(this.themeFolder); + const themes = this.scanDirectory(this.themeFolder); + const plugins = this.scanDirectory(this.pluginsFolder); + + // the website name + const name = path.basename(this.wpFolder); + + // get the WordPress version from wp-includes/version.php + const versionFile = path.join(this.wpFolder, 'wp-includes', 'version.php'); + const versionFileContent = fs.readFileSync(versionFile, 'utf8'); + const version = geVarFromPHPFile(versionFileContent, 'wp_version'); + + const language = Intl.DateTimeFormat().resolvedOptions().locale; + + const result = { + name, + wordpress: { + version, + language + }, + themes, + plugins + }; + + const outputPath = path.join(process.cwd(), 'wp-package.json'); + + fs.writeFileSync(outputPath, JSON.stringify(result, null, 2)); + console.log(`๐Ÿ†— Wordpress configuration Dump completed. Configuration saved to ${outputPath}`); + } + + scanDirectory (directory) { + const items = fs.readdirSync(directory); + const result = []; + + for (const item of items) { + const fullPath = path.join(directory, item); + console.log(`๐Ÿ”๏ธ Scanning ${fullPath}`); + const isDirectory = fs.statSync(fullPath).isDirectory(); + + if (isDirectory) { + const stylePath = path.join(fullPath, 'style.css'); + const themeFile = path.join(fullPath, `${item}.php`); + const pluginFile = `${item}.php`; // ie: 'hello-dolly.php' + + if (fs.existsSync(stylePath)) { + const version = this.extractVersionFromStyleFile(stylePath); + if (version) { + console.log(`โ„น๏ธ Found ${item} version ${version}`); + result.push({ name: item, version }); + } + } + + if (fs.existsSync(themeFile) || fs.existsSync(pluginFile)) { + const version = this.extractVersionFromPHPFile(themeFile) || this.extractVersionFromPHPFile(pluginFile); + if (version) { + console.log(`โ„น๏ธ Found ${item} version ${version}`); + result.push({ name: item, version }); + } + } + } + } + + return result; + } + + extractVersionFromStyleFile (filePath) { + const content = fs.readFileSync(filePath, 'utf8'); + const match = /Version:\s*([\d.]+)/i.exec(content); + return match ? match[1] : null; + } + + extractVersionFromPHPFile (filePath) { + const content = fs.readFileSync(filePath, 'utf8'); + const match = /Version:\s*([\d.]+)/i.exec(content); + return match ? match[1] : null; + } +} + +module.exports = dump; From d3ce1299c8acf188e509df4a8a2e0249740b0e21 Mon Sep 17 00:00:00 2001 From: Erik Golinelli Date: Sat, 2 Dec 2023 14:00:16 +0100 Subject: [PATCH 3/7] Refactor init.js for WordPress setup configuration Refactored the `init.js` file for a simplified setup process of WordPress projects. Renamed `init` class to `Initialize` and replaced `installer` parameter with `options` to allow custom configuration during construction. Modified `init` method to `generateConfig` to better reflect its functionality. Also added default WordPress configuration options and added error handling for pre-existing configuration files. This change provides more flexibility in project setup, easier adaptation for different environments, and a standardized way to setup WordPress configuration. --- lib/init.js | 92 +++++++++++++++++++++++++---------------------------- 1 file changed, 43 insertions(+), 49 deletions(-) diff --git a/lib/init.js b/lib/init.js index 8c227fd..3965e4a 100644 --- a/lib/init.js +++ b/lib/init.js @@ -1,64 +1,58 @@ const fs = require('fs'); const path = require('path'); -class init { - constructor (installer) { - this.installer = installer; - this.themeFolder = installer.themeFolder; - this.pluginsFolder = installer.pluginsFolder; +class Initialize { + constructor (options) { + this.options = options || {}; + this.wpFolder = process.cwd(); + this.outputPath = path.join(this.wpFolder, 'wp-package.json'); } - init () { - const themes = this.scanDirectory(this.themeFolder); - const plugins = this.scanDirectory(this.pluginsFolder); + generateConfig () { + const name = this.options.name || 'wordpress'; + const language = this.options.language || 'en_US'; + const version = this.options.version || '6.4.1'; + + const defaultConfig = { + DB_NAME: 'my_db_name', + DB_USER: 'my_username', + DB_PASSWORD: 'my_password', + DB_HOST: '127.0.0.1', + DB_CHARSET: 'utf8', + DB_COLLATE: '', + table_prefix: 'wp_', + WP_DEBUG: true, + WP_SITEURL: 'http://example.com', + WP_HOME: 'http://example.com', + WP_CONTENT_DIR: '/path/to/custom/content', + WP_CONTENT_URL: 'http://example.com/custom/content', + DISALLOW_FILE_EDIT: true + }; + + const customConfig = this.options.config || {}; const result = { - name: this.installer.config.name, - wordpress: this.installer.config.wordpress, - themes, - plugins, + name, + wordpress: { + version, + language, + config: { ...defaultConfig, ...customConfig } + }, + themes: [], + plugins: [], postInstall: [] }; - const outputPath = path.join(process.cwd(), 'wp-config.json'); - - fs.writeFileSync(outputPath, JSON.stringify(result, null, 2)); - console.log(`๐Ÿ†— Initialization completed. Configuration saved to ${outputPath}`); - } - - scanDirectory (directory) { - const items = fs.readdirSync(directory); - const result = []; - - for (const item of items) { - const fullPath = path.join(directory, item); - - if (fs.statSync(fullPath).isDirectory()) { - const stylePath = path.join(fullPath, 'style.css'); - if (fs.existsSync(stylePath)) { - const version = this.extractVersionFromStyleFile(stylePath); - result.push({ name: item, version }); - } - } else if (item.endsWith('.php')) { - const version = this.extractVersionFromPHPFile(fullPath); - result.push({ name: item, version }); - } + // check if the output path exists + if (fs.existsSync(this.outputPath)) { + console.error(`๐Ÿ”ด The configuration file ${this.outputPath} already exists.`); + return; } - return result; - } - - extractVersionFromStyleFile (filePath) { - const content = fs.readFileSync(filePath, 'utf8'); - const match = /Version:\s*([\d.]+)/i.exec(content); - return match ? match[1] : null; - } - - extractVersionFromPHPFile (filePath) { - const content = fs.readFileSync(filePath, 'utf8'); - const match = /Version:\s*([\d.]+)/i.exec(content); - return match ? match[1] : null; + // write the config to the output path + fs.writeFileSync(this.outputPath, JSON.stringify(result, null, 2)); + console.log(`๐Ÿ†— Wordpress configuration file created. Configuration saved to ${this.outputPath}`); } } -module.exports = init; +module.exports = Initialize; From be169ccfa5a7e2681db61621bc67be5e6231adc5 Mon Sep 17 00:00:00 2001 From: Erik Golinelli Date: Sat, 2 Dec 2023 14:00:39 +0100 Subject: [PATCH 4/7] Add utility functions for file system operations Introduced new module fs.js with multiple utility functions to handle file system operations such as creating directories, renaming folders, downloading files, and extracting zip files. These operations are essential for various process like setting up environments, downloading dependencies or cleaning up temporary files. --- lib/fs.js | 128 ++++++++++++++++++++++++++++++++++++++++++ lib/utils.js | 155 ++++++++++----------------------------------------- 2 files changed, 158 insertions(+), 125 deletions(-) create mode 100644 lib/fs.js diff --git a/lib/fs.js b/lib/fs.js new file mode 100644 index 0000000..458369b --- /dev/null +++ b/lib/fs.js @@ -0,0 +1,128 @@ +const fs = require('fs'); +const https = require('node:https'); +const extract = require('extract-zip'); + +/** + * Create a temporary directory if it does not already exist. + */ +function makeDir (dirpath) { + if (!fs.existsSync(dirpath)) { + fs.mkdirSync(dirpath, { recursive: true }); + } +} + +/** + * Asynchronously cleans up a temporary directory. + * + * @param {string} dir - The path to the temporary directory. + * @return {void} A promise that resolves when the cleanup is complete. + */ +async function cleanup (dir) { + try { + fs.rmSync(dir, { recursive: true }); + console.log(`๐Ÿงน ${dir} removed successfully.`); + } catch (err) { + // File deletion failed + console.error(err.message); + } +} + +/** + * Renames a folder from the old path to the new path. + * + * @param {string} oldPath - The path of the folder to be renamed. + * @param {string} newPath - The new path of the folder. + */ +function renameFolder (oldPath, newPath) { + fs.renameSync(oldPath, newPath); +} + +/** + * Downloads a file from the specified URL and saves it to the target file. + * + * @param {string} url - The URL of the file to download. + * @param {string} targetFile - The file path where the downloaded file will be saved. + * @return {Promise} A promise that resolves when the file is successfully downloaded and saved, or rejects with an error if there was an issue. + */ +async function downloadFile (url, targetFile) { + if (fs.existsSync(targetFile)) { + console.log(`โ„น๏ธ ${targetFile} already exists. Skipping download.`); + return; + } + try { + return await new Promise((resolve, reject) => { + https.get( + url, + { headers: { 'User-Agent': 'nodejs' } }, + async (response) => { + const code = response.statusCode ?? 0; + + if (code >= 400) { + return reject(new Error(response.statusMessage)); + } + + if (code > 300 && code < 400 && !!response.headers.location) { + return resolve(await downloadFile(response.headers.location, targetFile)); + } + + const fileWriter = fs.createWriteStream(targetFile).on('finish', () => { + resolve({}); + }); + + response.pipe(fileWriter); + }).on('error', (error) => { + reject(error); + }); + }); + } catch (error) { + throw new Error(error); + } +} + +/** + * Extracts a zip file to a target directory. + * + * @param {string} zipFilePath - The path of the zip file to extract. + * @param {string} targetDirectory - The directory to extract the zip file to. + * @return {Promise} Returns true if the extraction is successful, false otherwise. + */ +async function extractZip (zipFilePath, targetDirectory) { + let commonRootPath; // Variable to store the common root path + + try { + await extract(zipFilePath, { + dir: targetDirectory, + onEntry: (entry) => { + const entryPathParts = entry.fileName.split('/'); + + if (!commonRootPath) { + // Initialize the common root path with the first entry + commonRootPath = entryPathParts[0]; + } else { + // Update the common root path based on the current entry + for (let i = 0; i < entryPathParts.length; i++) { + if (commonRootPath.split('/')[i] !== entryPathParts[i]) { + commonRootPath = commonRootPath.split('/').slice(0, i).join('/'); + break; + } + } + } + } + }); + + // Return the root folder name + console.log(`๐Ÿ“‚ Extracted to ${commonRootPath}`); + return commonRootPath; + } catch (err) { + console.error(`๐Ÿ“› Error extracting ${zipFilePath} zip: ${err}`); + return err; + } +} + +module.exports = { + makeDir, + cleanup, + renameFolder, + downloadFile, + extractZip +}; diff --git a/lib/utils.js b/lib/utils.js index d7b8868..e3da6f5 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,8 +1,24 @@ const path = require('path'); const fs = require('fs'); const { exec } = require('node:child_process'); -const extract = require('extract-zip'); -const https = require('node:https'); + +/** + * Reads a PHP file, extracts, and returns the WordPress version number. + * + * @param {string} fileContent - Path to the PHP file to read + * @param variableName - The name of the variable to search adn replace + * @return {string|null} WordPress version number or null if not found or in case of an error + */ +function geVarFromPHPFile (fileContent, variableName = '$wp_version') { + // Define a regular expression to match the variableName and its value with both the single and double quotes + const versionRegex = new RegExp(`${variableName}\\s*=\\s*['"]([^'"]+)['"]`, 'g'); + + // Use the regular expression to extract the version number + const match = fileContent.match(versionRegex); + + // Return the version number or null if not found + return match ? match[1] : null; +} /** * Reads wp-package.json from the root folder and extracts the value of the --template option or uses the default. @@ -32,41 +48,6 @@ function getConfig (args) { return config; } -/** - * Create a temporary directory if it does not already exist. - */ -function makeDir (dirpath) { - if (!fs.existsSync(dirpath)) { - fs.mkdirSync(dirpath, { recursive: true }); - } -} - -/** - * Asynchronously cleans up a temporary directory. - * - * @param {string} dir - The path to the temporary directory. - * @return {void} A promise that resolves when the cleanup is complete. - */ -async function cleanup (dir) { - try { - fs.rmSync(dir, { recursive: true }); - console.log(`๐Ÿงน ${dir} removed successfully.`); - } catch (err) { - // File deletion failed - console.error(err.message); - } -} - -/** - * Renames a folder from the old path to the new path. - * - * @param {string} oldPath - The path of the folder to be renamed. - * @param {string} newPath - The new path of the folder. - */ -function renameFolder (oldPath, newPath) { - fs.renameSync(oldPath, newPath); -} - /** * Generates the download URL for a specific version of WordPress. * @@ -104,88 +85,6 @@ function getDownloadUrl (packageName, packageVersion, type) { return `https://downloads.wordpress.org/${type}/${packageName}.zip`; } -/** - * Downloads a file from the specified URL and saves it to the target file. - * - * @param {string} url - The URL of the file to download. - * @param {string} targetFile - The file path where the downloaded file will be saved. - * @return {Promise} A promise that resolves when the file is successfully downloaded and saved, or rejects with an error if there was an issue. - */ -async function downloadFile (url, targetFile) { - if (fs.existsSync(targetFile)) { - console.log(`โ„น๏ธ ${targetFile} already exists. Skipping download.`); - return; - } - try { - return await new Promise((resolve, reject) => { - https.get( - url, - { headers: { 'User-Agent': 'nodejs' } }, - async (response) => { - const code = response.statusCode ?? 0; - - if (code >= 400) { - return reject(new Error(response.statusMessage)); - } - - if (code > 300 && code < 400 && !!response.headers.location) { - return resolve(await downloadFile(response.headers.location, targetFile)); - } - - const fileWriter = fs.createWriteStream(targetFile).on('finish', () => { - resolve({}); - }); - - response.pipe(fileWriter); - }).on('error', (error) => { - reject(error); - }); - }); - } catch (error) { - throw new Error(error); - } -} - -/** - * Extracts a zip file to a target directory. - * - * @param {string} zipFilePath - The path of the zip file to extract. - * @param {string} targetDirectory - The directory to extract the zip file to. - * @return {Promise} Returns true if the extraction is successful, false otherwise. - */ -async function extractZip (zipFilePath, targetDirectory) { - let commonRootPath; // Variable to store the common root path - - try { - await extract(zipFilePath, { - dir: targetDirectory, - onEntry: (entry) => { - const entryPathParts = entry.fileName.split('/'); - - if (!commonRootPath) { - // Initialize the common root path with the first entry - commonRootPath = entryPathParts[0]; - } else { - // Update the common root path based on the current entry - for (let i = 0; i < entryPathParts.length; i++) { - if (commonRootPath.split('/')[i] !== entryPathParts[i]) { - commonRootPath = commonRootPath.split('/').slice(0, i).join('/'); - break; - } - } - } - } - }); - - // Return the root folder name - console.log(`๐Ÿ“‚ Extracted to ${commonRootPath}`); - return commonRootPath; - } catch (err) { - console.error(`๐Ÿ“› Error extracting ${zipFilePath} zip: ${err}`); - return err; - } -} - /** * Installs npm packages in the specified package directory. * @@ -300,20 +199,26 @@ async function isWPCLIAvailable () { } } +function printTimePassed (startTime) { + // End the timer + const endTime = Date.now(); + + // Calculate the time passed + const timePassed = endTime - startTime; + console.log(`๐Ÿ•’ Time passed: ${timePassed} milliseconds`); +} + module.exports = { + geVarFromPHPFile, getConfig, - makeDir, - cleanup, - renameFolder, - downloadFile, getWordPressDownloadUrl, getDownloadUrl, - extractZip, installNpmPackages, installComposer, replaceDbConstant, replaceDbConstantBool, generateSalt, replaceEmptySalts, - isWPCLIAvailable + isWPCLIAvailable, + printTimePassed }; From 1e15f2a41304bfd55f0de9f2291187079ed8b9b4 Mon Sep 17 00:00:00 2001 From: Erik Golinelli Date: Sat, 2 Dec 2023 14:01:15 +0100 Subject: [PATCH 5/7] Refactor code for better readability and improve function arrangement Modified file structures as the 'utils.js' and 'fs.js' files both contained functions related to file system operations, causing confusion. Moved all the file system related functions into 'fs.js', making the roles of 'utils.js' (holding the utility functions) and 'fs.js' (handling the filesystem operations) distinct. Additionally, renamed 'WordPressConfigInitializer' to 'Initialize' and added new function 'printTimePassed' for reusable time logging. Also replaced the 'init' function with 'dump' and 'initialize' functions to make the code more understandable and manage specific tasks separately. --- lib/index.js | 31 ++++++++++++++----------------- lib/install.js | 5 +++-- lib/package.js | 5 ++++- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/lib/index.js b/lib/index.js index 6b185a6..c2937d5 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,7 +1,8 @@ #!/usr/bin/env node -const { getConfig } = require('./utils'); -const { WordPressInstaller } = require('./install'); -const WordPressConfigInitializer = require('./init.js'); +const { getConfig, printTimePassed } = require('./utils'); +const WordPressInstaller = require('./install'); +const WordPressConfigDump = require('./dump.js'); +const Initialize = require('./initialize.js'); // Import the Initialize class const yargs = require('yargs'); const { hideBin } = require('yargs/helpers'); @@ -15,26 +16,22 @@ const config = getConfig(argv); // Start the timer const startTime = Date.now(); -if (argv.init === true) { - const initializer = new WordPressConfigInitializer(this); - initializer.init().then(() => { - process.exit(0); - }); +if (argv.dump === true) { + const dump = new WordPressConfigDump(this); + dump.init(); + printTimePassed(startTime); +} else if (argv.initialize === true) { + const initializer = new Initialize(config); + initializer.generateConfig(); + printTimePassed(startTime); } else { // Install WordPress const installer = new WordPressInstaller(config); installer.run().then(() => { console.log('๐Ÿš€ WordPress installed successfully.'); - - // End the timer - const endTime = Date.now(); - - // Calculate the time passed - const timePassed = endTime - startTime; - console.log(`๐Ÿ•’ Time passed: ${timePassed} milliseconds`); - - process.exit(0); + printTimePassed(startTime); }); } +process.exit(0); diff --git a/lib/install.js b/lib/install.js index 9b9b0ad..73cb93c 100644 --- a/lib/install.js +++ b/lib/install.js @@ -1,5 +1,6 @@ const path = require('path'); -const { cleanup, makeDir, isWPCLIAvailable} = require('./utils'); +const { isWPCLIAvailable } = require('./utils'); +const { cleanup, makeDir } = require('./fs'); const { WordPressPackage, PluginPackage, ThemePackage } = require('./package'); /** @@ -72,7 +73,7 @@ class WordPressInstaller { * @param {Array} commands - An array of WP-CLI commands to execute. * @return {Promise} - A promise that resolves when the post-install commands complete. */ - async runPostInstallCommands(commands) { + async runPostInstallCommands (commands) { // Execute each post-install command for (const command of commands) { try { diff --git a/lib/package.js b/lib/package.js index 8e3dfef..dce13db 100644 --- a/lib/package.js +++ b/lib/package.js @@ -7,11 +7,14 @@ const { getDownloadUrl, getWordPressDownloadUrl, installNpmPackages, - renameFolder, replaceDbConstant, replaceEmptySalts, installComposer, replaceDbConstantBool } = require('./utils'); +const { + renameFolder +} = require('./fs'); + class Package { /** * Constructs a new instance of the class. From c6f33b839ccd80e89163871ccce91142f31c721c Mon Sep 17 00:00:00 2001 From: Erik Golinelli Date: Sat, 2 Dec 2023 18:52:55 +0100 Subject: [PATCH 6/7] Refactor codebase, reorganize scripts and optimise config handling The diff represents several updates across the codebase. Reorganized 'scripts' in 'package.json' for better readability and further separation of concerns by adding the 'docs' command. Introduced a 'postInstall' property in 'wp-package.json'. Refactored 'lib/index.js' by wrapping actions within an object, which allows selection of the appropriate action based on the provided argv key. It improves code readability and maintainability whilst keeping the intent of the original code. In 'lib/package.js', reorganization of the 'require' statements was made. Reordered them to better reflect their execution sequence. 'Rename' command used to better align with the language used in rest of the code. The renaming of 'lib/init.js' to 'lib/initialize.js' helps in achieving consistency across the codebase. --- lib/index.js | 42 ++++++++++++++++++++-------------- lib/{init.js => initialize.js} | 0 lib/package.js | 4 ++-- package.json | 7 +++--- wp-package.json | 3 ++- 5 files changed, 33 insertions(+), 23 deletions(-) rename lib/{init.js => initialize.js} (100%) diff --git a/lib/index.js b/lib/index.js index c2937d5..0f0f487 100644 --- a/lib/index.js +++ b/lib/index.js @@ -16,22 +16,30 @@ const config = getConfig(argv); // Start the timer const startTime = Date.now(); -if (argv.dump === true) { - const dump = new WordPressConfigDump(this); - dump.init(); - printTimePassed(startTime); -} else if (argv.initialize === true) { - const initializer = new Initialize(config); - initializer.generateConfig(); - printTimePassed(startTime); -} else { - // Install WordPress - const installer = new WordPressInstaller(config); - - installer.run().then(() => { - console.log('๐Ÿš€ WordPress installed successfully.'); +const actions = { + dump: () => { + const dump = new WordPressConfigDump(this); + dump.init(); + printTimePassed(startTime); + process.exit(0); + }, + init: () => { + const initializer = new Initialize(config); + initializer.generateConfig(); printTimePassed(startTime); - }); -} + process.exit(0); + }, + default: () => { + // Install WordPress + const installer = new WordPressInstaller(config); + + installer.run().then(() => { + console.log('๐Ÿš€ WordPress installed successfully.'); + printTimePassed(startTime); + process.exit(0); + }); + } +}; -process.exit(0); +const action = Object.keys(argv).find(key => argv[key] === true); +(actions[action] || actions.default)(); diff --git a/lib/init.js b/lib/initialize.js similarity index 100% rename from lib/init.js rename to lib/initialize.js diff --git a/lib/package.js b/lib/package.js index dce13db..91649f7 100644 --- a/lib/package.js +++ b/lib/package.js @@ -2,8 +2,6 @@ const fs = require('fs'); const path = require('path'); const { exec } = require('child_process'); const { - downloadFile, - extractZip, getDownloadUrl, getWordPressDownloadUrl, installNpmPackages, @@ -12,6 +10,8 @@ const { } = require('./utils'); const { + downloadFile, + extractZip, renameFolder } = require('./fs'); diff --git a/package.json b/package.json index 2050ebb..0f07bcd 100644 --- a/package.json +++ b/package.json @@ -7,12 +7,13 @@ "type": "git", "url": "https://github.com/erikyo/wpmm.git" }, + "scripts": { + "test": "jest", + "docs": "npx jsdoc lib/index.js -d docs -c jsdoc.json" + }, "bin": { "wpmm": "lib/index.js" }, - "scripts": { - "test": "jest" - }, "main": "lib/index.js", "keywords": [ "wordpress", diff --git a/wp-package.json b/wp-package.json index 4371dc3..51f617c 100644 --- a/wp-package.json +++ b/wp-package.json @@ -20,5 +20,6 @@ } }, "themes": [], - "plugins": [] + "plugins": [], + "postInstall": [] } From 6dc79231dab3bcacafe5fab6a3cb8101e9e717e5 Mon Sep 17 00:00:00 2001 From: Erik Golinelli Date: Sat, 2 Dec 2023 19:00:28 +0100 Subject: [PATCH 7/7] 0.0.3 version update --- package.json | 2 +- readme.md | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 0f07bcd..92a0338 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wpmm", - "version": "0.0.2", + "version": "0.0.3", "description": "A Node.js script for easy installation of WordPress, themes, and plugins.", "author": "Erik Golinelli ", "repository": { diff --git a/readme.md b/readme.md index 20dbd89..ee66382 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,18 @@ # WordPress Magic Manager ๐Ÿช„ + WordPress Installer is a Node.js script designed to streamline the installation process of WordPress, themes, and plugins. It simplifies the configuration through a wp-package.json file, allowing you to specify the WordPress version, language, themes, and plugins for installation.