- CitrineOS core extracted (CSMS OCPP 2.0.1) - OpenOCPP extracted (firmware OCPP 1.6J/2.0.1) - ShapeShifter library installed (pip install -e) - ShapeShifter specification extracted - EVerest extracted TODO updated with progress
150 lines
6.4 KiB
Python
Executable File
150 lines
6.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
# Copyright Pionix GmbH and Contributors to EVerest
|
|
#
|
|
"""
|
|
author: kai-uwe.hermann@pionix.de
|
|
Use edm to create a snapshot of the current directory without polluting the current working dir
|
|
"""
|
|
|
|
import argparse
|
|
import yaml
|
|
import subprocess
|
|
from pathlib import Path
|
|
import shutil
|
|
import string
|
|
|
|
|
|
def get_tags(path: Path) -> list:
|
|
"""Return a list of tags the HEAD points to of the repo at path, or an empty list."""
|
|
tags = []
|
|
try:
|
|
result = subprocess.run(["git", "-C", path, "tag", "--points-at", "HEAD"],
|
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)
|
|
tags = result.stdout.decode("utf-8").splitlines()
|
|
except subprocess.CalledProcessError:
|
|
return tag
|
|
|
|
return tags
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(
|
|
description='create an isolated snapshot with edm')
|
|
|
|
parser.add_argument('--working-dir', '-wd', type=str,
|
|
help='Working directory containing the EVerest workspace (default: .)', default=str(Path.cwd()))
|
|
parser.add_argument('--temp-dir', '-td', type=str,
|
|
help='Temporary directory for creating the snapshot in (default: working-dir/tmp-for-snapshot)', default=None)
|
|
parser.add_argument('--version', type=str,
|
|
help='dependency version to override, format is: dependency1:version,dependency2:version2', default=None)
|
|
parser.add_argument('--git-version', action='store_true', help='Use "git" as version when encountering a git hash')
|
|
parser.add_argument('--allow-relative-to-working-dir', action='store_true', help='Allow temporary directory to be relative to working dir (dangerous!)')
|
|
parser.add_argument('--post-process', action='store_true', help='Postprocess existing snapshot')
|
|
parser.add_argument('--include-external-deps', action='store_true', help='Include external dependencies in snapshot')
|
|
parser.add_argument('--exclude-dir', action='append', dest='excluded_dirs', type=str, help='Exclude specified directory from snapshot (can be used multiple times)', default=[])
|
|
|
|
args = parser.parse_args()
|
|
|
|
working_dir = Path(args.working_dir).expanduser().resolve()
|
|
|
|
tmp_dir = working_dir / 'tmp-for-snapshot'
|
|
|
|
if args.temp_dir:
|
|
tmp_dir = Path(args.temp_dir).expanduser().resolve()
|
|
|
|
if working_dir == tmp_dir:
|
|
print(f'Temporary directory cannot be equal to working directory: {tmp_dir}')
|
|
return 1
|
|
|
|
if tmp_dir.is_relative_to(working_dir) and tmp_dir.parent != working_dir and not args.allow_relative_to_working_dir:
|
|
print(f'Temporary directory cannot be relative to working directory: {tmp_dir}')
|
|
return 1
|
|
|
|
excluded_paths = []
|
|
for excluded_dir in args.excluded_dirs:
|
|
excluded_path = working_dir / excluded_dir
|
|
excluded_path = excluded_path.expanduser().resolve()
|
|
excluded_paths.append(excluded_path)
|
|
|
|
if not args.post_process and tmp_dir.exists():
|
|
print(f'Temporary directory dir already exists, deleting it: {tmp_dir}')
|
|
shutil.rmtree(tmp_dir, ignore_errors=True)
|
|
if not args.post_process:
|
|
tmp_dir.mkdir()
|
|
|
|
subdirs = list(working_dir.glob('*/'))
|
|
for subdir in subdirs:
|
|
subdir_path = Path(subdir)
|
|
if not subdir_path.is_dir():
|
|
print(f'{subdir_path} is not a dir, ignoring')
|
|
continue
|
|
if subdir_path == tmp_dir:
|
|
print(f'{subdir_path} is tmp dir, ignoring')
|
|
continue
|
|
if subdir_path in excluded_paths:
|
|
print(f'{subdir_path} is excluded, ignoring')
|
|
continue
|
|
print(f'Copying {subdir_path} to {tmp_dir}')
|
|
destdir = tmp_dir / subdir_path.name
|
|
|
|
shutil.copytree(subdir_path, destdir, ignore=shutil.ignore_patterns('build*'))
|
|
|
|
print('Running edm snaphot --recursive')
|
|
cmd_line = ['edm']
|
|
if args.include_external_deps:
|
|
cmd_line.append('--external-in-config')
|
|
cmd_line.extend(['snapshot', '--recursive'])
|
|
with subprocess.Popen(cmd_line, stderr=subprocess.PIPE, cwd=tmp_dir) as edm:
|
|
for line in edm.stderr:
|
|
print(line.decode('utf-8'), end='')
|
|
in_snapshot = tmp_dir / 'snapshot.yaml'
|
|
snapshot = None
|
|
with open(in_snapshot, mode='r', encoding='utf-8') as snapshot_file:
|
|
try:
|
|
snapshot = yaml.safe_load(snapshot_file)
|
|
except yaml.YAMLError as e:
|
|
print(f'Error parsing yaml of {in_snapshot}: {e}')
|
|
if snapshot:
|
|
# check if git_tag is a 40 character hex string and assume it is a git_rev
|
|
if args.git_version:
|
|
for dependency, entry in snapshot.items():
|
|
git_tag = ''
|
|
if 'git_tag' in entry:
|
|
git_tag = entry['git_tag']
|
|
elif 'git_rev' in entry:
|
|
git_tag = entry['git_rev']
|
|
if len(git_tag) == 40 and all(character in string.hexdigits for character in git_tag):
|
|
snapshot[dependency]['git_tag'] = 'git'
|
|
if args.version:
|
|
versions = args.version.split(',')
|
|
for dep_versions in versions:
|
|
dependency, version = dep_versions.split(':')
|
|
if dependency in snapshot:
|
|
print(f'Overriding {dependency} version {snapshot[dependency]["git_tag"]} to {version}')
|
|
snapshot[dependency]['git_tag'] = version
|
|
for dependency, entry in snapshot.items():
|
|
git_tag = ''
|
|
if 'git_tag' in entry:
|
|
git_tag = entry['git_tag']
|
|
if git_tag == 'latest':
|
|
print(f'{dependency} has tag "latest", check if there is a version tag as well')
|
|
dependency_path = tmp_dir / dependency
|
|
tags = get_tags(dependency_path)
|
|
tags.remove('latest')
|
|
if len(tags) == 1:
|
|
print(' Fixing "latest" tag in snapshot')
|
|
snapshot[dependency]['git_tag'] = tags[0]
|
|
else:
|
|
print(f' List of tags with "latest" removed: "{tags}" is not directly usable...')
|
|
|
|
with open(in_snapshot, mode='w', encoding='utf-8') as snapshot_file:
|
|
yaml.safe_dump(snapshot, snapshot_file, indent=2, sort_keys=False, width=120)
|
|
print('Done')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|