Coverage for dak/export_suite.py: 30%

50 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2026-08-03 16:46 +0000

1# Copyright (C) 2012, Ansgar Burchardt <ansgar@debian.org> 

2# 

3# This program is free software; you can redistribute it and/or modify 

4# it under the terms of the GNU General Public License as published by 

5# the Free Software Foundation; either version 2 of the License, or 

6# (at your option) any later version. 

7# 

8# This program is distributed in the hope that it will be useful, 

9# but WITHOUT ANY WARRANTY; without even the implied warranty of 

10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

11# GNU General Public License for more details. 

12# 

13# You should have received a copy of the GNU General Public License along 

14# with this program; if not, write to the Free Software Foundation, Inc., 

15# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 

16 

17import os 

18import sys 

19 

20import apt_pkg 

21from sqlalchemy import select 

22 

23from daklib.config import Config 

24from daklib.dbconn import ArchiveFile, DBConn, Suite 

25from daklib.fstransactions import FilesystemTransaction 

26 

27 

28def usage(): 

29 print( 

30 """Usage: dak export-suite -s <suite> [options] 

31 

32Export binaries and sources from a suite to a flat directory structure. 

33 

34 -c --copy copy files instead of symlinking them 

35 -d <directory> target directory to export packages to 

36 default: current directory 

37 -r --relative use symlinks relative to target directory 

38 -s <suite> suite to grab uploads from 

39""" 

40 ) 

41 

42 

43def main(argv=None): 

44 if argv is None: 44 ↛ 47line 44 didn't jump to line 47

45 argv = sys.argv 

46 

47 arguments = [ 

48 ("h", "help", "Export::Options::Help"), 

49 ("c", "copy", "Export::Options::Copy"), 

50 ("d", "directory", "Export::Options::Directory", "HasArg"), 

51 ("r", "relative", "Export::Options::Relative"), 

52 ("s", "suite", "Export::Options::Suite", "HasArg"), 

53 ] 

54 

55 cnf = Config() 

56 apt_pkg.parse_commandline(cnf.Cnf, arguments, argv) # type: ignore[attr-defined] 

57 options = cnf.subtree("Export::Options") 

58 

59 if "Help" in options or "Suite" not in options: 59 ↛ 63line 59 didn't jump to line 63 because the condition on line 59 was always true

60 usage() 

61 sys.exit(0) 

62 

63 session = DBConn().session() 

64 

65 suite = session.scalars( 

66 select(Suite).filter_by(suite_name=options["Suite"]).limit(1) 

67 ).first() 

68 if suite is None: 

69 print("Unknown suite '{0}'".format(options["Suite"])) 

70 sys.exit(1) 

71 

72 directory = options.get("Directory") 

73 if not directory: 

74 print("No target directory.") 

75 sys.exit(1) 

76 

77 symlink = "Copy" not in options 

78 relative = "Relative" in options 

79 

80 if relative and not symlink: 

81 print("E: --relative and --copy cannot be used together.") 

82 sys.exit(1) 

83 

84 binaries = suite.binaries 

85 sources = suite.sources 

86 

87 files = [] 

88 files.extend([b.poolfile for b in binaries]) 

89 for s in sources: 

90 files.extend([ds.poolfile for ds in s.srcfiles]) 

91 

92 with FilesystemTransaction() as fs: 

93 for f in files: 

94 af = session.scalars( 

95 select(ArchiveFile) 

96 .join(ArchiveFile.component) 

97 .join(ArchiveFile.file) 

98 .where(ArchiveFile.archive == suite.archive) 

99 .where(ArchiveFile.file == f) 

100 .limit(1) 

101 ).first() 

102 assert af is not None 

103 src = af.path 

104 if relative: 

105 src = os.path.relpath(src, directory) 

106 dst = os.path.join(directory, f.basename) 

107 if not os.path.exists(dst): 

108 fs.copy(src, dst, symlink=symlink) 

109 fs.commit()