wraptool.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. # Copyright 2015-2016 The Meson development team
  2. # Licensed under the Apache License, Version 2.0 (the "License");
  3. # you may not use this file except in compliance with the License.
  4. # You may obtain a copy of the License at
  5. # http://www.apache.org/licenses/LICENSE-2.0
  6. # Unless required by applicable law or agreed to in writing, software
  7. # distributed under the License is distributed on an "AS IS" BASIS,
  8. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. # See the License for the specific language governing permissions and
  10. # limitations under the License.
  11. import json
  12. import sys, os
  13. import configparser
  14. import shutil
  15. import argparse
  16. from glob import glob
  17. from .wrap import API_ROOT, open_wrapdburl
  18. from .. import mesonlib
  19. def add_arguments(parser):
  20. subparsers = parser.add_subparsers(title='Commands', dest='command')
  21. subparsers.required = True
  22. p = subparsers.add_parser('list', help='show all available projects')
  23. p.set_defaults(wrap_func=list_projects)
  24. p = subparsers.add_parser('search', help='search the db by name')
  25. p.add_argument('name')
  26. p.set_defaults(wrap_func=search)
  27. p = subparsers.add_parser('install', help='install the specified project')
  28. p.add_argument('name')
  29. p.set_defaults(wrap_func=install)
  30. p = subparsers.add_parser('update', help='update the project to its newest available release')
  31. p.add_argument('name')
  32. p.set_defaults(wrap_func=update)
  33. p = subparsers.add_parser('info', help='show available versions of a project')
  34. p.add_argument('name')
  35. p.set_defaults(wrap_func=info)
  36. p = subparsers.add_parser('status', help='show installed and available versions of your projects')
  37. p.set_defaults(wrap_func=status)
  38. p = subparsers.add_parser('promote', help='bring a subsubproject up to the master project')
  39. p.add_argument('project_path')
  40. p.set_defaults(wrap_func=promote)
  41. def get_result(urlstring):
  42. u = open_wrapdburl(urlstring)
  43. data = u.read().decode('utf-8')
  44. jd = json.loads(data)
  45. if jd['output'] != 'ok':
  46. print('Got bad output from server.')
  47. print(data)
  48. sys.exit(1)
  49. return jd
  50. def get_projectlist():
  51. jd = get_result(API_ROOT + 'projects')
  52. projects = jd['projects']
  53. return projects
  54. def list_projects(options):
  55. projects = get_projectlist()
  56. for p in projects:
  57. print(p)
  58. def search(options):
  59. name = options.name
  60. jd = get_result(API_ROOT + 'query/byname/' + name)
  61. for p in jd['projects']:
  62. print(p)
  63. def get_latest_version(name):
  64. jd = get_result(API_ROOT + 'query/get_latest/' + name)
  65. branch = jd['branch']
  66. revision = jd['revision']
  67. return branch, revision
  68. def install(options):
  69. name = options.name
  70. if not os.path.isdir('subprojects'):
  71. print('Subprojects dir not found. Run this script in your source root directory.')
  72. sys.exit(1)
  73. if os.path.isdir(os.path.join('subprojects', name)):
  74. print('Subproject directory for this project already exists.')
  75. sys.exit(1)
  76. wrapfile = os.path.join('subprojects', name + '.wrap')
  77. if os.path.exists(wrapfile):
  78. print('Wrap file already exists.')
  79. sys.exit(1)
  80. (branch, revision) = get_latest_version(name)
  81. u = open_wrapdburl(API_ROOT + 'projects/%s/%s/%s/get_wrap' % (name, branch, revision))
  82. data = u.read()
  83. with open(wrapfile, 'wb') as f:
  84. f.write(data)
  85. print('Installed', name, 'branch', branch, 'revision', revision)
  86. def get_current_version(wrapfile):
  87. cp = configparser.ConfigParser()
  88. cp.read(wrapfile)
  89. cp = cp['wrap-file']
  90. patch_url = cp['patch_url']
  91. arr = patch_url.split('/')
  92. branch = arr[-3]
  93. revision = int(arr[-2])
  94. return branch, revision, cp['directory'], cp['source_filename'], cp['patch_filename']
  95. def update(options):
  96. name = options.name
  97. if not os.path.isdir('subprojects'):
  98. print('Subprojects dir not found. Run this command in your source root directory.')
  99. sys.exit(1)
  100. wrapfile = os.path.join('subprojects', name + '.wrap')
  101. if not os.path.exists(wrapfile):
  102. print('Project', name, 'is not in use.')
  103. sys.exit(1)
  104. (branch, revision, subdir, src_file, patch_file) = get_current_version(wrapfile)
  105. (new_branch, new_revision) = get_latest_version(name)
  106. if new_branch == branch and new_revision == revision:
  107. print('Project', name, 'is already up to date.')
  108. sys.exit(0)
  109. u = open_wrapdburl(API_ROOT + 'projects/%s/%s/%d/get_wrap' % (name, new_branch, new_revision))
  110. data = u.read()
  111. shutil.rmtree(os.path.join('subprojects', subdir), ignore_errors=True)
  112. try:
  113. os.unlink(os.path.join('subprojects/packagecache', src_file))
  114. except FileNotFoundError:
  115. pass
  116. try:
  117. os.unlink(os.path.join('subprojects/packagecache', patch_file))
  118. except FileNotFoundError:
  119. pass
  120. with open(wrapfile, 'wb') as f:
  121. f.write(data)
  122. print('Updated', name, 'to branch', new_branch, 'revision', new_revision)
  123. def info(options):
  124. name = options.name
  125. jd = get_result(API_ROOT + 'projects/' + name)
  126. versions = jd['versions']
  127. if not versions:
  128. print('No available versions of', name)
  129. sys.exit(0)
  130. print('Available versions of %s:' % name)
  131. for v in versions:
  132. print(' ', v['branch'], v['revision'])
  133. def do_promotion(from_path, spdir_name):
  134. if os.path.isfile(from_path):
  135. assert(from_path.endswith('.wrap'))
  136. shutil.copy(from_path, spdir_name)
  137. elif os.path.isdir(from_path):
  138. sproj_name = os.path.basename(from_path)
  139. outputdir = os.path.join(spdir_name, sproj_name)
  140. if os.path.exists(outputdir):
  141. sys.exit('Output dir %s already exists. Will not overwrite.' % outputdir)
  142. shutil.copytree(from_path, outputdir, ignore=shutil.ignore_patterns('subprojects'))
  143. def promote(options):
  144. argument = options.project_path
  145. path_segment, subproject_name = os.path.split(argument)
  146. spdir_name = 'subprojects'
  147. sprojs = mesonlib.detect_subprojects(spdir_name)
  148. if subproject_name not in sprojs:
  149. sys.exit('Subproject %s not found in directory tree.' % subproject_name)
  150. matches = sprojs[subproject_name]
  151. if len(matches) == 1:
  152. do_promotion(matches[0], spdir_name)
  153. return
  154. if path_segment == '':
  155. print('There are many versions of %s in tree. Please specify which one to promote:\n' % subproject_name)
  156. for s in matches:
  157. print(s)
  158. sys.exit(1)
  159. system_native_path_argument = argument.replace('/', os.sep)
  160. if system_native_path_argument in matches:
  161. do_promotion(argument, spdir_name)
  162. def status(options):
  163. print('Subproject status')
  164. for w in glob('subprojects/*.wrap'):
  165. name = os.path.basename(w)[:-5]
  166. try:
  167. (latest_branch, latest_revision) = get_latest_version(name)
  168. except Exception:
  169. print('', name, 'not available in wrapdb.')
  170. continue
  171. try:
  172. (current_branch, current_revision, _, _, _) = get_current_version(w)
  173. except Exception:
  174. print('Wrap file not from wrapdb.')
  175. continue
  176. if current_branch == latest_branch and current_revision == latest_revision:
  177. print('', name, 'up to date. Branch %s, revision %d.' % (current_branch, current_revision))
  178. else:
  179. print('', name, 'not up to date. Have %s %d, but %s %d is available.' % (current_branch, current_revision, latest_branch, latest_revision))
  180. def run(args):
  181. parser = argparse.ArgumentParser(prog='wraptool')
  182. add_arguments(parser)
  183. options = parser.parse_args(args)
  184. options.wrap_func(options)
  185. if __name__ == '__main__':
  186. sys.exit(run(sys.argv[1:]))