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
.