-
Notifications
You must be signed in to change notification settings - Fork 42
/
build-plugin.sh
executable file
·197 lines (177 loc) · 5.5 KB
/
build-plugin.sh
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
#!/bin/bash
#
# Build a migration with datastore plugins
#
# This script builds a migration with datastore plugins. Specify the
# migration, such as 10-to-11, and one or more plugin repos to build with. A
# specific version of a plugin is specified by following it with
# @<version_or_hash>. The migration binary is built in its module
# subdirectory. Run the migration binary directly, or copy it into a directory
# in PATH to be run by ipfs-update or fs-repo-migrations.
#
# For each plugin built, the script asks which plugin to load. Use the -y flag
# to avoid the prompt and choose 'plugin *' automatically.
#
# Example:
# ./build-plugin.sh 10-to-11 github.com/ipfs/go-ds-s3 github.com/ipfs/go-ds-swift@v0.1.0
#
set -eou pipefail
function usage() {
echo "usage: $0 [-y] x-to-y plugin_repo[@<version_or_hash>] ...">&2
echo
echo "example: $0 10-to-11 github.com/ipfs/go-ds-s3" >&2
}
AUTO_ANSWER=no
if [[ $# -ge 1 ]] && [[ "$1" =~ ^-.* ]]; then
if [ "$1" = "-h" -o "$1" = "-?" -o "$1" = "-help" ]; then
echo "Build a migration with one or more plugins"
echo
usage
echo
echo "Options and arguments"
echo "-y Automatically answer 'y' to all promots"
echo "First postional argument, specifies the migration to build."
echo "Remaining positional arguments specify plugin repos with optional version."
exit 0
elif [ "$1" = "-y" ]; then
AUTO_ANSWER=yes
shift 1
else
echo "unrecognized option $1" >&2
echo >&2
usage
exit 1
fi
fi
if [ $# -lt 2 ]; then
echo "too few arguments" >&2
echo >&2
usage
exit 1
fi
MIGRATION="$1"
BUILD_DIR="$(mktemp -d --suffix=migration_build)"
BUILD_GOIPFS="${BUILD_DIR}/go-ipfs"
IPFS_REPO="github.com/ipfs/go-ipfs"
IPFS_REPO_URL="https://${IPFS_REPO}"
function cleanup {
rm -rf "${BUILD_DIR}"
}
trap cleanup EXIT
function get_migration() {
for i in *${1}; do
if [ -d "$i" ]; then
echo "$i"
return 0
fi
done
}
function clone_ipfs() {
local mig="$1"
if [ ! -d "${mig}/vendor/github.com/ipfs/go-ipfs" ]; then
echo "migration $mig does not support datastore plugins" >&2
return 1
fi
pushd "$mig"
local ver="$(go list -f '{{.Version}}' -m github.com/ipfs/go-ipfs)"
popd
if echo "$ver" | grep -E 'v.*.[0-9]{14}-[0-9a-f]{12}$'; then
local commit="$(echo $ver | rev | cut -d '-' -f 1 | rev)"
echo "===> Getting go-ipfs commit $commit"
git clone "$IPFS_REPO_URL" "$BUILD_GOIPFS"
pushd "$BUILD_GOIPFS"
git checkout "$commit"
popd
else
echo "===> Getting go-ipfs branch $ver"
git clone -b "$ver" "$IPFS_REPO_URL" "$BUILD_GOIPFS"
fi
}
function ask_yes_no() {
local prompt="$1"
while true; do
read -p "$prompt [y/n]?" yn
case "$yn" in
[Yy]* ) return 0;;
[Nn]* ) return 1;;
* ) echo "Please answer y or n";;
esac
done
}
function bundle_ipfs_plugin() {
local plugin_repo="$1"
echo "===> Bundling plugin $plugin_repo info go-ipfs for migration"
local plugin_version=latest
if [[ "$plugin_repo" == *"@"* ]]; then
plugin_version="$(echo $plugin_repo | cut -d '@' -f 2)"
plugin_repo="$(echo $plugin_repo | cut -d '@' -f 1)"
fi
echo "plugin version: $plugin_version"
local plugin_name="$(echo $plugin_repo | rev | cut -d '-' -f 1 | rev)"
pushd "$BUILD_GOIPFS"
go get "${plugin_repo}@${plugin_version}"
popd
local ds_name="${plugin_name}ds"
# While there is a plugin name conflict, ask for or generate new name.
# When run non-interactively, keep appending "1" until no conflict.
while grep -q "^${ds_name} " "${BUILD_GOIPFS}/plugin/loader/preload_list"; do
old_ds_name="$ds_name"
ds_name="${ds_name}1"
if [ "$AUTO_ANSWER" != "yes" ]; then
echo -n "\"$old_ds_name\" already in use, "
while true; do
if ask_yes_no "use plugin name \"$ds_name\""; then
break
else
read -p "Enter new value: " ds_name
fi
done
fi
done
# Prompt for plugin to load
load_plugin='plugin *'
if [ "$AUTO_ANSWER" != "yes" ]; then
while true; do
if ask_yes_no "For $plugin_repo, load '$load_plugin'"; then
break
else
read -p "Enter new value: " load_plugin
fi
done
fi
echo "$ds_name ${plugin_repo}/${load_plugin}" >> "${BUILD_GOIPFS}/plugin/loader/preload_list"
}
function build_migration() {
echo "===> Building go-ipfs with datastore plugins"
sed -i '/^\tgo fmt .*/a \\tgo mod tidy' "${BUILD_GOIPFS}/plugin/loader/Rules.mk"
make -C "$BUILD_GOIPFS" build
local mig="$1"
echo
echo "===> Building migration $mig with plugins"
pushd "$mig"
go mod edit -replace "${IPFS_REPO}=${BUILD_GOIPFS}"
go mod vendor
go build -mod=vendor
# Cleanup temporary modifications
rm -rf vendor
git checkout vendor go.mod
if [ -e go.sum ]; then
git checkout go.sum
fi
popd
echo "===> Done building migration $mig with plugins"
}
migration="$(get_migration ${MIGRATION})"
if [ -z "$migration" ]; then
echo "migration $migration does not exist" >&2
exit 1
fi
clone_ipfs "$migration"
if [ $? -ne 0 ]; then
continue
fi
shift 1
for repo in "$@"; do
bundle_ipfs_plugin "$repo"
done
build_migration "$migration"