1# Copyright 2022 The Pigweed Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4# use this file except in compliance with the License. You may obtain a copy of 5# the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations under 13# the License. 14"""Serializes an Environment into a JSON file.""" 15 16from __future__ import print_function 17 18import ntpath 19import os 20import posixpath 21import re 22 23# Disable super() warnings since this file must be Python 2 compatible. 24# pylint: disable=super-with-arguments 25 26 27class GNIVisitor(object): # pylint: disable=useless-object-inheritance 28 """Serializes portions of an Environment into a gni file. 29 30 Example gni file: 31 32 declare_args() { 33 pw_env_setup_CIPD_DEFAULT = "//<ENVIRONMENT_DIR>/cipd/packages/default" 34 pw_env_setup_CIPD_PIGWEED = "//<ENVIRONMENT_DIR>/cipd/packages/pigweed" 35 pw_env_setup_CIPD_ARM = "//<ENVIRONMENT_DIR>/cipd/packages/arm" 36 pw_env_setup_CIPD_PYTHON = "//<ENVIRONMENT_DIR>/cipd/packages/python" 37 pw_env_setup_CIPD_BAZEL = "//<ENVIRONMENT_DIR>/cipd/packages/bazel" 38 pw_env_setup_CIPD_LUCI = "//<ENVIRONMENT_DIR>/cipd/packages/luci" 39 pw_env_setup_VIRTUAL_ENV = "//<ENVIRONMENT_DIR>/pigweed-venv" 40 } 41 """ 42 43 def __init__(self, project_root, *args, **kwargs): 44 super(GNIVisitor, self).__init__(*args, **kwargs) 45 self._project_root = project_root 46 self._lines = [] 47 48 def serialize(self, env, outs): 49 self._lines.append( 50 """ 51# This file is automatically generated by Pigweed's environment setup. Do not 52# edit it manually or check it in. 53""".strip() 54 ) 55 56 self._lines.append('declare_args() {') 57 58 env.accept(self) 59 60 self._lines.append('}') 61 62 for line in self._lines: 63 print(line, file=outs) 64 self._lines = [] 65 66 def _abspath_to_gn_path(self, path): 67 gn_path = os.path.relpath(path, start=self._project_root) 68 if os.name == 'nt': 69 # GN paths are posix-style, so convert to posix. This 70 # find-and-replace is a little crude, but python 2.7 doesn't support 71 # pathlib. 72 gn_path = gn_path.replace(ntpath.sep, posixpath.sep) 73 return '//{}'.format(gn_path) 74 75 def visit_set(self, set): # pylint: disable=redefined-builtin 76 match = re.search(r'PW_(.*)_CIPD_INSTALL_DIR', set.name) 77 if match: 78 name = 'pw_env_setup_CIPD_{}'.format(match.group(1)) 79 self._lines.append( 80 ' {} = "{}"'.format(name, self._abspath_to_gn_path(set.value)) 81 ) 82 83 if set.name == 'VIRTUAL_ENV': 84 self._lines.append( 85 ' pw_env_setup_VIRTUAL_ENV = "{}"'.format( 86 self._abspath_to_gn_path(set.value) 87 ) 88 ) 89 90 if set.name == 'PW_PACKAGE_ROOT': 91 self._lines.append( 92 ' pw_env_setup_PACKAGE_ROOT = "{}"'.format( 93 self._abspath_to_gn_path(set.value) 94 ) 95 ) 96 97 def visit_clear(self, clear): 98 pass 99 100 def visit_remove(self, remove): 101 pass 102 103 def visit_prepend(self, prepend): 104 pass 105 106 def visit_append(self, append): 107 pass 108 109 def visit_echo(self, echo): 110 pass 111 112 def visit_comment(self, comment): 113 pass 114 115 def visit_command(self, command): 116 pass 117 118 def visit_doctor(self, doctor): 119 pass 120 121 def visit_blank_line(self, blank_line): 122 pass 123 124 def visit_function(self, function): 125 pass 126 127 def visit_hash(self, hash): # pylint: disable=redefined-builtin 128 pass 129