9 Commits

Author SHA1 Message Date
4682664bf0 Update URL to GitHub raw content and bump version to 2.0.3
Replaced API URLs with GitHub raw content URLs for installation and updates to ensure reliability and consistency. Incremented the program version from 2.0.2 to 2.0.3 to reflect the changes.
2025-03-24 09:58:03 +02:00
1afeb7c5fa Update version to 2.0.2 and improve repository token handling
Bump the program version from 2.0.1 to 2.0.2. Enhance the repository token and API handling by allowing repository-specific [.api] and [.token] values to override global settings, with a fallback mechanism for global values. Added more comprehensive comments to clarify the override logic.
2024-10-07 18:18:11 +02:00
cac27adaf2 Add dry run, license setting & additional readme enhancement
Changes include implementing the dry run functionality, enabling the setting of license within the composer package, and allowing additional readme content to be appended to the usual readme. This development also entails minor code optimizations and bug fixes, making the package building scripts more robust and easier to use.
2024-06-29 23:56:00 +02:00
7a53c0acb9 Add exclude powers option. Add subshell to isolate variables. 2024-06-26 21:53:58 +02:00
fcb77c8f3e Fix namspace replace event to happen earlier. 2024-06-26 13:12:21 +02:00
709d26a389 Add option to string replace values in namespace and classes. 2024-06-26 10:53:42 +02:00
edc01a5372 Add extends interface. 2024-06-05 15:49:59 +02:00
ed1cd4fffa Skip comments in loadPower function
A new condition has been added to the loadPower function in src/octopower to identify and skip lines that start with //, which are treated as comments. Previously, the function validated and processed all lines without filtering out comments.
2024-06-03 18:15:45 +02:00
223c972795 Add link to classes where dependencies are. Add composer setup instructions. 2024-05-23 10:48:48 +02:00
2 changed files with 1999 additions and 1688 deletions

View File

@ -8,7 +8,7 @@ With this script we can easily package multiple power classes in an automated wa
---
# Install
```shell
$ sudo curl -L "https://git.vdm.dev/api/v1/repos/octoleo/octopower/raw/src/octopower" -o /usr/local/bin/octopower
$ sudo curl -L "https://raw.githubusercontent.com/octoleo/octopower/refs/heads/master/src/octopower" -o /usr/local/bin/octopower
$ sudo chmod +x /usr/local/bin/octopower
```
---

View File

@ -3,8 +3,8 @@
# Program name
PROGRAM_NAME="OctoPower"
PROGRAM_CODE="octopower"
PROGRAM_VERSION="1.0.0"
PROGRAM_V="1.0"
PROGRAM_VERSION="2.0.3"
PROGRAM_V="2.0"
PROGRAM_URL="https://git.vdm.dev/octoleo/${PROGRAM_CODE}"
# Do some prep work
@ -16,6 +16,10 @@ command -v curl >/dev/null 2>&1 || {
echo >&2 "[error] We require curl for $PROGRAM_NAME v${PROGRAM_VERSION} to work, but it's not installed. Aborting."
exit 1
}
command -v wget >/dev/null 2>&1 || {
echo >&2 "[error] We require wget for $PROGRAM_NAME v${PROGRAM_VERSION} to work, but it's not installed. Aborting."
exit 1
}
command -v jq >/dev/null 2>&1 || {
echo >&2 "[error] We require jq for $PROGRAM_NAME v${PROGRAM_VERSION} to work, but it's not installed. Aborting."
exit 1
@ -24,7 +28,13 @@ command -v zip >/dev/null 2>&1 || {
echo >&2 "[error] We require zip for $PROGRAM_NAME v${PROGRAM_VERSION} to work, but it's not installed. Aborting."
exit 1
}
command -v sed >/dev/null 2>&1 || {
echo >&2 "[error] We require sed for $PROGRAM_NAME v${PROGRAM_VERSION} to work, but it's not installed. Aborting."
exit 1
}
# Subshell to isolate variables
(
# main function ˘Ô≈ôﺣ
function main() {
# check if we have project overrides for the environment variables
@ -34,6 +44,8 @@ function main() {
clearMainEnv
exit 1
}
# when a dry run
showDryRunNotice
# get the package details
getPackageDetails || {
echo >&2 "[error] We require config file with correct packaging details for $PROGRAM_NAME v${PROGRAM_VERSION} to work, but it's not found in/at $VDM_PACKAGE_CONF_FILE. Aborting."
@ -60,6 +72,8 @@ function main() {
}
# set the package composer file
setPackageComposerFile
# set license
setLicenseFile
# set the readme
setReadMe
# get package repository
@ -82,6 +96,23 @@ function main() {
_echo "[Success] Package completely updated!"
}
# show dry run notice
function showDryRunNotice() {
_dry_run ""
_dry_run "======================================================================"
_dry_run " THIS IS A DRY RUN!"
_dry_run "======================================================================"
_dry_run ""
_dry_run " This means we will not update remote systems."
_dry_run " But will perform all expected tasks locally."
_dry_run " We will not clear folders and files created, and set locally."
_dry_run " Which mean you will need to clear those manually (after review)."
_dry_run ""
_dry_run "ALL remote changing events will be explained and marked as [dry-run]"
_dry_run "======================================================================"
_dry_run ""
}
# set the package details
function getPackageDetails() {
# little information of progress
@ -110,13 +141,16 @@ function getPackageDetails() {
getConfigValue 'VDM_PACKAGE_PHP' '.package.php' || has_error=true
getConfigValue 'VDM_PACKAGE_JOOMLA_FRAMEWORK' '.package.joomla_framework' false || unset VDM_PACKAGE_JOOMLA_FRAMEWORK
getConfigValue 'VDM_PACKAGE_VERSION' '.package.version' || has_error=true
getConfigValue 'VDM_LICENSE' '.package.license' || has_error=true
getConfigValue 'VDM_LICENSE_FILE' '.package.license_file' false || unset VDM_LICENSE_FILE
getConfigValue 'VDM_LICENSE_FILE_PATH' '.package.license_file_path' false || unset VDM_LICENSE_FILE_PATH
getConfigValue 'VDM_PACKAGE_LICENSE' '.package.license' || has_error=true
getConfigValue 'VDM_PACKAGE_LICENSE_FILE' '.package.license_file' false || unset VDM_PACKAGE_LICENSE_FILE
getConfigValue 'VDM_PACKAGE_LICENSE_FILE_PATH' '.package.license_file_path' false || unset VDM_PACKAGE_LICENSE_FILE_PATH
getConfigValue 'VDM_AUTHOR' '.package.author' false || unset VDM_AUTHOR
getConfigValue 'VDM_AUTHOR_EMAIL' '.package.author_email' false || unset VDM_AUTHOR_EMAIL
getConfigValue 'VDM_AUTHOR_URL' '.package.author_url' false || unset VDM_AUTHOR_URL
getConfigValue 'VDM_AUTHOR_ROLE' '.package.author_role' false || unset VDM_AUTHOR_ROLE
getConfigValue 'VDM_PACKAGE_ADDITIONAL_README' '.package.additional_readme' false || unset VDM_PACKAGE_ADDITIONAL_README
getConfigValue 'VDM_PACKAGE_ADDITIONAL_README_FILE' '.package.additional_readme_file' false || unset VDM_PACKAGE_ADDITIONAL_README_FILE
getConfigValue 'VDM_PACKAGE_README_FILE_PATH' '.package.readme_file_path' false || unset VDM_PACKAGE_README_FILE_PATH
# check if we have some errors already
$has_error && return 13
@ -147,6 +181,7 @@ function getRepositoryDetails() {
getConfigValue 'VDM_REPOSITORY_TOKEN_NAME' '.repository.token_name' false || VDM_REPOSITORY_TOKEN_NAME="VDM_GLOBAL_TOKEN"
getConfigValue 'VDM_REPOSITORY_URL_NAME' '.repository.url_name' false || VDM_REPOSITORY_URL_NAME="VDM_GLOBAL_URL"
getConfigValue 'VDM_REPOSITORY_API_NAME' '.repository.api_name' false || VDM_REPOSITORY_API_NAME="VDM_GLOBAL_API"
getConfigValue 'VDM_REPOSITORY_REPLACEMENT' '.repository.replace' false || unset VDM_REPOSITORY_REPLACEMENT
# set the package (api/url/toke)
tmp_token=${!VDM_REPOSITORY_TOKEN_NAME}
tmp_url=${!VDM_REPOSITORY_URL_NAME}
@ -175,27 +210,27 @@ function setPackageDir() {
# little information of progress
_echo "[info] Setting the Package Directories..."
# the full project path
VDM_PACKAGE_DIR="${VDM_MAIN_DIR}/${VDM_REPOSITORY_REPO}"
VDM_PACKAGE_GIT_DIR="${VDM_MAIN_DIR}/git"
VDM_PACKAGE_SRC_DIR="${VDM_PACKAGE_DIR}/src"
VDM_PACKAGE_ZIP_FILE="${VDM_PACKAGE_GIT_DIR}/${VDM_REPOSITORY_REPO}.${VDM_PACKAGE_VERSION:-1.0.0}.zip"
: "${VDM_PACKAGE_DIR:="${VDM_MAIN_DIR}/${VDM_REPOSITORY_REPO}"}"
: "${VDM_PACKAGE_GIT_DIR:="${VDM_MAIN_DIR}/git"}"
: "${VDM_PACKAGE_SRC_DIR:="${VDM_PACKAGE_DIR}/src"}"
: "${VDM_PACKAGE_ZIP_FILE:="${VDM_PACKAGE_GIT_DIR}/${VDM_REPOSITORY_REPO}.${VDM_PACKAGE_VERSION:-1.0.0}.zip"}"
# makes the project path available
export VDM_PACKAGE_DIR
export VDM_PACKAGE_GIT_DIR
export VDM_PACKAGE_SRC_DIR
export VDM_PACKAGE_ZIP_FILE
# always remove previous files (if found)
clearFiles
resetFiles
# set the license file
VDM_PACKAGE_LICENSE_FILE_PATH="${VDM_PACKAGE_DIR}/LICENSE"
: "${VDM_PACKAGE_LICENSE_FILE_PATH:="${VDM_PACKAGE_DIR}/LICENSE"}"
# set the README
: "${VDM_PACKAGE_README_FILE_PATH:="${VDM_PACKAGE_DIR}/README.md"}"
# set the package composer file
VDM_PACKAGE_COMPOSER_FILE="${VDM_PACKAGE_DIR}/composer.json"
# set the README
VDM_README_MD="${VDM_PACKAGE_DIR}/README.md"
# makes the project file locations available
export VDM_PACKAGE_LICENSE_FILE_PATH
export VDM_PACKAGE_README_FILE_PATH
export VDM_PACKAGE_COMPOSER_FILE
export VDM_README_MD
# make sure the packages dir is created
mkdir -p "${VDM_PACKAGE_DIR}" || return 12
#make sure the src dir is created
@ -214,6 +249,14 @@ function setPowers() {
local has_powers=false
# load all the repositories
loadSuperpowerRepositories || return 13
# Check if the .exclude-powers[] field exists and is not empty
if [ "$(echo "${VDM_CONFIG_DATA}" | jq '.exclude_powers | length')" -gt 0 ]; then
# Iterate over the exclude-powers array
for exclude_power in $(echo "${VDM_CONFIG_DATA}" | jq -r '.exclude_powers[]'); do
# Load the exclude power
loadExcludePower "${exclude_power}"
done
fi
# search for the powers
for power in $(echo "${VDM_CONFIG_DATA}" | jq -r '.powers[]'); do
# load the power
@ -225,14 +268,54 @@ function setPowers() {
return 0
}
# load the exclude power
function loadExcludePower() {
local guid="$1"
if [[ $guid == "//"* ]]; then
return 0 # skip comments ;)
elif [ ${#guid} -ge 30 ] && validateGuid "${guid}"; then
setExcludePower "$guid" || return 19
return 0
fi
return 0
}
# set the exclude power found
function setExcludePower() {
local guid="$1"
# Remove the power from VDM_POWERS if it exists
if existingPower "$guid"; then
VDM_POWERS=$(jq --arg guid "$guid" '
map(select(. != $guid))
' <<< "$VDM_POWERS")
fi
# check if we have already loaded this power
existingExcludePower "${guid}" && return 0
# Add the guid to VDM_EXCLUDE_POWERS
VDM_EXCLUDE_POWERS=$(jq --arg guid "$guid" '
. + [ $guid ]
' <<< "$VDM_EXCLUDE_POWERS")
return 0
}
# load the power
function loadPower() {
local guid="$1"
if [ ${#guid} -ge 30 ] && validateGuid "${guid}"; then
if [[ $guid == "//"* ]]; then
return 0 # skip comments ;)
elif [ ${#guid} -ge 30 ] && validateGuid "${guid}"; then
if existingExcludePower "$guid"; then
return 0 # skip excluded ;)
else
setPower "$guid" || return 19
loadChildrenPowers "$guid" || return 19
return 0
fi
fi
return 19
}
@ -263,7 +346,9 @@ function loadChildrenPowers() {
local has_error
local children_loaded
# some local vars
local guids
local extends
local extends_interfaces
local implements
local use_selection
local load_selection
@ -288,6 +373,7 @@ function loadChildrenPowers() {
addValueToPower "${guid}" 'children' "done"
# get the global config values if not set
setValueFromJson 'VDM_POWER_DATA' '.data' "${power}" || has_error=true
setValueFromJson 'VDM_POWER_USE_NAME' '.use_name' "${power}" || has_error=true
# could we get the data
if $has_error; then
_echo "[error] We could not get power data for ${guid} so the dependencies could not be loaded."
@ -299,23 +385,32 @@ function loadChildrenPowers() {
power_data="${VDM_POWER_DATA}"
# get th values if set
setValueFromJson 'VDM_POWER_EXTENDS' '.extends' "${power_data}"
setValueFromJson 'VDM_POWER_EXTENDS_INTERFACES' '.extendsinterfaces' "${power_data}"
setValueFromJson 'VDM_POWER_IMPLEMENTS' '.implements' "${power_data}"
setValueFromJson 'VDM_POWER_USE_SELECTION' '.use_selection' "${power_data}"
setValueFromJson 'VDM_POWER_LOAD_SELECTION' '.load_selection' "${power_data}"
setValueFromJson 'VDM_POWER_HEAD' '.head' "${power_data}"
# extract any joomla dependencies we might find
extractJoomlaUseStatements "${VDM_POWER_HEAD:-none}"
extractJoomlaUseStatements "${VDM_POWER_HEAD:-none}" "${VDM_POWER_USE_NAME}"
# TODO add more dynamic options
# setValueFromJson 'VDM_POWER_COMPOSER' '.composer' "${power_data}"
# check if we have VDM_POWER_EXTENDS
# we must add these locally to avoid collusion
extends="${VDM_POWER_EXTENDS:-0}"
extends_interfaces="${VDM_POWER_EXTENDS_INTERFACES:-null}"
implements="${VDM_POWER_IMPLEMENTS:-null}"
use_selection="${VDM_POWER_USE_SELECTION:-null}"
load_selection="${VDM_POWER_LOAD_SELECTION:-null}"
if [ "${extends}" != "0" ]; then
loadPower "${extends}"
fi
# Process the JSON array in extends_interfaces if it's not empty or null
if [ "${extends_interfaces}" != "null" ]; then
guids=$(echo "${extends_interfaces}" | jq -r '.[]')
for guid in $guids; do
loadPower "$guid"
done
fi
# Process the JSON array in implements if it's not empty or null
if [ "${implements}" != "null" ]; then
guids=$(echo "${implements}" | jq -r '.[]')
@ -343,6 +438,23 @@ function loadChildrenPowers() {
return 0
}
# Check if a given power already exists in VDM_EXCLUDE_POWERS
function existingExcludePower() {
local guid="$1"
local exists
# Check if the power is already in VDM_EXCLUDE_POWERS
exists=$(jq --arg guid "$guid" '
map(select(. == $guid)) | length > 0
' <<< "$VDM_EXCLUDE_POWERS")
if [ "$exists" = "true" ]; then
return 0 # GUID exists
else
return 1 # GUID does not exist
fi
}
# Check if a given power already exists in VDM_POWERS
function existingPower() {
local guid="$1"
@ -479,6 +591,7 @@ function setPowerData() {
local settings
local namespace
local name
local use_name
# get existing power
power=$(getExistingPower "${guid}")
if [ -z "$power" ]; then
@ -514,6 +627,8 @@ function setPowerData() {
clearPowerDataEnv
return 11
fi
# replace any strings in namespace as needed
[ -n "${VDM_REPOSITORY_REPLACEMENT}" ] && VDM_POWER_NAMESPACE=$(strReplace "${VDM_POWER_NAMESPACE}")
# we must add these locally to avoid collusion
owner="${VDM_POWER_OWNER}"
repo="${VDM_POWER_REPO}"
@ -524,6 +639,7 @@ function setPowerData() {
settings="${VDM_POWER_SETTINGS_URL}"
namespace="${VDM_POWER_NAMESPACE}"
name="${VDM_POWER_NAME}"
use_name="${VDM_POWER_NAMESPACE}\\${VDM_POWER_NAME}"
# little information of progress
_echo "[info] Getting (${namespace}\\${name}) power (${guid}) details."
# we first load the settings data
@ -537,6 +653,7 @@ function setPowerData() {
# check that we got data
if [ -n "${VDM_API_BUCKET}" ]; then
addJsonValueToPower "${guid}" 'data' "${VDM_API_BUCKET}"
addValueToPower "${guid}" 'use_name' "${use_name}"
else
# always clear memory
clearPowerDataEnv
@ -560,6 +677,8 @@ function setPowerData() {
mkdir -p "${class_path}"
# move the class into place
mv -f "${VDM_API_FILE_PATH}" "${class_path}/${name}.php"
# replace any strings in code as needed
[ -n "${VDM_REPOSITORY_REPLACEMENT}" ] && fileReplaceStrings "${class_path}/${name}.php"
else
# always clear memory
clearPowerDataEnv
@ -591,12 +710,19 @@ function loadSuperpowerRepositories() {
setValueFromJson 'VDM_BRANCH' '.branch' "${repository}" || VDM_BRANCH="default"
setValueFromJson 'VDM_API_NAME' '.api_name' "${repository}" || VDM_API_NAME="VDM_GLOBAL_API"
setValueFromJson 'VDM_TOKEN_NAME' '.token_name' "${repository}" || VDM_TOKEN_NAME="VDM_GLOBAL_TOKEN"
# Now check if the repository has its own `.api` and `.token` values
# If present, override the global values
if setValueFromJson 'VDM_API' '.api' "${repository}"; then
setValueFromJson 'VDM_TOKEN' '.token' "${repository}" || VDM_TOKEN=''
else
# set the package (api/toke)
tmp_api=${!VDM_API_NAME}
tmp_token=${!VDM_TOKEN_NAME}
# allow direct overriding (api/toke)
# allow direct overriding (api)
getConfigValue 'VDM_API' '.repository.api' false || VDM_API="${tmp_api}"
# allow direct overriding (toke)
getConfigValue 'VDM_TOKEN' '.repository.token' false || VDM_TOKEN="${tmp_token}"
fi
# check if we have some errors already
if $has_error; then
clearFileEnv
@ -698,6 +824,7 @@ function addNamespace() {
# extract Joomla use statements
function extractJoomlaUseStatements() {
local header_string="$1"
local use_name="$2"
# Check if the header string is empty
if [[ -z "$header_string" ]]; then
return
@ -715,14 +842,28 @@ function extractJoomlaUseStatements() {
# shellcheck disable=SC1003
extracted_namespace=$(echo "$namespace" | awk -F'\\' '{print $1 "\\" $2}')
JOOMLA_FRAMEWORK["$extracted_namespace"]=1
setLinkedDependencyClasses "${extracted_namespace}" "${use_name//\\//}" "${use_name}"
else
# Add the namespace to the associative array
JOOMLA_NAMESPACES["$namespace"]=1
setLinkedDependencyClasses "${namespace}" "${use_name//\\//}" "${use_name}"
fi
fi
done <<< "$header_string"
}
# set the linked classes to the dependencies
function setLinkedDependencyClasses() {
local main_key="$1"
local sub_key="$2"
local value="$3"
# Use jq to update the JSON structure
VDM_LINKED_CLASSES=$(echo "$VDM_LINKED_CLASSES" | jq --arg mk "$main_key" --arg sk "$sub_key" --arg val "$value" '
.[$mk][$sk] = $val
')
}
# just to clear all file ENVs
function clearPowerEnv() {
# SET IN: loadPowerRepositories
@ -760,6 +901,7 @@ function clearPowerChildrenEnv() {
unset VDM_POWER_LOAD_SELECTION
unset VDM_POWER_USE_SELECTION
unset VDM_POWER_HEAD
unset VDM_POWER_USE_NAME
unset VDM_POWER_COMPOSER
}
@ -787,7 +929,7 @@ function clearMainEnv() {
unset VDM_PACKAGE_ZIP_FILE
unset VDM_PACKAGE_LICENSE_FILE_PATH
unset VDM_PACKAGE_COMPOSER_FILE
unset VDM_README_MD
unset VDM_PACKAGE_README_FILE_PATH
# SET IN: getPackageDetails
unset VDM_CONFIG_DATA
unset VDM_PACKAGER
@ -804,9 +946,8 @@ function clearMainEnv() {
unset VDM_PACKAGE_PHP
unset VDM_PACKAGE_JOOMLA_FRAMEWORK
unset VDM_PACKAGE_VERSION
unset VDM_LICENSE
unset VDM_LICENSE_FILE
unset VDM_LICENSE_FILE_PATH
unset VDM_PACKAGE_LICENSE
unset VDM_PACKAGE_LICENSE_FILE
unset VDM_AUTHOR
unset VDM_AUTHOR_EMAIL
unset VDM_AUTHOR_URL
@ -826,6 +967,17 @@ function clearMainEnv() {
# clear all this projects files
function clearFiles() {
# when a dry run
_dry_run "[dry-run] We would have cleared all directories."
_dry_run "[dry-run] Therefore, ${VDM_PACKAGE_GIT_DIR:?}/${VDM_REPOSITORY_REPO:?} should still exist." && return 0
# always remove files
rm -fr "${VDM_PACKAGE_DIR:?}"
rm -fr "${VDM_PACKAGE_GIT_DIR:?}/${VDM_REPOSITORY_REPO:?}"
rm -fr "${VDM_PACKAGE_ZIP_FILE:?}"
}
# clear all the projects files if they exist
function resetFiles() {
# always remove files
rm -fr "${VDM_PACKAGE_DIR:?}"
rm -fr "${VDM_PACKAGE_GIT_DIR:?}/${VDM_REPOSITORY_REPO:?}"
@ -1088,37 +1240,85 @@ function getJoomlaFrameworkRequired() {
echo -n "$json"
}
# Convert JOOMLA_NAMESPACES to a Markdown list
function getJoomlaDependencies() {
if [ ${#JOOMLA_NAMESPACES[@]} -eq 0 ]; then
echo -n ""
else
local markdown_list="\n## Joomla CMS Dependencies\n\n"
markdown_list+=$(for key in "${!JOOMLA_NAMESPACES[@]}"; do
echo "- ${key}"
done | sort)
echo -e "$markdown_list\n"
# get the additional readme content
function getAdditionalReadme() {
# check if the additional readme content file is passed via a URL
if [ -n "${VDM_PACKAGE_ADDITIONAL_README_FILE}" ]; then
if [[ "${VDM_PACKAGE_ADDITIONAL_README_FILE}" =~ ^"http:" ]] || [[ "${VDM_PACKAGE_ADDITIONAL_README_FILE}" =~ ^"https:" ]]; then
# check if the URL is accessible
# shellcheck disable=SC2143
if [[ $(wget -S --spider "${VDM_PACKAGE_ADDITIONAL_README_FILE}" 2>&1 | grep 'HTTP/1.1 200 OK') ]]; then
echo ""
# fetch and print the content from the URL
wget --quiet -O - "${VDM_PACKAGE_ADDITIONAL_README_FILE}"
fi
elif [ -f "${VDM_PACKAGE_ADDITIONAL_README_FILE}" ]; then
echo ""
# print the content of the local file
cat "${VDM_PACKAGE_ADDITIONAL_README_FILE}"
fi
fi
# check if we have additional readme content set and print it
if [ -n "${VDM_PACKAGE_ADDITIONAL_README}" ]; then
echo ""
echo "${VDM_PACKAGE_ADDITIONAL_README}"
echo ""
fi
}
# Convert JOOMLA_FRAMEWORK to a Markdown list
function getJoomlaFramework() {
if [ ${#JOOMLA_FRAMEWORK[@]} -eq 0 ]; then
echo -n ""
else
local markdown_list="\n## Joomla Framework Dependencies\n\n"
markdown_list+="> Here we list the framework dependencies and provide links to where they are used.\n\n";
if [ -z "${VDM_PACKAGE_JOOMLA_FRAMEWORK}" ]; then
markdown_list+=">You can add the following to your project to insure the Joomla! framework classes are in your project.\n\n"
markdown_list+="> You should add the following to your project to ensure the Joomla! framework classes are included.\n\n"
for key in $(printf "%s\n" "${!JOOMLA_FRAMEWORK[@]}" | sort); do
markdown_list+="- \`composer require ${key//\\//} \"${VDM_PACKAGE_JOOMLA_FRAMEWORK:-~3.0}\"\`\n";
markdown_list+=$(getLinkedClassesMarkdown "${key}");
markdown_list+="\n";
done
else
markdown_list+=">We have added the following framework classes the required list of this composer package.\n\n"
markdown_list+="> We have added the following framework classes to the required list of this Composer package.\n\n"
for key in $(printf "%s\n" "${!JOOMLA_FRAMEWORK[@]}" | sort); do
markdown_list+="- ${key//\\//} \"${VDM_PACKAGE_JOOMLA_FRAMEWORK:-~3.0}\"\n";
markdown_list+=$(getLinkedClassesMarkdown "${key}");
markdown_list+="\n";
done
fi
markdown_list+=$(for key in "${!JOOMLA_FRAMEWORK[@]}"; do
echo "- \`composer require ${key//\\//} \"${VDM_PACKAGE_JOOMLA_FRAMEWORK:-~3.0}\"\`"
done | sort)
echo -e "$markdown_list\n"
echo -e "$markdown_list"
fi
}
# Convert JOOMLA_NAMESPACES to a Markdown list
function getJoomlaDependencies() {
if [ ${#JOOMLA_NAMESPACES[@]} -eq 0 ]; then
echo -n ""
else
local markdown_list="\n## Joomla CMS Dependencies\n\n"
markdown_list+="> Here we list the CMS dependencies and provide links to where they are used.\n\n";
for key in $(printf "%s\n" "${!JOOMLA_NAMESPACES[@]}" | sort); do
markdown_list+="- ${key}\n";
markdown_list+=$(getLinkedClassesMarkdown "${key}");
markdown_list+="\n";
done
echo -e "$markdown_list"
fi
}
# get the classes linked to this dependency
function getLinkedClassesMarkdown() {
local dependency="$1"
local subset
# Extract the subset for the given main_key
subset=$(echo "$VDM_LINKED_CLASSES" | jq --arg mk "$dependency" '.[$mk] // {}')
# Generate the markdown format
echo "$subset" | jq -r 'to_entries[] | " - [\(.value)](src/\(.key).php)"'
}
# convert VDM_NAME to the desired header format
function convertToHeader() {
local name="$1"
@ -1148,43 +1348,64 @@ function setReadMe() {
[ -n "${!VDM_PACKAGE_DESCRIPTION}" ] && echo "${!VDM_PACKAGE_DESCRIPTION}" || echo "${VDM_PACKAGE_DESCRIPTION}"
fi
echo ""
echo "## Details"
echo "## Composer Package Details"
echo ""
echo "- Packager: [${VDM_PACKAGER}](${VDM_PACKAGER_URL})"
echo "- Author: [${VDM_AUTHOR:-$PROGRAM_NAME}](${VDM_AUTHOR_URL:-$PROGRAM_URL})"
echo "- Creation Date: ${CREATION_DATE}"
getJoomlaDependencies
echo "- Package Build Date: ${VDM_PACKAGE_BUILD_DATE}"
echo ""
echo "### Installation via Composer"
echo ""
echo "Setup this registry in your \`~/.composer/config.json\` file:"
echo "\`\`\`"
echo "{"
echo " \"repositories\": [{"
echo " \"type\": \"composer\","
echo " \"url\": \"https://${VDM_REPOSITORY_URL}/api/packages/${VDM_REPOSITORY_OWNER}/composer\""
echo " }"
echo " ]"
echo "}"
echo "\`\`\`"
echo ""
echo "To install the package using Composer, run the following command:"
echo "\`\`\`"
echo "composer require ${VDM_NAME:-error}:${VDM_PACKAGE_VERSION:-1.0.0}"
echo "\`\`\`"
getAdditionalReadme
getJoomlaFramework
getJoomlaDependencies
echo ""
echo "### License"
echo "> ${VDM_LICENSE:-none}"
echo "> ${VDM_PACKAGE_LICENSE:-none}"
echo ""
} >"${VDM_README_MD}"
} >"${VDM_PACKAGE_README_FILE_PATH}"
}
# set the license file
function setLicenseFile() {
local has_error=false
# check if the license file is passed via a URL
if [[ "${VDM_LICENSE_FILE}" =~ ^"http:" ]] || [[ "${VDM_LICENSE_FILE}" =~ ^"https:" ]]; then
if [ -n "${VDM_PACKAGE_LICENSE_FILE}" ]; then
if [[ "${VDM_PACKAGE_LICENSE_FILE}" =~ ^"http:" ]] || [[ "${VDM_PACKAGE_LICENSE_FILE}" =~ ^"https:" ]]; then
# shellcheck disable=SC2143
if [[ $(wget -S --spider "${VDM_LICENSE_FILE}" 2>&1 | grep 'HTTP/1.1 200 OK') ]]; then
wget --quiet "${VDM_LICENSE_FILE}" -O "${VDM_LICENSE_FILE_PATH}"
VDM_LICENSE_FILE="LICENSE"
if [[ $(wget -S --spider "${VDM_PACKAGE_LICENSE_FILE}" 2>&1 | grep 'HTTP/1.1 200 OK') ]]; then
wget --quiet "${VDM_PACKAGE_LICENSE_FILE}" -O "${VDM_PACKAGE_LICENSE_FILE_PATH}"
else
echo >&2 "[error] The license:${VDM_LICENSE_FILE} is not a valid URL."
echo >&2 "[error] The license:${VDM_PACKAGE_LICENSE_FILE} is not a valid URL."
has_error=true
fi
elif [ -f "${VDM_LICENSE_DIR}/${VDM_LICENSE_FILE}" ]; then
elif [ -f "${VDM_LICENSE_DIR}/${VDM_PACKAGE_LICENSE_FILE}" ]; then
# now copy the license file
cp "${VDM_LICENSE_DIR}/${VDM_LICENSE_FILE}" "${VDM_LICENSE_FILE_PATH}"
cp "${VDM_LICENSE_DIR}/${VDM_PACKAGE_LICENSE_FILE}" "${VDM_PACKAGE_LICENSE_FILE_PATH}"
else
echo >&2 "[error] The license:${VDM_LICENSE_DIR}/${VDM_LICENSE_FILE} not found."
echo >&2 "[error] The license:${VDM_LICENSE_DIR}/${VDM_PACKAGE_LICENSE_FILE} not found."
has_error=true
fi
VDM_PACKAGE_LICENSE_FILE=$(basename "${VDM_PACKAGE_LICENSE_FILE_PATH}")
fi
# check if we have some errors
if $has_error; then
return 16
return 0
fi
# little information of progress
_echo "[info] Setting the License File..."
@ -1217,8 +1438,6 @@ function setRepository() {
if $update_repo && [[ -z $(git status --porcelain) ]]; then
_echo "[info] No changes found in (${VDM_REPOSITORY_OWNER}/${VDM_REPOSITORY_REPO}) repository"
else
# add user details
setUserDetails
# check if we must update or create repository
if $update_repo; then
# make API call
@ -1231,10 +1450,19 @@ function setRepository() {
else
message="Update"
fi
# add user details
setUserDetails
# get the repository last tag
makeGitCommit "${message}" "${VDM_PACKAGE_VERSION:-1.0.0}" "$VDM_TAG_EXIST" || return 28
# give little notice of progress
_echo "[info] Pushing changes to (${VDM_REPOSITORY_OWNER}/${VDM_REPOSITORY_REPO}) repository"
# when a dry run
_dry_run "[dry-run] We would have pushed the update to the existing repo on the Gitea system." && {
if ! $VDM_TAG_EXIST; then
_dry_run "[dry-run] We would have pushed the tags to the existing repo on the Gitea system."
fi
return 0
}
# make a normal push update
git push >/dev/null 2>&1 || return 30
if ! $VDM_TAG_EXIST; then
@ -1245,6 +1473,9 @@ function setRepository() {
setGitRepository || return 29
# give little notice of progress
_echo "[info] Pushing (TO CREATE) changes to (${VDM_REPOSITORY_OWNER}/${VDM_REPOSITORY_REPO}) repository"
# when a dry run
_dry_run "[dry-run] We would have pushed the changes to the new repo:${VDM_REPOSITORY_BRANCH} on the Gitea system."
_dry_run "[dry-run] We would have pushed the tags to the new repo on the Gitea system." && return 0
# push to creat the repository (if allowed)
if [[ "${VDM_REPOSITORY_BRANCH}" == 'default' ]]; then
git push -u origin master >/dev/null 2>&1 || return 30
@ -1289,6 +1520,8 @@ function setGitRepository() {
_echo "[info] Initializing the (${VDM_REPOSITORY_OWNER}/${VDM_REPOSITORY_REPO}) repository"
# initialize the repository
git init >/dev/null 2>&1 || return 29
# add user details
setUserDetails
# add the first commit
makeGitCommit "First Commit - ${VDM_PACKAGE_VERSION:-1.0.0}" "${VDM_PACKAGE_VERSION:-1.0.0}" >/dev/null 2>&1 || return 28
# little information of progress
@ -1378,6 +1611,10 @@ function setRepositoryNewFiles() {
# set a composer package
function setComposerPackage() {
# when a dry run
_dry_run "[dry-run] We would have removed ${VDM_PACKAGE_GIT_DIR}/${VDM_REPOSITORY_REPO}/.git"
_dry_run "[dry-run] Then we would have zipped ${VDM_PACKAGE_GIT_DIR}/${VDM_REPOSITORY_REPO} into ${VDM_PACKAGE_ZIP_FILE}"
_dry_run "[dry-run] Then we would have pushed the composer package up to the Gitea system." && return 0
# remove the git directory
rm -fr "${VDM_PACKAGE_GIT_DIR}/${VDM_REPOSITORY_REPO}/.git" || return 31
# zip the package
@ -1424,6 +1661,15 @@ function _echo() {
fi
}
# when this is a dry run
function _dry_run() {
if (("$VDM_DRY_RUN" == 1)); then
_echo "$1"
return 0
fi
return 1
}
# Zip the content of a path
function _zip() {
local folder_path="${1}"
@ -1444,6 +1690,56 @@ function _zip() {
return 1
}
# Perform string replacements (VDM_REPOSITORY_REPLACEMENT)
function strReplace() {
local content="$1"
local result="$content"
local pairs
local pair_decoded
local key
local value
# Extract keys and values and perform replacements
pairs=$(echo "$VDM_REPOSITORY_REPLACEMENT" | jq -r 'to_entries | .[] | @base64')
# Loop over the pairs without creating a subshell
while IFS= read -r pair; do
# Decode from base64
pair_decoded=$(echo "$pair" | base64 --decode)
key=$(echo "$pair_decoded" | jq -r .key)
value=$(echo "$pair_decoded" | jq -r .value)
# Perform replacements in the string
# shellcheck disable=SC2001
result=$(echo "$result" | sed "s|${key//\\/\\\\}|${value//\\/\\\\}|g")
done <<< "$pairs" # Redirect the variable into the loop to avoid subshells
echo "$result"
}
# Replace strings in a file directly (VDM_REPOSITORY_REPLACEMENT)
function fileReplaceStrings() {
local file_path="$1"
# Check if the file exists
if [[ ! -f "$file_path" ]]; then
echo "File does not exist: $file_path"
return 1
fi
# Extract keys and values and perform replacements
echo "$VDM_REPOSITORY_REPLACEMENT" | jq -r 'to_entries | .[] | @base64' |
while IFS= read -r pair; do
# Decode from base64
pair_decoded=$(echo "$pair" | base64 --decode)
key=$(echo "$pair_decoded" | jq -r .key)
value=$(echo "$pair_decoded" | jq -r .value)
# Perform replacements in the file using unescaped values
sed -i "s|${key//\\/\\\\}|${value//\\/\\\\}|g" "$file_path"
done
}
# uninstalls the octopc program.
function runUninstall() {
# now remove the script
@ -1489,7 +1785,7 @@ function runUpdate() {
sudo mv "/usr/local/bin/${PROGRAM_CODE}" "/usr/local/bin/${PROGRAM_CODE}.bak"
fi
# pull the latest version. Master is always the latest
if sudo curl --fail -L "https://git.vdm.dev/api/v1/repos/octoleo/${PROGRAM_CODE}/raw/src/${PROGRAM_CODE}?ref=${branch:-master}" -o "/usr/local/bin/${PROGRAM_CODE}" 2>/dev/null; then
if sudo curl --fail -L "https://raw.githubusercontent.com/octoleo/${PROGRAM_CODE}/refs/heads/${branch:-master}/src/${PROGRAM_CODE}" -o "/usr/local/bin/${PROGRAM_CODE}" 2>/dev/null; then
# give success message
echo "[success] Update was successful."
# do we have a backup
@ -1587,15 +1883,18 @@ START_BUILD=$(date +"%s")
# use UTC+00:00 time also called zulu
# shellcheck disable=SC2034
START_DATE=$(TZ=":ZULU" date +"%m/%d/%Y @ %R (UTC)")
CREATION_DATE=$(TZ=":ZULU" date +"%B %Y")
VDM_PACKAGE_BUILD_DATE=$(TZ=":ZULU" date +"%B %Y")
# the quiet switch
QUIET="${QUIET:-0}"
: "${QUIET:=0}"
# the dry run switch
: "${VDM_DRY_RUN:=0}"
# we set the packager directories
tmp_path="/home/$USER/${PROGRAM_CODE}"
# ALWAYS USE GLOBAL IF SET
VDM_MAIN_DIR="${VDM_MAIN_DIR:-$tmp_path}"
: "${VDM_MAIN_DIR:="${VDM_MAIN_DIR:-$tmp_path}"}"
# we set the licenses directory
tmp_path="${VDM_MAIN_DIR}/licenses"
@ -1603,7 +1902,7 @@ tmp_path="${VDM_MAIN_DIR}/licenses"
# if path not set try $PWD path
[ -d "$tmp_path" ] || tmp_path="$PWD"
# ALWAYS USE GLOBAL IF SET
VDM_LICENSE_DIR="${VDM_LICENSE_DIR:-$tmp_path}"
: "${VDM_LICENSE_DIR:="$tmp_path"}"
# the environment file variables path
tmp_path="$PWD/.env_${PROGRAM_CODE}"
@ -1612,7 +1911,7 @@ tmp_path="$PWD/.env_${PROGRAM_CODE}"
# if file not set try $VDM_MAIN_DIR path
[ -f "$tmp_path" ] || tmp_path="/home/$USER/.config/${PROGRAM_CODE}/.env"
# ALWAYS USE GLOBAL IF SET
VDM_ENV_FILE_PATH="${VDM_ENV_FILE_PATH:-$tmp_path}"
: "${VDM_ENV_FILE_PATH:="$tmp_path"}"
# clear this tmp out
unset tmp_path
@ -1627,6 +1926,9 @@ while :; do
-q | --quiet)
QUIET=1
;;
-n | --dry-run)
VDM_DRY_RUN=1
;;
--uninstall)
runUninstall
shift
@ -1656,6 +1958,13 @@ while :; do
exit 17
fi
;;
-l=* | --licence=*)
VDM_PACKAGE_LICENSE=${1#*=}
if [ -z "$VDM_PACKAGE_LICENSE" ]; then
echo '[error] "--licence" requires a non-empty option argument.'
exit 17
fi
;;
-ld=* | --licence-dir=*)
VDM_LICENSE_DIR=${1#*=}
if [ -z "$VDM_LICENSE_DIR" ]; then
@ -1726,8 +2035,10 @@ if [ -f "$VDM_ENV_FILE_PATH" ]; then
fi
# Initialize the global JSON array if not already initialized
VDM_SUPERPOWERS=${VDM_SUPERPOWERS:-"[]"}
VDM_POWERS=${VDM_POWERS:-"[]"}
: "${VDM_SUPERPOWERS:="[]"}"
: "${VDM_POWERS:="[]"}"
: "${VDM_EXCLUDE_POWERS:="[]"}"
# Create a global temporary file to store the dataset
VDM_SUPERPOWERS_FILE=$(mktemp)
# Initialize the global variable as an empty array or use the environment value if provided
@ -1740,13 +2051,14 @@ fi
# Global array to store Joomla namespaces
declare -A JOOMLA_NAMESPACES
declare -A JOOMLA_FRAMEWORK
VDM_LINKED_CLASSES=$(jq -n '{}')
# if path not set try $PWD path (so you can open a folder that has .octopc file and it will be loaded)
tmp_path="$PWD/.${PROGRAM_CODE}"
# if file not set try $VDM_MAIN_DIR path
[ -f "$tmp_path" ] || tmp_path="$VDM_MAIN_DIR/.${PROGRAM_CODE}"
# ALWAYS USE GLOBAL IF SET
VDM_PACKAGE_CONF_FILE=${VDM_PACKAGE_CONF_FILE:-$tmp_path}
: "${VDM_PACKAGE_CONF_FILE:="$tmp_path"}"
# Check if the config file is passed as a URL
if [[ "$VDM_PACKAGE_CONF_FILE" =~ ^http: ]] || [[ "$VDM_PACKAGE_CONF_FILE" =~ ^https: ]]; then
@ -1754,10 +2066,8 @@ if [[ "$VDM_PACKAGE_CONF_FILE" =~ ^http: ]] || [[ "$VDM_PACKAGE_CONF_FILE" =~ ^h
if curl --output /dev/null --silent --head --fail "$VDM_PACKAGE_CONF_FILE"; then
# Create the directory for the configuration file if it doesn't exist
mkdir -p "$HOME/.config/$PROGRAM_CODE/projects"
# get a file name
file_name=$(getUniqueFileName "$VDM_PACKAGE_CONF_FILE")
# Download the configuration file
curl --silent "$VDM_PACKAGE_CONF_FILE" -o "$HOME/.config/$PROGRAM_CODE/projects/${file_name}_conf.json"
VDM_PACKAGE_CONF_FILE="$HOME/.config/$PROGRAM_CODE/projects/${file_name}_conf.json"
@ -1775,6 +2085,7 @@ fi
}
# run Main ┬┴┬┴┤(・_├┬┴┬┴
main
main "$@"
)
exit 0