Python: reinstallare un'applicazione in Node.js

Python: reinstallare un'applicazione in Node.js

In questo articolo vedremo come eseguire una reinstallazione completa di un'applicazione Node.js utilizzando Python.

Possiamo iniziare leggendo l'elenco delle dipendenze dal file package.json originale e restituire i nomi dei pacchetti sotto forma di lista.

import json
import sys
import subprocess
import os
import shutil


def get_packages_names():
    names = []
    with open('./package.json', 'r') as f:
        data = json.load(f)
        deps = data.get('dependencies')
        if deps:
            names = list(deps.keys())
    return names

Ottenendo solo il nome della chiave, ci assicuriamo anche di installare l'ultima versione di ciascun pacchetto. Questo è utile quando dobbiamo aggiornare la nostra applicazione all'ultima versione delle sue dipendenze.

Per reinstallare la nostra app, dobbiamo prima rinominare il nostro file package.json originale per eseguire un comando npm init -y pulito. Se questo primo passaggio riesce, passiamo al processo di installazione vero e proprio, altrimenti rinominiamo il nostro file package.json con il suo nome originale.

Ora possiamo eseguire npm install [...] --save, dove [...] è l'elenco dei nomi dei pacchetti che abbiamo recuperato dalla proprietà dependencies del nostro file package.json. Abbiamo anche bisogno di creare una copia di backup della nostra directory node_modules, se presente.

Se l'installazione fallisce, ripristiniamo sia il file package.json originale sia la directory node_modules. In caso contrario, rimuoviamo le copie di backup di queste risorse.

def install_packages():
    packages_list = get_packages_names()
    orig_pkg_file = './package.json'
    old_pkg_filename = './package-old.json'
    modules_dir = './node_modules'
    old_modules_dir_name = './node_modules_old'

    if len(packages_list) == 0:
        print('No NPM packages to install')
        sys.exit(1)
        
    npm_init_cmd = 'npm init -y'.split(' ')
    print('Renaming old package.json')
    os.rename(orig_pkg_file, old_pkg_filename)
    print('Initializing new package.json')
    init_cmd = subprocess.run(npm_init_cmd, stdout=subprocess.DEVNULL)
    
    if init_cmd.returncode == 1:
        print('Failed to initialize, restoring the old package.json')
        os.rename(old_pkg_filename, orig_pkg_file)
        sys.exit(1)
        
    install_cmd = ['npm', 'install']
    
    for pkg in packages_list:
        install_cmd.append(pkg)
    install_cmd.append('--save')
    
    print('Installing packages')
    
    if os.path.isdir(modules_dir):
        os.rename(modules_dir, old_modules_dir_name)
        
    install = subprocess.run(install_cmd, stdout=subprocess.DEVNULL)
    if install.returncode == 1:
        print('Installation failed, cleaning up')
        if os.path.isdir(modules_dir):
            shutil.rmtree(modules_dir)
            os.rename(old_modules_dir_name, modules_dir)
        os.unlink(orig_pkg_file)
        os.rename(old_pkg_filename, orig_pkg_file)
        sys.exit(1)
        
    os.unlink(old_pkg_filename)
    shutil.rmtree(old_modules_dir_name)
    print('Done')
    
    sys.exit(0)

subprocess.run() ci dà la possibilità di sapere se il comando shell eseguito è riuscito o meno esponendo la proprietà returncode, dove 1 indica un errore e 0 significa che il comando è stato eseguito con successo.

Questo metodo accetta un comando come una lista, dove il primo elemento rappresenta il nome del comando (qui npm) e gli elementi successivi sono i parametri del comando.

Possiamo eseguire il nostro codice come segue:

def main():
    install_packages()


if __name__ == '__main__':
    main()

Questa soluzione è utile quando si deve ricostruire un'applicazione o si vogliono semplicemente installare le ultime versioni dei moduli senza dover cambiare manualmente il loro numero di versione all'interno del file package.json.

Torna su