Fix: circular dependency between bootstrap and projects cache
[deliverable/lttng-ivc.git] / lttng_ivc / bootstrap.py
1 import sys
2 import os
3 import yaml
4 import logging
5 import hashlib
6
7 from git import Repo
8
9 dir_path = os.path.dirname(os.path.realpath(__file__))
10 sys.path.insert(0, os.path.join(dir_path, ".."))
11
12 import settings as Settings
13
14 def is_ref_branch(repo, ref):
15 try:
16 repo.remote().refs[ref]
17 is_branch = True
18 except:
19 is_branch = False
20
21 return is_branch
22
23
24 def is_ref_tag(repo, ref):
25 try:
26 repo.tags[ref]
27 is_tag = True
28 except:
29 is_tag = False
30
31 return is_tag
32
33
34 def is_ref_commit(repo, ref):
35 try:
36 Repo.rev_parse(repo, ref)
37 is_commit = True
38 except:
39 is_commit = False
40
41 return is_commit
42
43
44 def logging_setup():
45 logger_format = '%(asctime)s %(name)-12s %(levelname)-8s %(message)s'
46 logging.basicConfig(level=logging.DEBUG,
47 format=logger_format,
48 datefmt='%m-%d %H:%M',
49 filename='./debug.log',
50 filemode='w')
51 # define a Handler which writes INFO messages or higher to the sys.stderr
52 console = logging.StreamHandler()
53 console.setLevel(logging.DEBUG)
54 # set a format which is simpler for console use
55 formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
56 # tell the handler to use this format
57 console.setFormatter(formatter)
58 # add the handler to the root logger
59 logging.getLogger('').addHandler(console)
60
61
62 logging_setup()
63
64 # Remote setup
65 logger_git = logging.getLogger('setup.git')
66
67 # Fetch local base repository
68 with open(Settings.configuration_file, 'r') as stream:
69 config = yaml.load(stream)
70
71 # Validate that all default dependancy are present.
72 # TODO: move to function
73 projects_markers = set()
74 for project, markers in config.items():
75 if markers is None:
76 continue
77 for marker in markers:
78 projects_markers.add(marker['marker'])
79
80 for project, markers in config.items():
81 if markers is None:
82 continue
83 for marker in markers:
84 if 'precook_deps' in marker:
85 for dep in marker['precook_deps']:
86 if dep not in projects_markers:
87 raise Exception("{} is not defined".format(dep))
88
89
90 # Retrieve all possibles remotes and clean url for path
91 remotes = {}
92 for project, markers in config.items():
93 if markers is None:
94 continue
95 for marker in markers:
96 url = marker['url']
97 url2path = hashlib.sha1(url.encode('utf8')).hexdigest()
98 path = os.path.abspath(Settings.git_remote_folder + '/' + url2path)
99 remotes[url] = path
100
101 logger_git.info('Remotes to be fetched {}'.format(remotes))
102
103 if not os.path.isdir(Settings.git_remote_folder):
104 os.makedirs(Settings.git_remote_folder)
105
106 # Fetch the remote
107 for url, path in remotes.items():
108 if os.path.exists(path):
109 if not os.path.isdir(path):
110 logger_git.error('Remote path {} exists and is not a folder'.format(path))
111 exit()
112 repo = Repo(path)
113 else:
114 repo = Repo.clone_from(url, path)
115
116 # TODO: might be necessary to actually update the base branch, to validate
117 repo.remote().fetch()
118
119 # Create marker definition for test runners
120 runnable_markers = {}
121 for project, markers in config.items():
122 if markers is None:
123 continue
124 for marker in markers:
125 name = marker['marker']
126 ref = marker['ref']
127 url = marker['url']
128 if 'precook_deps' in marker:
129 deps = marker['precook_deps']
130 else:
131 deps = []
132
133 path = remotes[url]
134 repo = Repo(path)
135
136 git_object = None
137 if is_ref_branch(repo, ref):
138 git_object = Repo.rev_parse(repo, repo.remote().refs[ref].name)
139 elif is_ref_tag(repo, ref):
140 git_object = repo.tags[ref].commit
141 elif is_ref_commit(repo, ref):
142 git_object = repo.commit(ref)
143
144 if git_object is None:
145 logger_git.error('Invalid git reference for marker "{}"'.format(name))
146 exit(1)
147
148 logger_git.info('Marker:{: <30} Sha1 {: <20}'.format(name, git_object.hexsha))
149
150 if name in runnable_markers:
151 logger_git.error('Duplicate for entry for marker "{}"'.format(name))
152 exit(1)
153
154 runnable_markers[name] = {
155 'project': project,
156 'sha1': git_object.hexsha,
157 'url': url,
158 'path': path,
159 'deps': deps
160 }
161
162 with open(Settings.run_configuration_file, 'w') as run_configuration:
163 yaml.dump(runnable_markers, run_configuration, default_flow_style=False)
This page took 0.03314 seconds and 5 git commands to generate.