Skip to content

Commit 651a517

Browse files
committed
Update install script and docs after pyinstaller update
1 parent f00d936 commit 651a517

File tree

3 files changed

+106
-94
lines changed

3 files changed

+106
-94
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ python -m gpt_cmd [...]
2323

2424
## Cutting a release
2525

26-
Pushing a version tag (e.g. `v.1.0.0`) will trigger the [release.yml](.github/workflows/release.yml) GitHub action, which will build binaries for supported OSes and publish a release with them.
26+
Pushing a version tag (e.g. `v1.0.0`) will trigger the [release.yml](.github/workflows/release.yml) GitHub workflow, which will build binaries for supported OSes and publish a release with them.
2727

2828
The binaries are generated using [pyinstaller](https://pyinstaller.org/en/stable/).

README.md

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ With this approach, ChatGPT is able to probe your system and try running command
3434
> [!WARNING]
3535
> In light of my other warning above, this install script is pulled directly from my GitHub repo, and is a potential vulnerability if the repo (or GitHub) becomes compromised. Always inspect scripts for shady behavior before running them on your device (even mine: [install.sh](https://raw.githubusercontent.com/chrisdothtml/gpt-cmd/main/install.sh)).
3636
37-
**NOTE**: the system requirements are: `bash` and either `curl` or `wget`
37+
### Linux/MacOS
38+
39+
**NOTE**: the only system requirements are `bash` and either `curl` or `wget`.
3840

3941
```sh
4042
curl -s https://raw.githubusercontent.com/chrisdothtml/gpt-cmd/main/install.sh | bash
@@ -43,18 +45,15 @@ curl -s https://raw.githubusercontent.com/chrisdothtml/gpt-cmd/main/install.sh |
4345
wget -qO- https://raw.githubusercontent.com/chrisdothtml/gpt-cmd/main/install.sh | bash
4446
```
4547

46-
See [Env var overrides](#env-var-overrides) section for changing the install dir.
48+
The install script will make its best attempt to expose the binary to your `$PATH`, but if that doesn't work, you'll have to manually add it your path (install location is `$HOME/.gpt_cmd/`).
4749

48-
The install script will write to your `.profile` file to expose it to your `$PATH`, but if that doesn't work, you'll have to manually add it your path:
50+
### Windows
4951

50-
```sh
51-
# replace `$HOME` with your custom install dir if you used one
52-
export PATH="$HOME/gpt_cmd/bin:$PATH"
53-
```
52+
There's not currently an automated installer for Windows, but you can download the `.exe` file from the [releases page](https://github.com/chrisdothtml/gpt-cmd/releases).
5453

5554
## Use
5655

57-
Before running, you need to create an `~/OPENAI_TOKEN` file and put your token in it.
56+
**NOTE**: before running, you need to create an `~/OPENAI_TOKEN` file and put your token in it.
5857

5958
```sh
6059
gpt_cmd <goal>
@@ -73,18 +72,6 @@ The `goal` can be literally anything you can achieve via a terminal (which is a
7372

7473
Enironment vars that you can provide to change the behavior of the tool.
7574

76-
### `GPT_CMD_INSTALL_DIR`
77-
78-
Override the dir the installer puts the tool in.
79-
80-
**Default**: home dir
81-
82-
**Example**:
83-
84-
```sh
85-
curl -s [...] | GPT_CMD_INSTALL_DIR="/my/custom/dir" bash
86-
```
87-
8875
### `GPT_CMD_MODEL`
8976

9077
Override the gpt model used by the tool.

install.sh

Lines changed: 98 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,44 @@
22

33
set -e
44

5-
# FIXME: update to use new binary approach
5+
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
6+
OS="linux"
7+
elif [[ "$OSTYPE" == "darwin"* ]]; then
8+
OS="macos"
9+
else
10+
OS="unknown"
11+
fi
612

713
ansi_blue='\033[94m'
814
ansi_green='\033[92m'
915
ansi_red='\033[91m'
16+
ansi_yellow='\033[93m'
1017
ansi_reset='\033[0m'
1118

12-
function log_blue() {
13-
echo -e "${ansi_blue}$1${ansi_reset}"
19+
function print_blue() {
20+
printf "${ansi_blue}%b${ansi_reset}" "$1"
1421
}
15-
16-
function log_green() {
17-
echo -e "${ansi_green}$1${ansi_reset}"
22+
function print_green() {
23+
printf "${ansi_green}%b${ansi_reset}" "$1"
24+
}
25+
function print_red() {
26+
printf "${ansi_red}%b${ansi_reset}" "$1"
27+
}
28+
function print_yellow() {
29+
printf "${ansi_yellow}%b${ansi_reset}" "$1"
1830
}
1931

20-
function log_red() {
21-
echo -e "${ansi_red}$1${ansi_reset}"
32+
function log_error() {
33+
print_red "ERROR: ${1}\n"
34+
}
35+
function log_warning() {
36+
print_yellow "WARNING: ${1}\n"
2237
}
2338

24-
function fetch_latest_tarball() {
39+
function fetch_latest_binary() {
2540
local github_repo="$1"
26-
local file_path="$2"
41+
local dir_path="$2"
42+
local binary_name="$3"
2743

2844
# detect which fetch tool is available on the machine
2945
local fetch_tool
@@ -32,7 +48,7 @@ function fetch_latest_tarball() {
3248
elif command -v wget >/dev/null; then
3349
fetch_tool="wget"
3450
else
35-
log_red "ERROR: No suitable download tool found (curl, wget)" >&2
51+
log_error "No suitable download tool found (curl, wget)"
3652
exit 1
3753
fi
3854

@@ -46,33 +62,69 @@ function fetch_latest_tarball() {
4662
releases_res="$(wget -qO- "$releases_url")";;
4763
esac
4864

49-
# parse out the latest release's tarball url
50-
local latest_tarball_url="$( \
65+
# get binary url from latest release for this OS
66+
local latest_version="$( \
5167
echo "$releases_res" \
52-
| grep '"tarball_url"' \
53-
| sed -E 's/.*"tarball_url": "(.*)",/\1/' \
68+
| grep '"tag_name"' \
69+
| sed -E 's/.*"tag_name": "(.*)",/\1/' \
5470
| head -1 \
5571
)"
56-
if [ -z "$latest_tarball_url" ]; then
72+
local binary_urls="$( \
73+
echo "$releases_res" \
74+
| grep "releases/download/$latest_version/gpt_cmd-" \
75+
| sed -E 's/[ \t]+"browser_download_url": "([^"]+)",?/\1/' \
76+
)"
77+
local latest_binary_url=""
78+
for url in $binary_urls; do
79+
os="$(echo "$url" | sed -E 's|.*/gpt_cmd-([^.]*).*|\1|')"
80+
if [ "$os" = "$OS" ]; then
81+
latest_binary_url="$url"
82+
break
83+
fi
84+
done
85+
if [ -z "$latest_binary_url" ]; then
5786
local error_file_name="gpt_cmd_install-error_$(date +"%Y-%m-%d_%H-%M-%S").log"
58-
echo -e "ERROR: unable to find release tarball\n" >> "$error_file_name"
87+
echo -e "ERROR: unable to find release binary\n" >> "$error_file_name"
5988
echo -e "GitHub releases response body:\n$releases_res" >> "$error_file_name"
6089

61-
log_red "ERROR: unable to find release tarball; see $error_file_name for more info" >&2
90+
log_error "unable to find release binary; see $error_file_name for more info"
6291
exit 1
6392
fi
6493

65-
# fetch the tarball
94+
# fetch the binary
95+
local file_name="$(basename "$latest_binary_url")"
96+
local file_path="$dir_path/$file_name"
6697
case $fetch_tool in
6798
curl)
68-
curl -L -o "$file_path" "$latest_tarball_url";;
99+
curl -L -s -S -o "$file_path" "$latest_binary_url";;
69100
wget)
70-
wget -O "$file_path" "$latest_tarball_url";;
101+
wget -q -O "$file_path" "$latest_binary_url";;
71102
esac
72103
if [ ! -e "$file_path" ]; then
73-
log_red "ERROR: failed to fetch latest release tarball ($latest_tarball_url)" >&2
104+
log_error "failed to fetch latest release tarball ($latest_binary_url)"
74105
exit 1
75106
fi
107+
108+
# rename binary file
109+
mv "$file_path" "$dir_path/$binary_name"
110+
}
111+
112+
function make_binary_executable() {
113+
local file_path="$1"
114+
115+
chmod +x "$file_path"
116+
117+
# try to make MacOS trust the binary file
118+
if [ "$OS" = "macos" ]; then
119+
if command -v xattr >/dev/null; then
120+
if xattr -p com.apple.quarantine "$file_path" &>/dev/null; then
121+
xattr -d com.apple.quarantine "$file_path"
122+
fi
123+
else
124+
log_warning "Unable to update MacOS to trust binary. You may need to manually do so"
125+
echo "(right click and click open on the binary file: $file_path)"
126+
fi
127+
fi
76128
}
77129

78130
function get_profile_file() {
@@ -91,68 +143,41 @@ function get_profile_file() {
91143
}
92144

93145
function run_install() {
94-
local base_install_dir="${GPT_CMD_INSTALL_DIR:-$HOME}"
95-
local install_dir="$base_install_dir/gpt_cmd"
96-
log_blue "Installing gpt_cmd to ${base_install_dir}..."
97-
98-
# check for previous installation
99-
local prev_install_exists="false"
100-
local convos_dir_path="$install_dir/.convos"
101-
local convos_backup_dir_path="$base_install_dir/.convos-backup"
102-
if [ -e "$install_dir" ]; then
103-
prev_install_exists="true"
104-
105-
# backup convos dir
106-
if [ -e "$convos_dir_path" ]; then
107-
echo ""
108-
log_blue "Existing installation detected; preserving convos dir..."
109-
mv "$convos_dir_path" "$convos_backup_dir_path"
110-
fi
111-
112-
rm -rf "$install_dir"
146+
if [ "$OS" = "unknown" ]; then
147+
log_error "OS type '$OSTYPE' not recognized as a supported OS"
148+
exit 1
113149
fi
114150

115-
mkdir -p "$install_dir"
116-
cd "$install_dir"
117-
118-
echo ""
119-
log_blue "Attempting to fetch latest release..."
120-
local tarball_file_name="gpt_cmd.tar.gz"
121-
fetch_latest_tarball "chrisdothtml/gpt-cmd" "$tarball_file_name"
122-
123-
echo ""
124-
log_blue "Expanding tarballs..."
125-
# untar repo
126-
tar -xzf "$tarball_file_name" --strip-components=1
127-
rm -rf "$tarball_file_name"
128-
# untar vendored dependencies
129-
tar -xzf vendor.tar.gz
130-
rm -rf vendor.tar.gz
131-
132-
if [ -e "$convos_backup_dir_path" ]; then
133-
echo ""
134-
log_blue "Restoring backed-up convos dir..."
135-
mv "$convos_backup_dir_path" "$convos_dir_path"
136-
fi
151+
local install_dir="$HOME/.gpt_cmd"
152+
echo "Installing to ${install_dir}"
153+
154+
print_blue "Attempting to fetch latest binary..."
155+
local repo_name="chrisdothtml/gpt-cmd"
156+
local binary_dir_path="$install_dir/bin"
157+
local binary_name="gpt_cmd"
158+
mkdir -p "$binary_dir_path"
159+
fetch_latest_binary "$repo_name" "$binary_dir_path" "$binary_name"
160+
echo ""
137161

138-
local path_update_str="export PATH=\"${install_dir}/bin:\$PATH\""
162+
print_blue "Making binary executable on your system..."
163+
local binary_file_path="$binary_dir_path/$binary_name"
164+
make_binary_executable "$binary_file_path"
165+
echo ""
166+
167+
local path_update_str="export PATH=\"${binary_dir_path}:\$PATH\""
139168
local profile_file
140169
if ! command -v gpt_cmd >/dev/null; then
141170
profile_file="$(get_profile_file)"
142-
echo ""
143-
log_blue "Updating ${profile_file}..."
171+
print_blue "Exposing binary to PATH..."
144172
echo -e "\n$path_update_str" >> "$profile_file"
173+
echo ""
145174
fi
146175

147-
echo ""
148-
log_green "✅ Done!"
149-
176+
print_green "\n✅ gpt_cmd installed successfully!\n"
150177
if [ -n "$profile_file" ]; then
151-
echo ""
152-
log_blue "\$PATH was updated via ${profile_file}. Open a new terminal and run 'gpt_cmd --help' to make sure it worked."
178+
print_yellow "\nYour PATH was updated via ${profile_file}. Open a new terminal and run 'gpt_cmd --help' to make sure it worked.\n"
153179
fi
154-
echo ""
155-
log_blue "If \`gpt_cmd\` isn't found, add this to a profile file your terminal recognizes:"
180+
print_yellow "\nIf \`gpt_cmd\` isn't found, add this to a profile file your terminal recognizes:\n"
156181
echo -e "\n $path_update_str\n"
157182
}
158183

0 commit comments

Comments
 (0)