USB_Config_Vendor/CC_SDK/Environment/cppp-reiconv/cpppdist.py

196 lines
5.9 KiB
Python
Raw Normal View History

2026-02-03 14:36:30 +08:00
#!/usr/bin/env python3
# Copyright (C) 2023 The C++ Plus Project.
# This file is part of the cppp library.
#
# The cppp library is free software; you can redistribute it
# and/or modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# The cppp library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with the cppp library; see the file COPYING.
# If not, see <https://www.gnu.org/licenses/>.
# C++ Plus dist utils.
import os
import sys
import json
import shutil
import importlib.util
PACKAGE_INFO = "CPPPPKG"
PROGNAME = "cpppdist.py"
def import_file(path):
"""
Import a Python file from it's path
Args:
path (str): Python file's path
Raises:
ModuleNotFoundError: When module invalid, load error or not found.
Returns:
ModuleType: module
"""
spec = importlib.util.spec_from_file_location(os.path.basename(path).replace(".py", ""), path)
if(spec == None):
raise ModuleNotFoundError("Invalid module or module not found: " + path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
class Package:
"""
A dist package type
"""
name = ""
version = ""
list_file_path = ""
filelist = []
subpackages = {}
def __init__(self, pkginfo_filepath) -> None:
try:
os.chdir(fwd)
with open(pkginfo_filepath, "r", encoding="UTF-8") as info_file:
data = json.load(info_file)
self.name = data["name"]
self.version = data["version"]
self.list_file_path = data["list_file_path"]
try:
_subpackages = data["subpackages"]
for pkgname in _subpackages:
pkgpath = _subpackages[pkgname]["path"]
try:
pkgmodule = import_file(os.path.join(pkgpath, PROGNAME))
self.subpackages[pkgpath] = pkgmodule.package
except Exception as e:
if(not _subpackages[pkgname]["ignore"]):
raise
else:
print(f"DEBUG: Ignore a subpackage '{pkgname}': {e}", file=sys.stderr)
except KeyError:
pass
self.filelist = self.get_file_list()
finally:
os.chdir(cwd)
def get_file_list(self) -> list:
"""
Get file list for dist.
"""
try:
os.chdir(fwd)
file_list = []
with open(self.list_file_path, "rt", encoding="UTF-8") as list_file:
data = list_file.read()
file_list = data.strip().split("\n")
return file_list
finally:
os.chdir(cwd)
def copy_files(self, dest):
"""
Copy files to dist dest
"""
try:
os.chdir(fwd)
if(os.path.exists(dest)):
shutil.rmtree(dest)
print(f"Copy package '{self.name}' to '{dest}' ... ", file=sys.stderr)
progressbar = ProgressBar(len(self.filelist))
for file in self.filelist:
relpath = os.path.relpath(file, fwd)
filedir = os.path.abspath(os.path.join(dest, relpath, ".."))
if(not os.path.exists(filedir)):
os.makedirs(filedir)
shutil.copy(file, os.path.join(dest, relpath))
progressbar.add(1)
progressbar.end()
print("", end="\n", file=sys.stderr)
# Copy subpackages
for (pkgpath, pkg) in self.subpackages.items():
pkg.copy_files(os.path.join(dest, os.path.join(dest, pkgpath)))
finally:
os.chdir(cwd)
class ProgressBar:
"""
Progress bar type.
"""
def __init__(self, total):
self.total = total
self.cur = 0
sys.stderr.write("\n")
self.update()
def add(self, step):
"""
Add current value and update.
"""
self.cur += step
self.update()
def set(self, cur):
"""
Set current value and update.
"""
self.cur = cur
self.update()
def update(self):
"""
Update progress bar.
"""
try:
progress = 0.0
if(self.cur):
progress = self.cur / self.total
term_width = os.get_terminal_size(sys.stderr.fileno()).columns
part_width = term_width - len("[]100.0%")
if(part_width <= 0):
# Terminal is too small, ignore.
return
sys.stderr.write("\r")
# Part1 is '#'
part1 = int(part_width * progress) * '#'
# Part2 is ' '
part2 = int(part_width - len(part1)) * ' '
# Part3 is 'xxx.x%'
part3 = str(int(progress * 1000) / 10) + "%"
sys.stderr.write(f"[{part1}{part2}]{part3}")
sys.stderr.flush()
except:
return
def end(self):
"""
End this progress bar
"""
self.set(self.total)
sys.stderr.write("\n")
sys.stderr.flush()
cwd = os.path.abspath(os.curdir)
fwd = os.path.abspath(os.path.join(__file__, ".."))
package = None
try:
package = Package(PACKAGE_INFO)
except Exception as exc:
print("Getting packge infomation error:", exc, file=sys.stderr)
raise exc
if __name__ == "__main__":
distdir = f"{package.name}-v{package.version}"
package.copy_files(os.path.abspath(distdir))