Skip to content

Commit

Permalink
Merge pull request #4 from dotenvx/installer
Browse files Browse the repository at this point in the history
Installer
  • Loading branch information
motdotla authored Jun 3, 2024
2 parents fe3ab7d + c4de349 commit f83609b
Show file tree
Hide file tree
Showing 9 changed files with 325 additions and 41 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: ci

on: push

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: true
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 16.x
- name: install shellspec
run: curl -fsSL https://git.io/shellspec | sh -s 0.28.1 --yes
- run: which shellspec
- run: npm install
- run: npm run standard
- run: npm test
12 changes: 12 additions & 0 deletions .shellspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--require spec_helper

## Default kcov (coverage) options
# --kcov-options "--include-path=. --path-strip-level=1"
# --kcov-options "--include-pattern=.sh"
# --kcov-options "--exclude-pattern=/.shellspec,/spec/,/coverage/,/report/"

## Example: Include script "myprog" with no extension
# --kcov-options "--include-pattern=.sh,myprog"

## Example: Only specified files/directories
# --kcov-options "--include-pattern=myprog,/lib/"
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ curl -fsS https://dotenvx.sh/ | sh
* alternatively, install with wget `wget -qO- https://dotenvx.sh/ | sh`
* make sure you are using `https`, not `http`. We do not redirect for trust reasons.
* deployed to heroku using dotenvx buildpack `heroku buildpacks:add https://github.com/dotenvx/heroku-buildpack-dotenvx`
* run specs with [`shellspec`](https://github.com/shellspec/shellspec)
40 changes: 0 additions & 40 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ const app = express()

const PORT = process.env.PORT || 3000
const GITHUB_TOKEN = process.env.GITHUB_TOKEN
const UMAMI_ROOT_URL = 'https://dotenv-umami-fd0ec6de187e.herokuapp.com'
const UMAMI_WEBSITE_ID = process.env.UMAMI_WEBSITE_ID
const UMAMI_SEND_URL = `${UMAMI_ROOT_URL}/api/send`
const SPOOFED_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'

// Read the installer script once at the start
const installerScriptPath = path.join(__dirname, 'installer.sh')
Expand All @@ -22,42 +18,6 @@ fs.readFile(installerScriptPath, 'utf8', (err, data) => {
installerScript = data
})

const umamiVisitMiddleware = (req, res, next) => {
const payload = {
website: UMAMI_WEBSITE_ID,
hostname: req.get('host'),
screen: '1920x1080',
language: 'en-US',
title: req.originalUrl,
url: req.originalUrl,
referrer: req.get('referrer') || '',
}

const postData = {
type: 'event',
payload: payload,
userIp: req.ip
}

const options = {
headers: {
'User-Agent': SPOOFED_USER_AGENT // otherwise, umami ignores https://github.com/umami-software/umami/blob/7fb74feeaf399b89866e8b368a5bfbe91349f848/src/pages/api/send.ts#L77
}
}

try {
axios.post(UMAMI_SEND_URL, postData, options)
} catch (error) {
console.error('Error sending page visit to Umami:', error)
console.error('postData', postData)
}

next() // Continue to the next middleware/route handler
}

// umami visits
// app.use(umamiVisitMiddleware)

app.get('/', (req, res) => {
// Check User-Agent to determine the response
const userAgent = req.headers['user-agent'] || ''
Expand Down
140 changes: 140 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#!/bin/sh

set -e

# default values
VERSION="0.44.1"
DIRECTORY="/usr/local/bin"

usage() {
echo "Usage: $0 [options] [command]"
echo ""
echo "install dotenvx – a better dotenv"
echo ""
echo "Options:"
echo " --directory directory to install dotenvx to (default: \"/usr/local/bin\")"
echo " --version version of dotenvx to install (default: \"$VERSION\")"
echo ""
echo "Commands:"
echo " install install dotenvx"
echo " help display help"
}

directory() {
local dir=$DIRECTORY

case "$dir" in
~*/*)
dir="$HOME/${dir#\~/}"
;;
~*)
dir="$HOME/${dir#\~}"
;;
esac

echo "${dir}"
return 0
}

is_directory_writable() {
# check installation directory is writable
if [ ! -w "$(directory)" ] && [ "$(id -u)" -ne 0 ]; then
echo "[INSTALLATION_FAILED] the installation directory [$(directory)] is not writable by the current user"
echo "? run as root [sudo $0] or choose a writable directory like your current directory [$0 directory=.]"

return 1
fi

return 0
}

is_curl_installed() {
if ! command -v curl >/dev/null 2>&1; then
echo "[INSTALLATION_FAILED] curl is required and appears to not be installed"
echo "? install curl and try again"

exit 1
fi

return 0
}

os() {
echo "$(uname -s | tr '[:upper:]' '[:lower:]')"

return 0
}

arch() {
echo "$(uname -m | tr '[:upper:]' '[:lower:]')"

return 0
}

is_os_supported() {
local os="$(os)"

case "$os" in
linux) os="linux" ;;
darwin) os="darwin" ;;
*)
echo "[INSTALLATION_FAILED] your operating system ${os} is currently unsupported"
echo "? request support by opening an issue at [https://github.com/dotenvx/dotenvx.sh/issues]"

return 1
;;
esac

return 0
}

is_arch_supported() {
local arch="$(arch)"

case "$arch" in
x86_64) arch="x86_64" ;;
amd64) arch="amd64" ;;
arm64) arch="arm64" ;;
aarch64) arch="aarch64" ;;
*)
echo "[INSTALLATION_FAILED] your architecture ${arch} is currently unsupported - must be x86_64, amd64, arm64, or aarch64"
echo "? request support by opening an issue at [https://github.com/dotenvx/dotenvx.sh/issues]"

return 1
;;
esac

return 0
}

os_arch() {
echo "$(os)-$(arch)"

return 0
}

# parse arguments
for arg in "$@"; do
case $arg in
directory=* | --directory=*)
DIRECTORY="${arg#*=}"
;;
help | --help)
usage
exit 0
;;
*)
# Unknown option
echo "Unknown option: $arg"
usage
exit 1
;;
esac
done

# is_directory_writable
# is_curl_installed
# is_os_supported
# is_arch_supported
# echo "os: $(os) arch: $(arch)"
echo "hello"
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"scripts": {
"standard": "standard",
"standard:fix": "standard --fix"
"standard:fix": "standard --fix",
"test": "bash shellspec"
},
"dependencies": {
"axios": "^1.6.2",
Expand Down
126 changes: 126 additions & 0 deletions spec/install_spec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
Describe 'install.sh'
Include install.sh directory=./spec/tmp

setup() {
VERSION="0.44.1"
}

mock_home() {
HOME="/home/testuser"
DIRECTORY="~/testdir"
}

mock_unwritable_directory() {
DIRECTORY="/usr/local/testing-installer" # requires root/sudo
}

BeforeEach 'setup'

Describe 'default values'
It 'checks default VERSION'
When call echo "$VERSION"
The output should equal "0.44.1"
End

It 'checks default DIRECTORY'
When call echo "$DIRECTORY"
The output should equal "./spec/tmp"
End
End

Describe 'usage()'
It 'displays usage'
When call usage
The output should equal "Usage: $0 [options] [command]
install dotenvx – a better dotenv
Options:
--directory directory to install dotenvx to (default: \"/usr/local/bin\")
--version version of dotenvx to install (default: \"0.44.1\")
Commands:
install install dotenvx
help display help"
End
End

Describe 'directory()'
It 'smartly returns directory as default INSTALL_DIR'
When call directory
The output should equal "./spec/tmp"
End

Describe 'when home directory'
Before 'mock_home'

It 'expands ~ to home directory'
When call directory
The output should equal "/home/testuser/testdir"
End
End
End

Describe 'is_directory_writable()'
It 'is true (0)'
When call is_directory_writable
The status should equal 0
End

Describe 'when unwritable directory'
Before 'mock_unwritable_directory'

It 'is false (1) to /usr/local/testing-installer (typical case that /usr/local/testing-installer is not writable)'
When call is_directory_writable
The status should equal 1
The output should equal "[INSTALLATION_FAILED] the installation directory [/usr/local/testing-installer] is not writable by the current user
? run as root [sudo $0] or choose a writable directory like your current directory [$0 directory=.]"
End
End
End

Describe 'is_curl_installed()'
It 'is true (0) (typical case that /usr/bin/curl is installed)'
When call is_curl_installed
The status should equal 0
End
End

Describe 'os()'
It 'returns current os lowercased'
When call os
The status should equal 0
The output should equal "$(uname -s | tr '[:upper:]' '[:lower:]')"
End
End

Describe 'arch()'
It 'returns current arch lowercased'
When call arch
The status should equal 0
The output should equal "$(uname -m | tr '[:upper:]' '[:lower:]')"
End
End

Describe 'is_os_supported()'
It 'returns true'
When call is_os_supported
The status should equal 0
End
End

Describe 'is_arch_supported()'
It 'returns true'
When call is_arch_supported
The status should equal 0
End
End

Describe 'os_arch()'
It 'returns the combined values'
When call os_arch
The status should equal 0
The output should equal "$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | tr '[:upper:]' '[:lower:]')"
End
End
End
24 changes: 24 additions & 0 deletions spec/spec_helper.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# shellcheck shell=sh

# Defining variables and functions here will affect all specfiles.
# Change shell options inside a function may cause different behavior,
# so it is better to set them here.
# set -eu

# This callback function will be invoked only once before loading specfiles.
spec_helper_precheck() {
# Available functions: info, warn, error, abort, setenv, unsetenv
# Available variables: VERSION, SHELL_TYPE, SHELL_VERSION
: minimum_version "0.28.1"
}

# This callback function will be invoked after a specfile has been loaded.
spec_helper_loaded() {
:
}

# This callback function will be invoked after core modules has been loaded.
spec_helper_configure() {
# Available functions: import, before_each, after_each, before_all, after_all
: import 'support/custom_matcher'
}
Empty file added spec/tmp/.gitkeep
Empty file.

0 comments on commit f83609b

Please sign in to comment.