File: inspect_changes.sh

package info (click to toggle)
cccl 2.5.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 39,248 kB
  • sloc: cpp: 264,457; python: 6,421; sh: 2,762; perl: 460; makefile: 114; xml: 13
file content (215 lines) | stat: -rwxr-xr-x 5,259 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#!/bin/bash

# Github action script to identify which subprojects are dirty in a PR

set -u

# Usage: inspect_changes.sh <base_sha> <head_sha>
if [ "$#" -ne 2 ]; then
  echo "Usage: $0 <base_sha> <head_sha>"
  exit 1
fi

base_sha=$1
head_sha=$2

# Github gives the SHA as the current HEAD of the target ref, not the common ancestor.
# Find the common ancestor and use that for the base.
git fetch origin --unshallow -q
git fetch origin $base_sha -q
base_sha=$(git merge-base $head_sha $base_sha)

# Define a list of subproject directories by their subdirectory name:
subprojects=(
  cccl
  libcudacxx
  cub
  thrust
  cudax
)

# ...and their dependencies:
declare -A dependencies=(
  [cccl]=""
  [libcudacxx]="cccl"
  [cub]="cccl libcudacxx thrust"
  [thrust]="cccl libcudacxx cub"
  [cudax]="cccl libcudacxx"
)

declare -A project_names=(
  [cccl]="CCCL Infrastructure"
  [libcudacxx]="libcu++"
  [cub]="CUB"
  [thrust]="Thrust"
  [cudax]="CUDA Experimental"
)

# Usage checks:
for subproject in "${subprojects[@]}"; do
  # Check that the subproject directory exists
  if [ "$subproject" != "cccl" ] && [ ! -d "$subproject" ]; then
    echo "Error: Subproject directory '$subproject' does not exist."
    exit 1
  fi

  # If the subproject has dependencies, check that they exist (except for "cccl")
  for dependency in ${dependencies[$subproject]}; do
    if [ "$dependency" != "cccl" ] && [ ! -d "$dependency" ]; then
      echo "Error: Dependency directory '$dependency' for subproject '$subproject' does not exist."
      exit 1
    fi
  done
done

write_output() {
  local key="$1"
  local value="$2"
  echo "$key=$value" | tee --append "${GITHUB_OUTPUT:-/dev/null}"
}

tee_to_step_summary() {
  if [ -n "${GITHUB_STEP_SUMMARY:-}" ]; then
    tee -a "${GITHUB_STEP_SUMMARY}"
  else
    cat
  fi
}

dirty_files() {
  git diff --name-only "${base_sha}" "${head_sha}"
}

# Return 1 if any files outside of the subproject directories have changed
inspect_cccl() {
  subprojs_grep_expr=$(
    IFS="|"
    echo "(${subprojects[*]})/"
  )

  if dirty_files | grep -v -E "${subprojs_grep_expr}" | grep -q "."; then
    return 1
  else
    return 0
  fi
}

# inspect_subdir <subdir>
# Returns 1 if any files in the subdirectory have changed
inspect_subdir() {
  local subdir="$1"

  if dirty_files | grep -E "^${subdir}/" | grep -q '.'; then
    return 1
  else
    return 0
  fi
}

# add_dependencies <subproject>
# if the subproject or any of its dependencies are dirty, return 1
add_dependencies() {
  local subproject="$1"

  # Check if ${subproject^^}_DIRTY is set to 1, return 1 if it is.
  local dirty_flag=${subproject^^}_DIRTY
  if [[ ${!dirty_flag} -ne 0 ]]; then
    return 1
  fi

  for dependency in ${dependencies[$subproject]}; do
    dirty_flag="${dependency^^}_DIRTY"
    if [[ ${!dirty_flag} -ne 0 ]]; then
      return 1
    fi
  done

  return 0
}

main() {
  # Print the list of subprojects and all of their dependencies:
  echo "Subprojects: ${subprojects[*]}"
  echo
  echo "Dependencies:"
  for subproject in "${subprojects[@]}"; do
    printf "  - %-27s -> %s\n" "$subproject (${project_names[$subproject]})" "${dependencies[$subproject]}"

  done
  echo

  echo "Base SHA: ${base_sha}"
  echo "HEAD SHA: ${head_sha}"
  echo

  check="+/-"
  no_check="   "
  get_checkmark() {
    if [[ $1 -eq 0 ]]; then
      echo "$no_check"
    else
      echo "$check"
    fi
  }

  # Print the list of files that have changed:
  echo "::group::Dirty files"
  dirty_files | sed 's/^/  - /'
  echo "::endgroup::"
  echo


  echo "<details><summary><h3>👃 Inspect Changes</h3></summary>" | tee_to_step_summary
  echo | tee_to_step_summary

  echo -e "### Modifications in project?\n" | tee_to_step_summary
  echo "|     | Project" | tee_to_step_summary
  echo "|-----|---------" | tee_to_step_summary

  # Assign the return value of `inspect_cccl` to the variable `CCCL_DIRTY`:
  inspect_cccl
  CCCL_DIRTY=$?
  checkmark="$(get_checkmark ${CCCL_DIRTY})"
  echo "| ${checkmark} | ${project_names[cccl]}" | tee_to_step_summary

  # Check for changes in each subprojects directory:
  for subproject in "${subprojects[@]}"; do
    if [[ ${subproject} == "cccl" ]]; then
      # Special case handled above.
      continue
    fi

    inspect_subdir $subproject
    local dirty=$?
    declare ${subproject^^}_DIRTY=${dirty}
    checkmark="$(get_checkmark ${dirty})"
    echo "| ${checkmark} | ${project_names[$subproject]}" | tee_to_step_summary
  done
  echo | tee_to_step_summary

  echo -e "### Modifications in project or dependencies?\n" | tee_to_step_summary
  echo "|     | Project" | tee_to_step_summary
  echo "|-----|---------" | tee_to_step_summary

  for subproject in "${subprojects[@]}"; do
    add_dependencies ${subproject}
    local dirty=$?
    declare ${subproject^^}_DIRTY=${dirty}
    checkmark="$(get_checkmark ${dirty})"
    echo "| ${checkmark} | ${project_names[$subproject]}" | tee_to_step_summary
  done

  echo "</details>" | tee_to_step_summary

  declare -a dirty_subprojects=()
  for subproject in "${subprojects[@]}"; do
    var_name="${subproject^^}_DIRTY"
    if [[ ${!var_name} -ne 0 ]]; then
      dirty_subprojects+=("$subproject")
    fi
  done

  write_output "DIRTY_PROJECTS" "${dirty_subprojects[*]}"
}

main "$@"