@@ -157,64 +157,159 @@ export default async (beforeError, forceUpdate) => {
157157 process . stdout . write ( '\u001b[2J\u001b[0;0H' ) ;
158158 await splashLogo ( client . locale . lib . loaders . splashLogo ) ;
159159
160+ // Obtains the repository URL
161+ let repoUrl = packageConfig . repository . url ;
162+
163+ // Removes the unnecessary parts from the URL
164+ repoUrl = repoUrl . replace ( / ^ g i t \+ / , '' ) . replace ( / \. g i t $ / , '' ) ;
165+
160166 // Shows a message indicating that the bot is downloading the new version
161- console . log ( `⬇️ ${ await client . functions . utils . parseLocale ( locale . downloadingNewVersion , { targetVersion : `v${ latestRemoteTag } ` , repositoryURL : packageConfig . repository . url } ) } ...` ) ;
167+ console . log ( `⬇️ ${ await client . functions . utils . parseLocale ( locale . downloadingNewVersion , { targetVersion : `v${ latestRemoteTag } ` , repositoryURL : repoUrl } ) } ...` ) ;
168+
169+ // Stores the working directory
170+ const workingDirectory = String ( process . cwd ( ) ) ;
162171
163- // Stores the latest configuration from the config.json file
164- const currentConfigContent = await fs . readFileSync ( './config.json' ) ;
172+ // Stores the temporary directory
173+ const tmpDir = ` ${ workingDirectory } /tmp` ;
165174
166- // Fetches the latest changes from the repository
167- await git . fetch ( [ '--all' ] ) ;
175+ try {
168176
169- // Resets the local repository to the latest remote version
170- await git . reset ( [ '--hard' , latestRemoteTag ] ) ;
177+ // Creates the temporary directory if it doesn't exist, or empties it if it does
178+ if ( ! fs . existsSync ( tmpDir ) ) await fs . promises . mkdir ( tmpDir ) ;
179+ else await fs . promises . rm ( tmpDir , { recursive : true } ) ;
171180
172- // Checks out the latest remote tag
173- // await git.checkout(latestRemoteTag );
181+ // Clones the repository in the temporary directory
182+ await git . clone ( repoUrl , tmpDir ) ;
174183
175- // Restores the stored configuration to the config.json file
176- await fs . writeFile ( './config.json' , currentConfigContent ) ;
184+ // Changes the working directory to the temporary directory
185+ process . chdir ( tmpDir ) ;
177186
178- // Cleans the console and shows the logo
179- process . stdout . write ( '\u001b[2J\u001b[0;0H' ) ;
180- await splashLogo ( client . locale . lib . loaders . splashLogo ) ;
187+ // Stops the process
188+ process . exit ( 0 ) ; // --- EXPERIMENTAL ---
181189
182- // Shows a message indicating that the bot has been updated
183- console . log ( `🎉 ${ await client . functions . utils . parseLocale ( locale . updatedCorrectly , { targetVersion : `v${ latestRemoteTag } ` } ) } \n` ) ;
190+ // Switches to the latest remote tag
191+ await git . fetch ( [ '--all' ] ) ;
192+ await git . reset ( [ '--hard' , latestRemoteTag ] ) ;
184193
185- // Shows a message indicating that the bot needs to be restarted in order to apply the changes
186- console . log ( ` ${ locale . needsRestart } .\n` ) ;
194+ // Changes the working directory back to the original directory
195+ process . chdir ( workingDirectory ) ;
187196
188- // Shows the select menu to ask the user if wants to update the bot
189- global . currentPrompt = select ( {
197+ // Creates an array with the files to exclude from the update
198+ const excludeFiles = [ './config.json' ] ;
199+
200+ // Copied the files from the temporary directory to the original directory
201+ await fs . readdir ( './tmp' , async ( err , files ) => {
202+
203+ // If an error occurred, throws it
204+ if ( err ) throw err ;
205+
206+ // For each file in the temporary directory
207+ for ( const file of files ) {
208+
209+ // If the file is not in the exclude list, copies it
210+ if ( ! excludeFiles . includes ( file ) ) await fs . copy ( `./tmp/${ file } ` , `./${ file } ` ) ;
211+ } ;
212+ } ) ;
213+
214+ // Deletes the files that are not in the temporary directory
215+ await fs . readdir ( '.' , async ( err , files ) => {
216+
217+ // If an error occurred, throws it
218+ if ( err ) throw err ;
219+
220+ // For each file in the original directory
221+ for ( const file of files ) {
222+
223+ // If the file is not in the temporary directory, deletes it
224+ if ( ! fs . existsSync ( `./tmp/${ file } ` ) ) await fs . unlink ( `./${ file } ` ) ;
225+ } ;
226+ } ) ;
227+
228+ // Deletes the temporary directory
229+ await fs . promises . rmdir ( './tmp' ) ;
230+
231+ // Requires the child_process library
232+ const { exec } = require ( 'child_process' ) ;
233+
234+ // Function to install the dependencies
235+ const installDependencies = ( ) => {
236+
237+ // Returns a promise to install the dependencies
238+ return new Promise ( ( resolve , reject ) => {
239+
240+ // Execites the command to install the dependencies
241+ exec ( 'npm install' , ( error , stdout , stderr ) => {
242+
243+ // If an error occurred
244+ if ( error ) {
245+
246+ // Logs an error message if one occurred
247+ console . error ( `Error while installing dependencies : ${ error . stack } ` ) ;
248+
249+ // Rejects the promise with the error
250+ reject ( error ) ;
251+
252+ } else {
253+
254+ // Resolves the promise
255+ resolve ( ) ;
256+ } ;
257+ } ) ;
258+ } ) ;
259+ } ;
260+
261+ // Installs the dependencies
262+ await installDependencies ( ) ;
190263
191- message : `${ locale . restartConfirmationPrompt . message } :` ,
192- choices : [
193- {
194- name : `🔄 ${ locale . restartConfirmationPrompt . restartNow } ` ,
195- value : 'restart'
196- }
197- ] ,
198- } ) ;
199-
200- // When the user selects an option
201- global . currentPrompt . then ( async ( result ) => {
202-
203- // If the user wants to restart now, restarts the bot
204- if ( result === 'restart' ) process . exit ( 0 ) ;
264+ // Cleans the console and shows the logo
265+ process . stdout . write ( '\u001b[2J\u001b[0;0H' ) ;
266+ await splashLogo ( client . locale . lib . loaders . splashLogo ) ;
205267
206- // When an error occurs
207- } ) . catch ( async ( error ) => {
268+ // Shows a message indicating that the bot has been updated
269+ console . log ( `🎉 ${ await client . functions . utils . parseLocale ( locale . updatedCorrectly , { targetVersion : `v ${ latestRemoteTag } ` } ) } \n` ) ;
208270
209- // Runs this menu again, passing the error
210- await client . functions . menus [ menuName ] ( error ) ;
211- } ) ;
212-
213- // Waits 30 seconds before exiting the process
214- await new Promise ( resolve => setTimeout ( resolve , 30000 ) ) ;
271+ // Shows a message indicating that the bot needs to be restarted in order to apply the changes
272+ console . log ( `${ locale . needsRestart } .\n` ) ;
273+
274+ // Shows the select menu to ask the user if wants to update the bot
275+ global . currentPrompt = select ( {
276+
277+ message : `${ locale . restartConfirmationPrompt . message } :` ,
278+ choices : [
279+ {
280+ name : `🔄 ${ locale . restartConfirmationPrompt . restartNow } ` ,
281+ value : 'restart'
282+ }
283+ ] ,
284+ } ) ;
285+
286+ // When the user selects an option
287+ global . currentPrompt . then ( async ( result ) => {
288+
289+ // If the user wants to restart now, restarts the bot
290+ if ( result === 'restart' ) process . exit ( 0 ) ;
291+
292+ // When an error occurs
293+ } ) . catch ( async ( error ) => {
215294
216- // Exits the process
217- process . exit ( 0 ) ;
295+ // Runs this menu again, passing the error
296+ await client . functions . menus [ menuName ] ( error ) ;
297+ } ) ;
298+
299+ // Waits 30 seconds before exiting the process
300+ await new Promise ( resolve => setTimeout ( resolve , 30000 ) ) ;
301+
302+ // Exits the process
303+ process . exit ( 0 ) ;
304+
305+ } catch ( error ) {
306+
307+ // Elimina el directorio temporal
308+ if ( fs . existsSync ( tmpDir ) ) await fs . promises . rmdir ( './tmp' ) ;
309+
310+ // Logs an error message if one occurred
311+ throw new Error ( `An error occurred while updating the bot: ${ error . stack } ` ) ;
312+ } ;
218313 } ;
219314
220315 // Shows a message indicating that there are new updates
0 commit comments