1#!/bin/bash
2#
3#  Copyright (C) 2020 The Android Open Source Project
4#
5#  Licensed under the Apache License, Version 2.0 (the "License");
6#  you may not use this file except in compliance with the License.
7#  You may obtain a copy of the License at
8#
9#       http://www.apache.org/licenses/LICENSE-2.0
10#
11#  Unless required by applicable law or agreed to in writing, software
12#  distributed under the License is distributed on an "AS IS" BASIS,
13#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#  See the License for the specific language governing permissions and
15#  limitations under the License.
16#
17
18set -e
19
20function usage() {
21  echo "usage: $0 <exploded dir> <source path>"
22  echo "This script concatenates files in <exploded dir> and puts the results in <source path>"
23  exit 1
24}
25
26explodedDir="$1"
27sourcePath="$2"
28
29if [ "$sourcePath" == "" ]; then
30  usage
31fi
32sourcePath="$(readlink -f $sourcePath)"
33
34if [ "$explodedDir" == "" ]; then
35  usage
36fi
37mkdir -p "$explodedDir"
38explodedDir="$(cd $explodedDir && pwd)"
39
40function joinPath() {
41  explodedPath="$1"
42  sourceFile="$2"
43
44  # replace ending '/.' with nothing
45  sourceFile="$(echo $sourceFile | sed 's|/\.$||')"
46
47  # if this file doesn't already exist, regenerate it
48  if [ ! -e "$sourceFile" ]; then
49    mkdir -p "$(dirname $sourceFile)"
50    bash -c "cd $explodedPath && find -type f | sort | xargs cat > $sourceFile"
51    chmod u+x "$sourceFile"
52  fi
53}
54
55function deleteStaleOutputs() {
56  if [ -e "$sourcePath" ]; then
57    # find everything in explodedDir newer than sourcePath
58    cd "$explodedDir"
59    changedPaths="$(find -newer "$sourcePath" | sed 's|\([/0-9]*\)$||' | sort | uniq)"
60    # for each modified inode in explodedDir, delete the corresponding inode in sourcePath
61    # first check for '.' because `rm` refuses to delete '.'
62    for filePath in $changedPaths; do
63      if [ "$filePath" == "." ]; then
64        # the source dir itself is older than the exploded dir, so we have to delete the entire source dir
65        rm "$sourcePath" -rf
66        return
67      fi
68    done
69    # now we can delete any stale paths
70    cd "$sourcePath"
71    for filePath in $changedPaths; do
72      rm $filePath -rf
73    done
74  fi
75}
76
77function main() {
78  # Remove most files and directories under $sourcePath other than build caches (out)
79  deleteStaleOutputs
80  mkdir -p "$sourcePath"
81
82  # regenerate missing files
83  cd "$explodedDir"
84  echo joining all file paths under $explodedDir into $sourcePath
85  filePaths="$(find -type f -name file | sed 's|/[^/]*$||' | sort | uniq)"
86  for filePath in $filePaths; do
87    joinPath "$explodedDir/$filePath" "$sourcePath/$filePath"
88  done
89  for filePath in $(find -type l); do
90    cp -PT "$explodedDir/$filePath" "$sourcePath/$filePath"
91  done
92
93  # record the timestamp at which we finished
94  touch $sourcePath
95
96  # announce that we're done
97  echo done joining all file paths under $explodedDir into $sourcePath
98}
99
100
101main
102