mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Rewrote archive script in Node.js.
It requires the fs-extra module, but that's considerably less to install than Python.
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
#!/usr/bin/env node
|
||||
// Archive packaging script. Takes one argument, which is the path to the
|
||||
// repository's root. Requires 7-zip and Git to be installed, and Git to be
|
||||
// available on the system path.
|
||||
|
||||
var child_process = require('child_process');
|
||||
var path = require('path');
|
||||
var fs = require('fs-extra');
|
||||
|
||||
if (process.argc < 3) {
|
||||
var root_path = process.argv[2];
|
||||
} else {
|
||||
var root_path = '.';
|
||||
}
|
||||
var temp_path = path.join(root_path, 'build', 'archive.tmp');
|
||||
|
||||
function vulcanize() {
|
||||
return child_process.execFileSync('node', [
|
||||
'scripts/vulcanize.js',
|
||||
root_path
|
||||
]);
|
||||
}
|
||||
|
||||
function getGitDescription() {
|
||||
return String(child_process.execFileSync('git', [
|
||||
'describe',
|
||||
'--tags',
|
||||
'--long'
|
||||
])).slice(0, -1);
|
||||
}
|
||||
|
||||
function compress(source_path, dest_path) {
|
||||
var sevenzip_path = path.join('C:\\', 'Program Files', '7-Zip', '7z.exe');
|
||||
|
||||
// First remove any existing archive.
|
||||
fs.removeSync(dest_path);
|
||||
|
||||
// The last argument must have a leading dot for the subdirectory not to
|
||||
// be present in the archive, but path.join removes it, so it's prefixed.
|
||||
return child_process.execFileSync(sevenzip_path, [
|
||||
'a',
|
||||
'-r',
|
||||
dest_path,
|
||||
'.' + path.sep + path.join(source_path, '*')
|
||||
]);
|
||||
}
|
||||
|
||||
function createAppArchive(dest_path) {
|
||||
// Ensure that the output directory is empty.
|
||||
fs.emptyDirSync(temp_path);
|
||||
|
||||
// Copy LOOT exectuable and CEF files.
|
||||
[
|
||||
'LOOT.exe',
|
||||
'd3dcompiler_47.dll',
|
||||
'libEGL.dll',
|
||||
'libGLESv2.dll',
|
||||
'libcef.dll',
|
||||
'wow_helper.exe',
|
||||
'natives_blob.bin',
|
||||
'snapshot_blob.bin',
|
||||
'cef.pak',
|
||||
'cef_100_percent.pak',
|
||||
'cef_200_percent.pak',
|
||||
'devtools_resources.pak',
|
||||
'icudtl.dat'
|
||||
].forEach(function(file){
|
||||
fs.copySync(
|
||||
path.join(root_path, 'build', 'Release', file),
|
||||
path.join(temp_path, file)
|
||||
);
|
||||
});
|
||||
|
||||
// CEF locale file.
|
||||
fs.mkdirsSync(path.join(temp_path, 'resources', 'l10n'));
|
||||
fs.copySync(
|
||||
path.join(root_path, 'build', 'Release', 'resources', 'l10n', 'en-US.pak'),
|
||||
path.join(temp_path, 'resources', 'l10n', 'en-US.pak')
|
||||
);
|
||||
|
||||
// Translation files.
|
||||
[
|
||||
'es', 'ru', 'fr', 'zh_CN', 'pl',
|
||||
'pt_BR', 'fi', 'de', 'da', 'ko'
|
||||
].forEach(function(lang){
|
||||
fs.mkdirsSync(path.join(temp_path, 'resources', 'l10n', lang, 'LC_MESSAGES'));
|
||||
fs.copySync(
|
||||
path.join(root_path, 'resources', 'l10n', lang, 'LC_MESSAGES', 'loot.mo'),
|
||||
path.join(temp_path, 'resources', 'l10n', lang, 'LC_MESSAGES', 'loot.mo')
|
||||
);
|
||||
});
|
||||
|
||||
// UI files.
|
||||
fs.mkdirsSync(path.join(temp_path, 'resources', 'ui', 'css'));
|
||||
fs.copySync(
|
||||
path.join(root_path, 'build', 'Release', 'resources', 'ui', 'index.html'),
|
||||
path.join(temp_path, 'resources', 'ui', 'index.html')
|
||||
);
|
||||
fs.copySync(
|
||||
path.join(root_path, 'resources', 'ui', 'css', 'dark-theme.css'),
|
||||
path.join(temp_path, 'resources', 'ui', 'css', 'dark-theme.css')
|
||||
);
|
||||
fs.copySync(
|
||||
path.join(root_path, 'resources', 'ui', 'fonts'),
|
||||
path.join(temp_path, 'resources', 'ui', 'fonts')
|
||||
);
|
||||
|
||||
// Docs.
|
||||
fs.mkdirsSync(path.join(temp_path, 'docs'));
|
||||
[
|
||||
'images',
|
||||
'licenses',
|
||||
'LOOT Metadata Syntax.html',
|
||||
'LOOT Readme.html'
|
||||
].forEach(function(item){
|
||||
fs.copySync(
|
||||
path.join(root_path, 'docs', item),
|
||||
path.join(temp_path, 'docs', item)
|
||||
);
|
||||
});
|
||||
|
||||
// Now compress the folder to a 7-zip archive.
|
||||
compress(temp_path, dest_path);
|
||||
|
||||
// Finally, delete the temporary folder.
|
||||
fs.removeSync(temp_path);
|
||||
}
|
||||
|
||||
function createApiArchive(dest_path) {
|
||||
// Ensure that the output directory is empty.
|
||||
fs.emptyDirSync(temp_path);
|
||||
|
||||
// API binary.
|
||||
fs.copySync(
|
||||
path.join(root_path, 'build', 'Release', 'loot32.dll'),
|
||||
path.join(temp_path, 'loot32.dll')
|
||||
);
|
||||
|
||||
// API header file.
|
||||
fs.mkdirsSync(path.join(temp_path, 'include', 'loot'));
|
||||
fs.copySync(
|
||||
path.join(root_path, 'src', 'api', 'api.h'),
|
||||
path.join(temp_path, 'include', 'loot', 'api.h')
|
||||
);
|
||||
|
||||
// Docs.
|
||||
fs.mkdirsSync(path.join(temp_path, 'docs'));
|
||||
fs.copySync(
|
||||
path.join(root_path, 'docs', 'latex', 'refman.pdf'),
|
||||
path.join(temp_path, 'docs', 'readme.pdf')
|
||||
);
|
||||
fs.copySync(
|
||||
path.join(root_path, 'docs', 'licenses'),
|
||||
path.join(temp_path, 'docs', 'licenses')
|
||||
);
|
||||
|
||||
|
||||
// Now compress the folder to a 7-zip archive.
|
||||
compress(temp_path, dest_path);
|
||||
|
||||
// Finally, delete the temporary folder.
|
||||
fs.removeSync(temp_path);
|
||||
}
|
||||
|
||||
var git_desc = getGitDescription();
|
||||
vulcanize();
|
||||
createAppArchive(path.join(root_path, 'build', 'LOOT ' + git_desc + '.7z'));
|
||||
createApiArchive(path.join(root_path, 'build', 'LOOT API ' + git_desc + '.7z'));
|
||||
@@ -1,186 +0,0 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Creates an archive of a LOOT release, putting it in the 'build' folder.
|
||||
|
||||
# LOOT
|
||||
#
|
||||
# A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
|
||||
# Fallout: New Vegas.
|
||||
#
|
||||
# Copyright (C) 2013-2015 WrinklyNinja
|
||||
#
|
||||
# This file is part of LOOT.
|
||||
#
|
||||
# LOOT is free software: you can redistribute
|
||||
# it and/or modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# LOOT is distributed in the hope that it will
|
||||
# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with LOOT. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
import sys
|
||||
import os
|
||||
import shutil
|
||||
import zipfile
|
||||
import subprocess
|
||||
|
||||
# There are two compression methods available:
|
||||
#
|
||||
# * Zip (Deflate)
|
||||
# * 7-Zip (LZMA)
|
||||
#
|
||||
# Python 3.3+ can also do BZIP2 and LZMA zip archives, but they don't have good
|
||||
# Windows OS support, so people think they should be able to open them without
|
||||
# an archiving utility, find they can't, and think the archive is broken. So
|
||||
# they won't be used.
|
||||
#
|
||||
# Look for 7-Zip in its default install location, and use it if it is found.
|
||||
# Fall back to zip if not.
|
||||
#
|
||||
# Archives are named using the output of `git describe --tags --long`, if Git
|
||||
# is found in the current PATH. Otherwise, they will simply be named
|
||||
# 'LOOT Archive'.
|
||||
#
|
||||
# The current path throughout the script is the `src` folder, where this script
|
||||
# is located.
|
||||
|
||||
# Find an executable's path from its name. Like Python 3.3's shutil.which, but
|
||||
# also checks likely paths for hardcoded programs.
|
||||
def which(cmd):
|
||||
if 'which' in dir(shutil):
|
||||
exe_path = shutil.which(cmd)
|
||||
else:
|
||||
# Check the PATH environmental variable manually.
|
||||
exe_path = None
|
||||
path = os.getenv('PATH')
|
||||
for p in path.split(os.path.pathsep):
|
||||
p = os.path.join(p, cmd)
|
||||
if os.path.exists(p) and os.access(p, os.X_OK):
|
||||
exe_path = p
|
||||
|
||||
if not exe_path:
|
||||
if cmd == '7z.exe':
|
||||
sevenzip_path = os.path.join('C:\\', 'Program Files', '7-Zip', '7z.exe')
|
||||
if os.path.exists(sevenzip_path):
|
||||
exe_path = sevenzip_path
|
||||
elif cmd == 'vulcanize.cmd':
|
||||
npm = os.path.join( os.getenv('APPDATA'), 'npm' )
|
||||
if (os.path.exists(npm, 'vulcanize.cmd')):
|
||||
exe_path = os.path.join(npm, 'vulcanize.cmd')
|
||||
|
||||
return exe_path
|
||||
|
||||
def getNameSuffix():
|
||||
# Check for a Git install, and get the revision info if found.
|
||||
git = which('git.exe')
|
||||
if git:
|
||||
args = [git, 'describe', '--tags', '--long']
|
||||
output = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
|
||||
if len(output[1]) == 0:
|
||||
return output[0].decode('ascii')[:-1]
|
||||
|
||||
return ''
|
||||
|
||||
def buildUIFiles():
|
||||
# Vulcanize the UI's files.
|
||||
subprocess.call(['node', './vulcanize.js', '..']);
|
||||
|
||||
def createArchive(folder_path, archive_path):
|
||||
sevenzip_path = os.path.join('C:\\', 'Program Files', '7-Zip', '7z.exe')
|
||||
if os.path.exists(sevenzip_path):
|
||||
args = [sevenzip_path, 'a', '-r', archive_path + '.7z', os.path.join(folder_path, '*')]
|
||||
subprocess.call(args)
|
||||
else:
|
||||
zip = zipfile.ZipFile( archive_path + '.zip', 'w', zipfile.ZIP_DEFLATED )
|
||||
for root, dirs, files in os.walk(folder_path):
|
||||
for file in files:
|
||||
zip.write(os.path.join(root, file))
|
||||
zip.close()
|
||||
|
||||
def createAppArchive(archive_path):
|
||||
temp_path = os.path.join('..', 'build', 'archive.tmp')
|
||||
|
||||
# Delete the temporary folder if it already exists, then create it.
|
||||
if os.path.exists(temp_path):
|
||||
shutil.rmtree(temp_path)
|
||||
os.makedirs(temp_path)
|
||||
|
||||
# Now copy everything into the temporary folder.
|
||||
# LOOT executable and CEF files.
|
||||
shutil.copy( os.path.join('..', 'build', 'Release', 'LOOT.exe'), temp_path )
|
||||
shutil.copy( os.path.join('..', 'build', 'Release', 'd3dcompiler_47.dll'), temp_path )
|
||||
shutil.copy( os.path.join('..', 'build', 'Release', 'libEGL.dll'), temp_path )
|
||||
shutil.copy( os.path.join('..', 'build', 'Release', 'libGLESv2.dll'), temp_path )
|
||||
shutil.copy( os.path.join('..', 'build', 'Release', 'libcef.dll'), temp_path )
|
||||
shutil.copy( os.path.join('..', 'build', 'Release', 'wow_helper.exe'), temp_path )
|
||||
shutil.copy( os.path.join('..', 'build', 'Release', 'natives_blob.bin'), temp_path )
|
||||
shutil.copy( os.path.join('..', 'build', 'Release', 'snapshot_blob.bin'), temp_path )
|
||||
shutil.copy( os.path.join('..', 'build', 'Release', 'cef.pak'), temp_path )
|
||||
shutil.copy( os.path.join('..', 'build', 'Release', 'cef_100_percent.pak'), temp_path )
|
||||
shutil.copy( os.path.join('..', 'build', 'Release', 'cef_200_percent.pak'), temp_path )
|
||||
shutil.copy( os.path.join('..', 'build', 'Release', 'devtools_resources.pak'), temp_path )
|
||||
shutil.copy( os.path.join('..', 'build', 'Release', 'icudtl.dat'), temp_path )
|
||||
|
||||
# Translation files.
|
||||
os.makedirs(os.path.join(temp_path, 'resources', 'l10n'))
|
||||
shutil.copy( os.path.join('..', 'build', 'Release', 'resources', 'l10n', 'en-US.pak'), os.path.join(temp_path, 'resources', 'l10n') )
|
||||
for lang in ['es', 'ru', 'fr', 'zh_CN', 'pl', 'pt_BR', 'fi', 'de', 'da', 'ko']:
|
||||
os.makedirs(os.path.join(temp_path, 'resources', 'l10n', lang, 'LC_MESSAGES'))
|
||||
shutil.copy( os.path.join('..', 'resources', 'l10n', lang, 'LC_MESSAGES', 'loot.mo'), os.path.join(temp_path, 'resources', 'l10n', lang, 'LC_MESSAGES') )
|
||||
|
||||
# UI files.
|
||||
os.makedirs( os.path.join(temp_path, 'resources', 'ui', 'css') )
|
||||
shutil.copy( os.path.join('..', 'build', 'Release', 'resources', 'ui', 'index.html'), os.path.join(temp_path, 'resources', 'ui') )
|
||||
shutil.copy( os.path.join('..', 'resources', 'ui', 'css', 'dark-theme.css'), os.path.join(temp_path, 'resources', 'ui', 'css') )
|
||||
shutil.copytree( os.path.join('..', 'resources', 'ui', 'fonts'), os.path.join(temp_path, 'resources', 'ui', 'fonts') )
|
||||
|
||||
# Docs.
|
||||
shutil.copytree( os.path.join('..', 'docs', 'images'), os.path.join(temp_path, 'docs', 'images') )
|
||||
shutil.copytree( os.path.join('..', 'docs', 'licenses'), os.path.join(temp_path, 'docs', 'licenses') )
|
||||
shutil.copy( os.path.join('..', 'docs', 'LOOT Metadata Syntax.html'), os.path.join(temp_path, 'docs') )
|
||||
shutil.copy( os.path.join('..', 'docs', 'LOOT Readme.html'), os.path.join(temp_path, 'docs') )
|
||||
|
||||
# Now compress the temporary folder.
|
||||
createArchive(temp_path, archive_path);
|
||||
|
||||
# And finally, delete the temporary folder.
|
||||
shutil.rmtree(temp_path)
|
||||
|
||||
def createApiArchive(archive_path):
|
||||
temp_path = os.path.join('..', 'build', 'archive.tmp')
|
||||
|
||||
# Delete the temporary folder if it already exists, then create it.
|
||||
if os.path.exists(temp_path):
|
||||
shutil.rmtree(temp_path)
|
||||
os.makedirs(temp_path)
|
||||
|
||||
# Create directories in temporary folder.
|
||||
os.makedirs( os.path.join(temp_path, 'include', 'loot') )
|
||||
os.makedirs( os.path.join(temp_path, 'docs') )
|
||||
|
||||
# Now copy everything into the temporary folder.
|
||||
shutil.copy( os.path.join('..', 'build', 'Release', 'loot32.dll'), temp_path )
|
||||
shutil.copy( os.path.join('..', 'src', 'api', 'api.h'), os.path.join(temp_path, 'include', 'loot') )
|
||||
shutil.copy( os.path.join('..', 'docs', 'latex', 'refman.pdf'), os.path.join(temp_path, 'docs', 'readme.pdf') )
|
||||
|
||||
shutil.copytree( os.path.join('..', 'docs', 'licenses'), os.path.join(temp_path, 'docs', 'licenses') )
|
||||
|
||||
# Now compress the temporary folder.
|
||||
createArchive(temp_path, archive_path);
|
||||
|
||||
# And finally, delete the temporary folder.
|
||||
shutil.rmtree(temp_path)
|
||||
|
||||
# Create the archives.
|
||||
archive_suffix = getNameSuffix()
|
||||
buildUIFiles();
|
||||
createAppArchive( os.path.join('..', 'build', 'LOOT ' + archive_suffix) )
|
||||
createApiArchive( os.path.join('..', 'build', 'LOOT API ' + archive_suffix) )
|
||||
Reference in New Issue
Block a user