blob: 13ee258e7ad78237231a882475e39f0bb3908135 [file] [log] [blame]
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001# Development tool - export command plugin
2#
3# Copyright (C) 2014-2017 Intel Corporation
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License version 2 as
7# published by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc.,
16# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17"""Devtool export plugin"""
18
19import os
20import argparse
21import tarfile
22import logging
23import datetime
24import json
25
26logger = logging.getLogger('devtool')
27
28# output files
29default_arcname_prefix = "workspace-export"
30metadata = '.export_metadata'
31
32def export(args, config, basepath, workspace):
33 """Entry point for the devtool 'export' subcommand"""
34
35 def add_metadata(tar):
36 """Archive the workspace object"""
37 # finally store the workspace metadata
38 with open(metadata, 'w') as fd:
39 fd.write(json.dumps((config.workspace_path, workspace)))
40 tar.add(metadata)
41 os.unlink(metadata)
42
43 def add_recipe(tar, recipe, data):
44 """Archive recipe with proper arcname"""
45 # Create a map of name/arcnames
46 arcnames = []
47 for key, name in data.items():
48 if name:
49 if key == 'srctree':
50 # all sources, no matter where are located, goes into the sources directory
51 arcname = 'sources/%s' % recipe
52 else:
53 arcname = name.replace(config.workspace_path, '')
54 arcnames.append((name, arcname))
55
56 for name, arcname in arcnames:
57 tar.add(name, arcname=arcname)
58
59
60 # Make sure workspace is non-empty and possible listed include/excluded recipes are in workspace
61 if not workspace:
62 logger.info('Workspace contains no recipes, nothing to export')
63 return 0
64 else:
65 for param, recipes in {'include':args.include,'exclude':args.exclude}.items():
66 for recipe in recipes:
67 if recipe not in workspace:
68 logger.error('Recipe (%s) on %s argument not in the current workspace' % (recipe, param))
69 return 1
70
71 name = args.file
72
73 default_name = "%s-%s.tar.gz" % (default_arcname_prefix, datetime.datetime.now().strftime('%Y%m%d%H%M%S'))
74 if not name:
75 name = default_name
76 else:
77 # if name is a directory, append the default name
78 if os.path.isdir(name):
79 name = os.path.join(name, default_name)
80
81 if os.path.exists(name) and not args.overwrite:
82 logger.error('Tar archive %s exists. Use --overwrite/-o to overwrite it')
83 return 1
84
85 # if all workspace is excluded, quit
86 if not len(set(workspace.keys()).difference(set(args.exclude))):
87 logger.warn('All recipes in workspace excluded, nothing to export')
88 return 0
89
90 exported = []
91 with tarfile.open(name, 'w:gz') as tar:
92 if args.include:
93 for recipe in args.include:
94 add_recipe(tar, recipe, workspace[recipe])
95 exported.append(recipe)
96 else:
97 for recipe, data in workspace.items():
98 if recipe not in args.exclude:
99 add_recipe(tar, recipe, data)
100 exported.append(recipe)
101
102 add_metadata(tar)
103
104 logger.info('Tar archive created at %s with the following recipes: %s' % (name, ', '.join(exported)))
105 return 0
106
107def register_commands(subparsers, context):
108 """Register devtool export subcommands"""
109 parser = subparsers.add_parser('export',
110 help='Export workspace into a tar archive',
111 description='Export one or more recipes from current workspace into a tar archive',
112 group='advanced')
113
114 parser.add_argument('--file', '-f', help='Output archive file name')
115 parser.add_argument('--overwrite', '-o', action="store_true", help='Overwrite previous export tar archive')
116 group = parser.add_mutually_exclusive_group()
117 group.add_argument('--include', '-i', nargs='+', default=[], help='Include recipes into the tar archive')
118 group.add_argument('--exclude', '-e', nargs='+', default=[], help='Exclude recipes into the tar archive')
119 parser.set_defaults(func=export)