blob: 3244bde57e3e6398a30db638a1cea9c14bd8831d [file] [log] [blame]
Diana Picus3b2ef822016-10-13 16:53:18 +03001"""This is the main tool for handling llvm builds, bisects etc."""
2
3import os
4from sys import exit
5
Diana Picus95226d42017-11-01 13:16:54 +01006from modules.llvm import LLVMSubproject
7from modules.llvm import LLVMSourceConfig
8from modules.llvm import get_remote_branch
9from modules.llvm import push_branch
10
Diana Picus3b2ef822016-10-13 16:53:18 +030011from linaropy.git.clone import Clone
12from linaropy.proj import Proj
13
14from argparse import Action, ArgumentParser, RawTextHelpFormatter
Diana Picusefc7bda2017-06-09 19:14:08 +020015from functools import partial
Diana Picus3b2ef822016-10-13 16:53:18 +030016
17
18def die(message, config_to_dump=None):
19 """Print an error message and exit."""
Diana Picusb4307602017-04-05 19:48:39 +020020 print(message)
Diana Picus3b2ef822016-10-13 16:53:18 +030021
22 if config_to_dump is not None:
23 dump_config(config_to_dump)
24
25 exit(1)
26
Diana Picus3d1a3012017-03-14 17:38:32 +010027
Diana Picus3d1a3012017-03-14 17:38:32 +010028def get_worktree_root(env):
Diana Picus81089db2017-05-05 22:26:49 +020029 """Get the path to the LLVM worktree corresponding to env."""
30 return os.path.join(env, "llvm")
Diana Picus3b2ef822016-10-13 16:53:18 +030031
32
33def dump_config(config):
34 """Dump the list of projects that are enabled in the given config."""
35
Diana Picusb4307602017-04-05 19:48:39 +020036 print("Projects linked:")
Diana Picus3b2ef822016-10-13 16:53:18 +030037 enabled = config.get_enabled_subprojects()
38 if not enabled:
Diana Picusb4307602017-04-05 19:48:39 +020039 print("none")
Diana Picus3b2ef822016-10-13 16:53:18 +030040 else:
41 for subproj in sorted(enabled):
Diana Picusb4307602017-04-05 19:48:39 +020042 print(" + {}".format(subproj))
Diana Picus3b2ef822016-10-13 16:53:18 +030043
44
45def projects(args):
46 """Add/remove subprojects based on the values in args."""
47
48 proj = Proj()
Diana Picus3d1a3012017-03-14 17:38:32 +010049
50 llvm_worktree_root = get_worktree_root(args.env)
Diana Picus81089db2017-05-05 22:26:49 +020051 llvm_repos_root = args.repos
Diana Picus3b2ef822016-10-13 16:53:18 +030052 config = LLVMSourceConfig(proj, llvm_worktree_root)
53
54 if not args.add and not args.remove:
55 # Nothing to change, just print the current configuration
56 dump_config(config)
57 exit(0)
58
59 to_add = {}
60 if args.add:
61 for subproj in args.add:
62 repo = Clone(proj, os.path.join(llvm_repos_root, subproj))
63 to_add[subproj] = repo
64
65 try:
66 config.update(to_add, args.remove)
67 except (EnvironmentError, ValueError) as exc:
68 die("Failed to update subprojects because:\n{}".format(str(exc)))
69
70 dump_config(config)
71
Diana Picusefc7bda2017-06-09 19:14:08 +020072
Diana Picus95226d42017-11-01 13:16:54 +010073def push_current_branch(args):
Diana Picusefc7bda2017-06-09 19:14:08 +020074 """Push current branch to origin."""
75
76 proj = Proj()
77
78 llvm_worktree_root = get_worktree_root(args.env)
79 config = LLVMSourceConfig(proj, llvm_worktree_root)
80
Diana Picus95226d42017-11-01 13:16:54 +010081 llvm_worktree = Clone(proj, llvm_worktree_root)
82 local_branch = llvm_worktree.getbranch()
Diana Picusefc7bda2017-06-09 19:14:08 +020083
84 try:
Diana Picus95226d42017-11-01 13:16:54 +010085 remote_branch = get_remote_branch(llvm_worktree, local_branch)
86 config.for_each_enabled(partial(push_branch, proj, local_branch,
87 remote_branch))
88 print("Pushed to {}".format(remote_branch))
89 except (EnvironmentError, RuntimeError) as exc:
Diana Picusefc7bda2017-06-09 19:14:08 +020090 die("Failed to push branch because: " + str(exc) + str(exc.__cause__))
91
Diana Picus95226d42017-11-01 13:16:54 +010092
Diana Picus3b2ef822016-10-13 16:53:18 +030093##########################################################################
94# Command line parsing #
95##########################################################################
96
97# If we decide we want shorthands for the subprojects, we can append to this
98# list
Diana Picusb4307602017-04-05 19:48:39 +020099valid_subprojects = list(LLVMSubproject.get_all_subprojects().keys())
Diana Picus3b2ef822016-10-13 16:53:18 +0300100
101options = ArgumentParser(formatter_class=RawTextHelpFormatter)
Diana Picus81089db2017-05-05 22:26:49 +0200102options.add_argument(
103 '--env',
104 required=True,
105 help="Path to the environment to update.")
106options.add_argument(
107 '--repos', required=True,
108 help="Path to the directory containing the repositories for all LLVM subprojects.")
Diana Picus3d1a3012017-03-14 17:38:32 +0100109
Diana Picus3b2ef822016-10-13 16:53:18 +0300110subcommands = options.add_subparsers()
111
112# Subcommand for adding / removing subprojects
Diana Picus3d1a3012017-03-14 17:38:32 +0100113projs = subcommands.add_parser("projects", help="Add/remove LLVM subprojects.")
Diana Picus3b2ef822016-10-13 16:53:18 +0300114projs.set_defaults(run_command=projects)
115
116# TODO: Overwriting previous values is not necessarily what users expect (so for
117# instance --add S1 S2 --remove S3 --add S4 would lead to adding only S4). We
118# can do better by using action='append', which would create a list (of lists?
119# or of lists and scalars?) that we can flatten to obtain all the values passed
120# by the user.
121projs.add_argument(
122 '-a', '--add',
123 nargs='+',
124 choices=valid_subprojects,
125 metavar='subproject',
126 help="Link given subprojects. Valid values are:\n\t{}\n".format(
127 "\n\t".join(valid_subprojects)))
128projs.add_argument(
129 '-r', '--remove',
130 nargs='+',
131 choices=valid_subprojects,
132 metavar='subproject',
133 help="Unlink given subprojects.")
134
Diana Picusefc7bda2017-06-09 19:14:08 +0200135# Subcommand for pushing the current branch to origin
136push = subcommands.add_parser(
137 "push",
138 help="Push current branch to origin linaro-local/<user>/<branch>, for all linked subprojects.")
Diana Picus95226d42017-11-01 13:16:54 +0100139push.set_defaults(run_command=push_current_branch)
Diana Picusefc7bda2017-06-09 19:14:08 +0200140
Diana Picus3b2ef822016-10-13 16:53:18 +0300141args = options.parse_args()
142args.run_command(args)