class Worker: """The worker Class.""" def __init__(self, args): """Constructor.""" self.args = args self.git = Git(args) def branches_to_be_deleted(self): """Return branches to be deleted.""" branches = self.branches_to_be_deleted_excluding_skipped() if len(branches) > 0: Formatter.print_pretty_warn_message("Following local branches would \ be deleted:") return branches else: Formatter.print_pretty_fail_message("No branches to be deleted") return [] def branches_to_be_deleted_excluding_skipped(self): """Return branches to be deleted except pattern matching branches.""" branches = list( set( self.git.merged_branches() ).difference( self.git.pattern_matching_branches()) ) self.exclude_current_branch(branches) return branches def delete_branches(self, remote=False): """Delete the branches.""" """If Remote=True, deletes remote branches as well.""" if len(self.branches_to_be_deleted()) > 0: self.delete_local_branches() if remote: self.delete_remote_branches() Formatter.print_pretty_ok_message("Cleaned Successfully!!") def delete_remote_branches(self): """Delete remote branches.""" try: os.popen("git push origin --delete " + " ".join( self.branches_to_be_deleted()) ) except: print "There was an error deleting remote branches: ", sys.exc_info()[0] def delete_local_branches(self): """Delete local branches.""" os.popen("git branch -D " + " ".join(self.branches_to_be_deleted())) def exclude_current_branch(self, branches): """Exclude current branch from list of branches to be deleted.""" if(self.git.current_branch() in branches): branches.remove(self.git.current_branch())
class Worker: """The worker Class.""" def __init__(self, args): """Constructor.""" self.args = args self.git = Git(args) def branches_to_be_deleted(self): """Return branches to be deleted.""" branches = self.branches_to_be_deleted_excluding_skipped() if len(branches) > 0: Formatter.print_pretty_warn_message( "Following local branches would \ be deleted:") return branches else: Formatter.print_pretty_fail_message("No branches to be deleted") return [] def branches_to_be_deleted_excluding_skipped(self): """Return branches to be deleted except pattern matching branches.""" branches = list( set(self.git.merged_branches()).difference( self.git.pattern_matching_branches())) self.exclude_current_branch(branches) return branches def delete_branches(self, remote=False): """Delete the branches.""" """If Remote=True, deletes remote branches as well.""" if len(self.branches_to_be_deleted()) > 0: self.delete_local_branches() if remote: self.delete_remote_branches() Formatter.print_pretty_ok_message("Cleaned Successfully!!") def delete_remote_branches(self): """Delete remote branches.""" try: os.popen("git push origin --delete " + " ".join(self.branches_to_be_deleted())) except: print "There was an error deleting remote branches: ", sys.exc_info()[0] def delete_local_branches(self): """Delete local branches.""" os.popen("git branch -D " + " ".join(self.branches_to_be_deleted())) def exclude_current_branch(self, branches): """Exclude current branch from list of branches to be deleted.""" if (self.git.current_branch() in branches): branches.remove(self.git.current_branch())
def regenerate_includes(work_dir: Path, config: ImportConfig) -> None: for ledger_config in config.ledgers.values(): if work_dir.is_relative_to(ledger_config.ledger_dir): break else: print(f'Current working directory {work_dir} is not inside any known' ' ledger path.') exit(1) print(f'Regenerate includes in {ledger_config.ledger_dir}.') # change working directory for git status to work correctly os.chdir(ledger_config.ledger_dir) git: BaseGit if ledger_config.git_dir is not None: git = Git(ledger_config.ledger_dir, ledger_config.git_dir) import_branch = ledger_config.import_branch else: git = FakeGit() import_branch = git.current_branch() write_include_files(ledger_config.ledger_dir, git)
class Project(): def __init__(self): self.tree = ElementTree(); self.git = Git() if not os.path.exists(PROJECT_CONFIG_PATH): os.mkdir(PROJECT_CONFIG_PATH) try: self.tree.parse(PROJECT_CONFIG_FILE) except: root = Element('Project', {'name':os.path.basename(os.getcwd())}) self.tree._setroot(root) def save(self): self.tree.write(PROJECT_CONFIG_FILE, xml_declaration=True, method="xml") def iter(self): return self.tree.iter('SubProject') def find(self, name): for i in self.iter(): if i.get('name') == name: return i def inSubProject(self): cwd = os.getcwd() for node in self.iter(): name = node.get('name') print("") print("On:%s" % name) print("***************************************") os.chdir("/".join([cwd, name])) yield print("***************************************") def clone(self): for module in self.iter(): self.git.clone(module) def __init_module(self, module): if not os.path.exists(module): print("module %s not exists." % module) return None cwd = os.getcwd() os.chdir("/".join([cwd, module])) if self.git.is_repo(): node = Element('SubProject') node.set("name", module) current_branch = self.git.current_branch() if current_branch != None: node.set("branch", current_branch) remote_uri = self.git.current_remote_uri(branch=current_branch) if remote_uri != None: node.set("uri", remote_uri) else: node = None else: print("fatal: Not a git repository") node = None os.chdir(cwd) return node def __append_ignore_file(self, module): if os.path.exists(".gitignore"): ignoreFile = open(".gitignore","r") for line in ignoreFile: if module == line.strip(): return ignoreFile.close() ignoreFile = open(".gitignore", "a") ignoreFile.write(module + "\n") ignoreFile.close() def __remove_ignore_file(self, modules): if os.path.exists(".gitignore"): ignoreFile = open(".gitignore","r") print modules data = [line.strip() for line in ignoreFile if not (line.strip() in modules)] ignoreFile = open(".gitignore", "w") ignoreFile.write("\n".join(data)+"\n") ignoreFile.close() data = None def append(self, module): if module == None: return -1 node = self.find(module) root = self.tree.getroot() if node != None: root.remove(node) node = self.__init_module(module) if node == None: return -1 else: root.append(node) self.__append_ignore_file(module) self.save() return 0 def remove(self, module=None): if module != None: node = self.find(module) root = self.tree.getroot() if node != None: root.remove(node) self.__remove_ignore_file(module) self.save() else: data = [node.get('name') for node in self.iter()] self.__remove_ignore_file(data)
def main() -> None: aparser = argparse.ArgumentParser( description='import account statement PDFs into hledger') aparser.add_argument('--force', dest='force', default=False, action='store_true', help='overwrite existing ledgers') aparser.add_argument('--dry-run', dest='dry_run', default=False, action='store_true', help='run parsers without writing any output files') aparser.add_argument('--regenerate-includes', dest='regenerate_includes', default=False, action='store_true', help='only regenerate include files; don\'t import ' 'new bank statements') aparser.add_argument('--no-merge', dest='merge', default=True, action='store_false', help='don\'t merge import branch after import') args = aparser.parse_args() xdg = getXDGdirectories('bank-statement-parser') config_file = xdg['config'] / 'import.cfg' config = ImportConfig.read_from_file(config_file) if args.regenerate_includes: regenerate_includes(Path.cwd(), config) exit(0) selection_script = xdg['config'] / 'select_ledger.py' select_ledger: Callable[[BankStatementMetadata], str] if selection_script.exists(): with open(selection_script, 'r') as f: content = f.read() parse_globals: dict[str, Any] = { 'BankStatementMetadata': BankStatementMetadata, } exec(compile(content, selection_script, 'exec'), parse_globals) if 'select_ledger' not in parse_globals: print(f'{selection_script} doesn\'t contain select_ledger' ' function.', file=sys.stderr) exit(1) select_ledger = parse_globals['select_ledger'] elif len(config.ledgers) == 1: ledger_name = next(iter(config.ledgers)) def select_ledger(meta: BankStatementMetadata) -> str: return ledger_name else: print(f'Error: {config_file} contains more than one ledger,' f' but {selection_script} is missing.', file=sys.stderr) exit(1) incoming_statements = get_metadata_of_incoming_statements( config.incoming_dir) classified = sort_incoming_statements_to_ledger_dirs( incoming_statements, select_ledger, ) if any(key not in config.ledgers for key in classified.keys()): for key, statements in classified.items(): if key in config.ledgers: continue mismatched_files = ', '.join(str(s.statement_path) for s in statements) print(f'Error: {mismatched_files} were assigned to unknown ledger' f' configuration {key}. Please check {selection_script}.', file=sys.stderr) exit(1) for key, statements in classified.items(): ledger_config = config.ledgers[key] print(f'Importing bank statements to {ledger_config.ledger_dir}.') # change working directory for git status to work correctly os.chdir(ledger_config.ledger_dir) git: BaseGit if ledger_config.git_dir is not None: git = Git(ledger_config.ledger_dir, ledger_config.git_dir) import_branch = ledger_config.import_branch else: git = FakeGit() import_branch = git.current_branch() try: import_incoming_statements(statements, ledger_config.ledger_dir, git, import_branch, args.force, args.dry_run) except DirtyWorkingDirectoryException: print(f'{ledger_config.ledger_dir} contains uncommitted changes,' ' please commit those before continuing.', file=sys.stderr) exit(1) # The import_transaction in import_incoming_statements automatically # resets the branch to the previously checked-out one after importing # to the import_branch. if (args.merge and isinstance(git, Git) and import_branch != git.current_branch()): try: git.merge(import_branch) except GitMergeConflictError as e: conflicting_files = [ledger_config.ledger_dir / c.name for c in e.conflicts] not_autogenerated = [p for p in conflicting_files if p.name != 'journal.hledger'] if not_autogenerated: raise RuntimeError( 'Could not automerge the following files:\n' + '\n'.join(str(p) for p in not_autogenerated)) write_include_files(ledger_config.ledger_dir, git) git.commit(f"Merge branch '{import_branch}'")