forked from p4lang/p4app
-
Notifications
You must be signed in to change notification settings - Fork 0
/
p4app
executable file
·180 lines (151 loc) · 4.85 KB
/
p4app
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
#!/usr/bin/env bash
# Ensure the LANG environment variable is set to UTF-8
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
P4APP_IMAGE=${P4APP_IMAGE:-p4lang/p4app:latest}
P4APP_CONTAINER_ARGS=${P4APP_CONTAINER_ARGS:-""}
# Ensure QEMU is set up for cross-platform execution if on arm64
function setup_qemu() {
if ! docker run --rm --privileged multiarch/qemu-user-static --reset -p yes &>/dev/null; then
echo "Setting up QEMU for cross-platform Docker support."
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
fi
}
# Run QEMU setup if on arm64 platform
if [[ "$(uname -m)" == "aarch64" ]]; then
setup_qemu
fi
# Function to get absolute path
myrealpath() {
[[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
}
P4APP_LOGDIR=$(myrealpath "${P4APP_LOGDIR:-/tmp/p4app_logs}")
# Function to check and fix encoding with multiple fallback options
function check_and_fix_utf8() {
local file="$1"
local encoding
# Detect encoding
encoding=$(file -i "$file" | awk -F "=" '{print $2}')
if [[ "$encoding" != "utf-8" ]]; then
echo "Invalid UTF-8 detected in: $file (encoding: $encoding)"
local fixed_file="${file}.fixed"
local success=false
# Try iconv with detected or known encodings
for enc in "$encoding" ISO-8859-1 WINDOWS-1252 ASCII; do
if iconv -f "$enc" -t UTF-8//IGNORE "$file" -o "$fixed_file" 2>/dev/null; then
success=true
echo "Fixed encoding using $enc for: $file"
break
fi
done
# If iconv failed, remove non-UTF-8 characters
if ! $success; then
echo "All iconv attempts failed. Removing non-UTF-8 characters from: $file"
sed 's/[^[:print:]\t]//g' "$file" > "$fixed_file"
fi
# Replace original file if fixed
if [ -f "$fixed_file" ]; then
mv "$fixed_file" "$file"
echo "Fixed encoding in: $file"
else
echo "Failed to fix encoding in: $file"
fi
else
echo "Valid UTF-8: $file"
fi
}
# Function to get absolute filename
function get_abs_filename() {
echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
}
# Normalize path by removing any trailing slash
function normalize_path() {
echo ${1%/}
}
# Build command function
function build-command {
local output_file=${2:-"out.json"}
run-command "$1" --build-only "${@:3}"
rc=$?
[ $rc -eq 0 ] && cp "$P4APP_LOGDIR/program.json" "$output_file"
exit $rc
}
# Run p4app function with Docker container
function run-p4app {
APP_TO_RUN=/tmp/app.tar.gz
P4APP_NAME=${P4APP_NAME:-"p4app_$RANDOM"}
docker run --platform linux/amd64 --privileged --interactive --tty --rm \
--name "$P4APP_NAME" \
-v "$1:$APP_TO_RUN" \
-v "$P4APP_LOGDIR:/tmp/p4app_logs" \
$P4APP_CONTAINER_ARGS \
$P4APP_IMAGE "$APP_TO_RUN" "${@:2}"
}
# Run command function to handle .p4app packages
function run-command {
if [ -d "$1" ]; then
PACKAGE_DIR=$(normalize_path "$1")
APP_FILE=$(mktemp /tmp/p4app.tar.gz.XXXXXX)
# Create backup of the package before compilation
create_backup_object "$PACKAGE_DIR"
# Package files without extended pax headers
tar --format=ustar -czf "$APP_FILE" -C "$PACKAGE_DIR" .
run-p4app "$APP_FILE" "${@:2}"
rc=$?
rm "$APP_FILE"
elif [ -f "$1" ]; then
APP_FILE=$(get_abs_filename "$1")
# Create backup of the single file
create_backup_object "$(dirname "$APP_FILE")"
# Check and fix encoding for the file
check_and_fix_utf8 "$APP_FILE"
run-p4app "$APP_FILE" "${@:2}"
rc=$?
else
echo "Couldn't read p4app package: $1"
exit 1
fi
return $rc
}
function create_backup_object() {
local package_dir="$1"
local backup_file="backup_$(basename "$package_dir").txt"
echo "This is the code:\n" >> "$backup_file"
# Iterate through files in the package directory and add headers and content to the TXT file
for file in "$package_dir"/*; do
if [ -f "$file" ]; then
local filename=$(basename "$file")
# Write the file header to the backup file
echo "$filename" >> "$backup_file"
# Append file content to the backup file
cat "$file" >> "$backup_file"
# Add a newline after each file's content for separation
echo -e "\n" >> "$backup_file"
fi
done
echo "Backup created at $backup_file"
}
# Main case selector
case "$1" in
"run")
run-command "${@:2}"
;;
"build")
build-command "${@:2}"
;;
"pack")
pack-command "${@:2}"
;;
"unpack")
unpack-command "${@:2}"
;;
"update")
update-command "${@:2}"
;;
"exec")
exec-command "${@:2}"
;;
*)
usage-command
;;
esac