1## @file
2# manage multiple workspace file.
3#
4# This file is required to make Python interpreter treat the directory
5# as containing package.
6#
7# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
8# This program and the accompanying materials
9# are licensed and made available under the terms and conditions of the BSD License
10# which accompanies this distribution.  The full text of the license may be found at
11# http://opensource.org/licenses/bsd-license.php
12#
13# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15#
16
17import Common.LongFilePathOs as os
18from Common.DataType import TAB_WORKSPACE
19
20## MultipleWorkspace
21#
22# This class manage multiple workspace behavior
23#
24# @param class:
25#
26# @var WORKSPACE:      defined the current WORKSPACE
27# @var PACKAGES_PATH:  defined the other WORKSAPCE, if current WORKSPACE is invalid, search valid WORKSPACE from PACKAGES_PATH
28#
29class MultipleWorkspace(object):
30    WORKSPACE = ''
31    PACKAGES_PATH = None
32
33    ## convertPackagePath()
34    #
35    #   Convert path to match workspace.
36    #
37    #   @param  cls          The class pointer
38    #   @param  Ws           The current WORKSPACE
39    #   @param  Path         Path to be converted to match workspace.
40    #
41    @classmethod
42    def convertPackagePath(cls, Ws, Path):
43        if str(os.path.normcase (Path)).startswith(Ws):
44            return os.path.join(Ws, os.path.relpath(Path, Ws))
45        return Path
46
47    ## setWs()
48    #
49    #   set WORKSPACE and PACKAGES_PATH environment
50    #
51    #   @param  cls          The class pointer
52    #   @param  Ws           initialize WORKSPACE variable
53    #   @param  PackagesPath initialize PackagesPath variable
54    #
55    @classmethod
56    def setWs(cls, Ws, PackagesPath=None):
57        cls.WORKSPACE = Ws
58        if PackagesPath:
59            cls.PACKAGES_PATH = [cls.convertPackagePath (Ws, os.path.normpath(Path.strip())) for Path in PackagesPath.split(os.pathsep)]
60        else:
61            cls.PACKAGES_PATH = []
62
63    ## join()
64    #
65    #   rewrite os.path.join function
66    #
67    #   @param  cls       The class pointer
68    #   @param  Ws        the current WORKSPACE
69    #   @param  *p        path of the inf/dec/dsc/fdf/conf file
70    #   @retval Path      the absolute path of specified file
71    #
72    @classmethod
73    def join(cls, Ws, *p):
74        Path = os.path.join(Ws, *p)
75        if not os.path.exists(Path):
76            for Pkg in cls.PACKAGES_PATH:
77                Path = os.path.join(Pkg, *p)
78                if os.path.exists(Path):
79                    return Path
80            Path = os.path.join(Ws, *p)
81        return Path
82
83    ## relpath()
84    #
85    #   rewrite os.path.relpath function
86    #
87    #   @param  cls       The class pointer
88    #   @param  Path      path of the inf/dec/dsc/fdf/conf file
89    #   @param  Ws        the current WORKSPACE
90    #   @retval Path      the relative path of specified file
91    #
92    @classmethod
93    def relpath(cls, Path, Ws):
94        for Pkg in cls.PACKAGES_PATH:
95            if Path.lower().startswith(Pkg.lower()):
96                Path = os.path.relpath(Path, Pkg)
97                return Path
98        if Path.lower().startswith(Ws.lower()):
99            Path = os.path.relpath(Path, Ws)
100        return Path
101
102    ## getWs()
103    #
104    #   get valid workspace for the path
105    #
106    #   @param  cls       The class pointer
107    #   @param  Ws        the current WORKSPACE
108    #   @param  Path      path of the inf/dec/dsc/fdf/conf file
109    #   @retval Ws        the valid workspace relative to the specified file path
110    #
111    @classmethod
112    def getWs(cls, Ws, Path):
113        absPath = os.path.join(Ws, Path)
114        if not os.path.exists(absPath):
115            for Pkg in cls.PACKAGES_PATH:
116                absPath = os.path.join(Pkg, Path)
117                if os.path.exists(absPath):
118                    return Pkg
119        return Ws
120
121    ## handleWsMacro()
122    #
123    #   handle the $(WORKSPACE) tag, if current workspace is invalid path relative the tool, replace it.
124    #
125    #   @param  cls       The class pointer
126    #   @retval PathStr   Path string include the $(WORKSPACE)
127    #
128    @classmethod
129    def handleWsMacro(cls, PathStr):
130        if TAB_WORKSPACE in PathStr:
131            Path = PathStr.replace(TAB_WORKSPACE, cls.WORKSPACE).strip()
132            if not os.path.exists(Path):
133                for Pkg in cls.PACKAGES_PATH:
134                    Path = PathStr.replace(TAB_WORKSPACE, Pkg).strip()
135                    if os.path.exists(Path):
136                        return Path
137        return PathStr
138
139    ## getPkgPath()
140    #
141    #   get all package pathes.
142    #
143    #   @param  cls       The class pointer
144    #
145    @classmethod
146    def getPkgPath(cls):
147        return cls.PACKAGES_PATH
148