link-tool now could generate configuration
This commit is contained in:
parent
4cf9ab1ea1
commit
3d3ba6c378
80
link-tool.py
Normal file → Executable file
80
link-tool.py
Normal file → Executable file
|
|
@ -2,11 +2,26 @@
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import dataclasses
|
import dataclasses
|
||||||
import os
|
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
from string import Template
|
||||||
from typing import List, Tuple, Union
|
from typing import List, Tuple, Union
|
||||||
|
|
||||||
|
|
||||||
|
configuration_template = Template(
|
||||||
|
'''
|
||||||
|
cwd = $cwd
|
||||||
|
|
||||||
|
# Generated by link-tool.py
|
||||||
|
# $link_tool_cmd
|
||||||
|
|
||||||
|
$link_rules
|
||||||
|
''')
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@dataclasses.dataclass(repr=True)
|
@dataclasses.dataclass(repr=True)
|
||||||
|
|
@ -87,6 +102,38 @@ def make_link(links: List[Link], dry_run=False, overwrite=False):
|
||||||
if not dry_run:
|
if not dry_run:
|
||||||
os.link(link.src, link.dst)
|
os.link(link.src, link.dst)
|
||||||
|
|
||||||
|
def generate_configuration(src: str, dst: str, config_path: str):
|
||||||
|
config_path_depth = config_path.strip('/').count('/')
|
||||||
|
cwd = '.' if config_path_depth == 0 else '..' + '/..' * (config_path_depth - 1)
|
||||||
|
|
||||||
|
logger.info('configuration: cwd: {}'.format(cwd))
|
||||||
|
|
||||||
|
link_rules = []
|
||||||
|
for dirname, _, files in os.walk(src):
|
||||||
|
for file in files:
|
||||||
|
link_rules.append(Link(src=os.path.join(dirname, file),
|
||||||
|
dst=os.path.join(dst, os.path.basename(file))))
|
||||||
|
|
||||||
|
max_src_file_path_len = max([len(l.src) for l in link_rules])
|
||||||
|
formater = '{:%d} -> {}' % max_src_file_path_len
|
||||||
|
link_rules_str = ''
|
||||||
|
for l in link_rules:
|
||||||
|
link_rules_str += formater.format(l.src, l.dst) + '\n'
|
||||||
|
|
||||||
|
configuration_str = configuration_template.safe_substitute(
|
||||||
|
cwd=cwd,
|
||||||
|
link_rules=link_rules_str,
|
||||||
|
link_tool_cmd="'{}'".format("' '".join(sys.argv)))
|
||||||
|
|
||||||
|
# create parent dir for configuration file
|
||||||
|
configuration_dir = os.path.dirname(config_path)
|
||||||
|
if not os.path.exists(configuration_dir):
|
||||||
|
os.makedirs(configuration_dir)
|
||||||
|
|
||||||
|
# write configuration file
|
||||||
|
with open(config_path, 'w', encoding='utf-8') as f:
|
||||||
|
f.write(configuration_str)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('-c', '--config', required=True,
|
parser.add_argument('-c', '--config', required=True,
|
||||||
|
|
@ -98,26 +145,43 @@ def main():
|
||||||
parser.add_argument('-v', '--verbose', action='store_true',
|
parser.add_argument('-v', '--verbose', action='store_true',
|
||||||
help='more verbose log')
|
help='more verbose log')
|
||||||
|
|
||||||
|
parser.add_argument('-g', '--generate', action='store_true',
|
||||||
|
help='generate configuration with a predefined template, '
|
||||||
|
'need other arguments. When this argument is used, '
|
||||||
|
'the generated configuration will be place to the path of --config')
|
||||||
|
parser.add_argument('--src', default=None,
|
||||||
|
help='src directory, link rule will be generate for '
|
||||||
|
'every file in this (sub)directory')
|
||||||
|
parser.add_argument('--dst', default=None,
|
||||||
|
help='dst directory, link rule\'target directory')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
config_path = args.config
|
logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO)
|
||||||
verbose = args.verbose
|
|
||||||
|
if args.generate:
|
||||||
|
if args.src is None or args.dst is None:
|
||||||
|
logger.error('invalid argument, --src or --dst is not specified')
|
||||||
|
exit(1)
|
||||||
|
if '..' in args.config:
|
||||||
|
logger.error('configuration file path must not contain any \'..\'')
|
||||||
|
else:
|
||||||
|
generate_configuration(args.src, args.dst, args.config)
|
||||||
|
else:
|
||||||
dry_run = args.dry_run
|
dry_run = args.dry_run
|
||||||
overwrite = args.overwrite
|
overwrite = args.overwrite
|
||||||
|
|
||||||
logging.basicConfig(level=logging.DEBUG if verbose else logging.INFO)
|
config, links = load_config(args.config)
|
||||||
|
|
||||||
config, links = load_config(config_path)
|
|
||||||
|
|
||||||
if not config.validate():
|
if not config.validate():
|
||||||
logger.error('invalid configuration, exiting...')
|
logger.error('invalid configuration, exiting...')
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
for link in links:
|
for link in links:
|
||||||
logger.info('loaded link: {}'.format(link))
|
logger.debug('loaded link: {}'.format(link))
|
||||||
|
|
||||||
assert(config.cwd is not None)
|
assert(config.cwd is not None)
|
||||||
config_path_dir = os.path.dirname(config_path)
|
config_path_dir = os.path.dirname(args.config)
|
||||||
chdir_target = os.path.join(config_path_dir, config.cwd)
|
chdir_target = os.path.join(config_path_dir, config.cwd)
|
||||||
logger.info('changing CWD: {}/{}'.format(config_path_dir, config.cwd))
|
logger.info('changing CWD: {}/{}'.format(config_path_dir, config.cwd))
|
||||||
logger.info('the CWD realpath: {}'.format(os.path.realpath(chdir_target)))
|
logger.info('the CWD realpath: {}'.format(os.path.realpath(chdir_target)))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue