Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# -------------------------------------------------------------------------------------------------- 

2# Copyright (c) Lukas Vik. All rights reserved. 

3# 

4# This file is part of the tsfpga project. 

5# https://tsfpga.com 

6# https://gitlab.com/tsfpga/tsfpga 

7# -------------------------------------------------------------------------------------------------- 

8 

9import re 

10import subprocess 

11 

12from tsfpga.system_utils import file_is_in_directory 

13 

14 

15def get_svn_revision_information(cwd=None): 

16 check_that_svn_commands_are_available(cwd) 

17 result = f"r{get_svn_revision(cwd)}" 

18 if svn_local_changes_are_present(cwd): 

19 result += " (local changes present)" 

20 return result 

21 

22 

23def svn_commands_are_available(cwd=None): 

24 try: 

25 get_svn_revision(cwd) 

26 except (subprocess.CalledProcessError, FileNotFoundError): 

27 return False 

28 return True 

29 

30 

31def check_that_svn_commands_are_available(cwd=None): 

32 if not svn_commands_are_available(cwd): 

33 mesg = ( 

34 "Could not run svn. Is the command available on PATH? Is the script called from a repo?" 

35 ) 

36 raise RuntimeError(mesg) 

37 

38 

39def get_svn_revision(cwd=None): 

40 command = ["svn", "info", "--show-item", "revision"] 

41 output = subprocess.check_output(command, cwd=cwd, universal_newlines=True) 

42 # Remove trailing newline 

43 return int(output.strip()) 

44 

45 

46def svn_local_changes_are_present(cwd=None): 

47 """ 

48 Return true if the repo contains changes that have been made after the last commit. 

49 Info from here: https://rubyinrails.com/2014/01/11/svn-command-to-check-modified-files/ 

50 """ 

51 command = ["svn", "status"] 

52 output = subprocess.check_output(command, cwd=cwd, universal_newlines=True) 

53 # Status code for file Added, Deleted, Modified, in Conflict or missing 

54 regexp = re.compile(r"\n[ADMC!] ") 

55 return regexp.search(output) is not None 

56 

57 

58RE_SVN_STATUS_LINE = re.compile(r"^.+\d+\s+\d+\s+\S+\s+(\S+)$") 

59 

60 

61def find_svn_files( 

62 directory, 

63 excludes=None, 

64 file_endings_include=None, 

65 file_endings_avoid=None, 

66): 

67 """ 

68 Find files that are checked in to SVN. It runs "svn status" rather than "svn ls". This means 

69 that it is a local operation, that does not require credentials or any connection with 

70 an SVN server. 

71 

72 Arguments: 

73 directory (`pathlib.Path`): Search in this directory. 

74 excludes (list(`pathlib.Path`)): These files and folders will not be included. 

75 file_endings_include (str or tuple(str)). Only files with these endings will be included. 

76 file_endings_avoid (str or tuple(str)): String or tuple of strings. Files with these endings 

77 will not be included. 

78 

79 Returns: 

80 list(`pathlib.Path`): The files that are available in SVN. 

81 """ 

82 excludes = [] if excludes is None else [exclude.resolve() for exclude in excludes] 

83 

84 command = ["svn", "status", "-v"] 

85 output = subprocess.check_output(command, cwd=directory, universal_newlines=True) 

86 for line in output.split("\n"): 

87 match = RE_SVN_STATUS_LINE.match(line) 

88 if not match: 

89 continue 

90 

91 svn_file = match.group(1) 

92 file_path = directory / svn_file 

93 

94 # Make sure concatenation of relative paths worked 

95 assert file_path.exists(), file_path 

96 

97 if file_path.is_dir(): 

98 continue 

99 

100 if file_endings_include is not None and not file_path.name.endswith(file_endings_include): 

101 continue 

102 

103 if file_endings_avoid is not None and file_path.name.endswith(file_endings_avoid): 

104 continue 

105 

106 if file_is_in_directory(file_path, excludes): 

107 continue 

108 

109 yield file_path