1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import os
20 import sys
21
22 import apt_pkg
23
24 from daklib.config import Config
25 from daklib.dbconn import ArchiveFile, DBConn, Suite
26 from daklib.fstransactions import FilesystemTransaction
27
28
30 print(
31 """Usage: dak export-suite -s <suite> [options]
32
33 Export binaries and sources from a suite to a flat directory structure.
34
35 -c --copy copy files instead of symlinking them
36 -d <directory> target directory to export packages to
37 default: current directory
38 -r --relative use symlinks relative to target directory
39 -s <suite> suite to grab uploads from
40 """
41 )
42
43
45 if argv is None:
46 argv = sys.argv
47
48 arguments = [
49 ("h", "help", "Export::Options::Help"),
50 ("c", "copy", "Export::Options::Copy"),
51 ("d", "directory", "Export::Options::Directory", "HasArg"),
52 ("r", "relative", "Export::Options::Relative"),
53 ("s", "suite", "Export::Options::Suite", "HasArg"),
54 ]
55
56 cnf = Config()
57 apt_pkg.parse_commandline(cnf.Cnf, arguments, argv)
58 options = cnf.subtree("Export::Options")
59
60 if "Help" in options or "Suite" not in options:
61 usage()
62 sys.exit(0)
63
64 session = DBConn().session()
65
66 suite = session.query(Suite).filter_by(suite_name=options["Suite"]).first()
67 if suite is None:
68 print("Unknown suite '{0}'".format(options["Suite"]))
69 sys.exit(1)
70
71 directory = options.get("Directory")
72 if not directory:
73 print("No target directory.")
74 sys.exit(1)
75
76 symlink = "Copy" not in options
77 relative = "Relative" in options
78
79 if relative and not symlink:
80 print("E: --relative and --copy cannot be used together.")
81 sys.exit(1)
82
83 binaries = suite.binaries
84 sources = suite.sources
85
86 files = []
87 files.extend([b.poolfile for b in binaries])
88 for s in sources:
89 files.extend([ds.poolfile for ds in s.srcfiles])
90
91 with FilesystemTransaction() as fs:
92 for f in files:
93 af = (
94 session.query(ArchiveFile)
95 .join(ArchiveFile.component)
96 .join(ArchiveFile.file)
97 .filter(ArchiveFile.archive == suite.archive)
98 .filter(ArchiveFile.file == f)
99 .first()
100 )
101 src = af.path
102 if relative:
103 src = os.path.relpath(src, directory)
104 dst = os.path.join(directory, f.basename)
105 if not os.path.exists(dst):
106 fs.copy(src, dst, symlink=symlink)
107 fs.commit()
108
109
110 if __name__ == "__main__":
111 main()
112