def run_standard_syncs(projectroot: Path, mode: Mode, syncitems: Sequence[SyncItem]) -> None: """Run a standard set of syncs. Syncitems should be a list of tuples consisting of a src project name, a src subpath, and optionally a dst subpath (src will be used by default). """ from efrotools import getlocalconfig localconfig = getlocalconfig(projectroot) for syncitem in syncitems: assert isinstance(syncitem, SyncItem) src_project = syncitem.src_project_id src_subpath = syncitem.src_path dst_subpath = (syncitem.dst_path if syncitem.dst_path is not None else syncitem.src_path) dstname = os.path.basename(dst_subpath) if mode == Mode.CHECK: print(f'Checking sync target {dstname}...') count = check_path(Path(dst_subpath)) print(f'Sync check passed for {count} items.') else: link_entry = f'linked_{src_project}' # Actual syncs require localconfig entries. if link_entry not in localconfig: print(f'No link entry for {src_project}; skipping sync entry.') continue src = Path(localconfig[link_entry], src_subpath) print(f'Processing {dstname} in {mode.name} mode...') count = sync_paths(src_project, src, Path(dst_subpath), mode) if mode in [Mode.LIST, Mode.CHECK]: print(f'Scanned {count} items.') else: print(f'Sync successful for {count} items.')
def push_ipa(root: pathlib.Path, modename: str) -> None: """Construct ios IPA and push it to staging server for device testing. This takes some shortcuts to minimize turnaround time; It doesn't recreate the ipa completely each run, uses rsync for speedy pushes to the staging server, etc. The use case for this is quick build iteration on a device that is not physically near the build machine. """ # Load both the local and project config data. cfg = Config(**getconfig(root)['push_ipa_config']) lcfg = LocalConfig(**getlocalconfig(root)['push_ipa_local_config']) if modename not in MODES: raise Exception('invalid mode: "' + str(modename) + '"') mode = MODES[modename] pcommand_path = pathlib.Path(root, 'tools/pcommand') xcprojpath = pathlib.Path(root, cfg.projectpath) app_dir = subprocess.run( [pcommand_path, 'xcode_build_path', xcprojpath, mode['configuration']], check=True, capture_output=True).stdout.decode().strip() built_app_path = pathlib.Path(app_dir, cfg.app_bundle_name) workdir = pathlib.Path(root, 'build', 'push_ipa') workdir.mkdir(parents=True, exist_ok=True) pathlib.Path(root, 'build').mkdir(parents=True, exist_ok=True) exportoptionspath = pathlib.Path(root, workdir, 'exportoptions.plist') ipa_dir_path = pathlib.Path(root, workdir, 'ipa') ipa_dir_path.mkdir(parents=True, exist_ok=True) # Inject our latest build into an existing xcarchive (creating if needed). archivepath = _add_build_to_xcarchive(workdir, xcprojpath, built_app_path, cfg) # Export an IPA from said xcarchive. ipa_path = _export_ipa_from_xcarchive(archivepath, exportoptionspath, ipa_dir_path, cfg) # And lastly sync said IPA up to our staging server. print('Pushing to staging server...') sys.stdout.flush() subprocess.run( [ 'rsync', '--verbose', ipa_path, '-e', 'ssh -oBatchMode=yes -oStrictHostKeyChecking=yes', f'{lcfg.sftp_host}:{lcfg.sftp_dir}' ], check=True, ) print('iOS Package Updated Successfully!')
def __init__(self, check: bool, fix: bool) -> None: from efrotools import getconfig, getlocalconfig from pathlib import Path self._check = check self._fix = fix self._checkarg = ' --check' if self._check else '' # We behave differently in the public repo self._public = getconfig(Path('.'))['public'] assert isinstance(self._public, bool) self._source_files: List[str] = [] self._header_files: List[str] = [] self._line_corrections: Dict[str, List[LineChange]] = {} self._file_changes: Dict[str, str] = {} self._copyright_checks = bool( getlocalconfig(Path('.')).get('copyright_checks', True))
def __init__(self, check: bool, fix: bool) -> None: from efrotools import getconfig, getlocalconfig from pathlib import Path self._check = check self._fix = fix self._checkarg = ' --check' if self._check else '' self._checkarglist: list[str] = ['--check'] if self._check else [] # We behave differently in the public repo self._public = getconfig(Path('.'))['public'] assert isinstance(self._public, bool) self._source_files: list[str] = [] self._header_files: list[str] = [] self._line_corrections: dict[str, list[LineChange]] = {} self._file_changes: dict[str, str] = {} self._license_line_checks = bool( getlocalconfig(Path('.')).get('license_line_checks', True)) self._internal_source_dirs: Optional[set[str]] = None self._internal_source_files: Optional[set[str]] = None