diff --git a/.builder-post-rsync-filters-post b/.builder-post-rsync-filters-post new file mode 100644 index 00000000..baadf122 --- /dev/null +++ b/.builder-post-rsync-filters-post @@ -0,0 +1,6 @@ +- composer.json +- composer.lock +- vendor/publishpress/vendor-locator/composer.json +- vendor/publishpress/wordpress-banners/.gitattributes +- vendor/woocommerce/action-scheduler/README.md +- vendor/woocommerce/action-scheduler/changelog.txt diff --git a/.builder-rsync-filters b/.builder-rsync-filters new file mode 100644 index 00000000..0e362eed --- /dev/null +++ b/.builder-rsync-filters @@ -0,0 +1,43 @@ +- *.code-workspace +- .babelrc +- .builder-post-rsync-filters-post +- .builder-rsync-filters +- .distignore +- .git +- .gitattributes +- .github +- .gitignore +- .idea +- .php-cs-fixer.cache +- .phpcs.xml +- .phplint-cache +- .phplint.yml +- .vscode +- .wordpress-org +- Gruntfile.js +- README-build.md +- README.md +- RoboFile.php +- assets/jsx +- bin +- builder +- builder.yml +- codeception.dist.yml +- cs +- dev-workspace +- dist +- jsconfig.json +- node_modules +- package-lock.json +- package.json +- psalm.xml +- ray-dist.php +- ray.php +- screenshot-*.png +- tests +- /vendor +- /vendor/publishpress/vendor-locator/composer.json +- /vendor/publishpress/wordpress-banners/.gitattributes +- /version.txt +- /webpack.config.js +- /yarn.lock diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..78c4e8ee --- /dev/null +++ b/.gitattributes @@ -0,0 +1,41 @@ +*.code-workspace export-ignore +.babelrc export-ignore +.builder-post-rsync-filters-post export-ignore +.builder-rsync-filters export-ignore +.distignore export-ignore +.git export-ignore +.gitattributes export-ignore +.github export-ignore +.gitignore export-ignore +.idea export-ignore +.php-cs-fixer.cache export-ignore +.phpcs.xml export-ignore +.phplint-cache export-ignore +.phplint.yml export-ignore +.vscode export-ignore +.wordpress-org export-ignore +Gruntfile.js export-ignore +README-build.md export-ignore +README.md export-ignore +RoboFile.php export-ignore +assets/jsx export-ignore +bin export-ignore +builder export-ignore +builder.yml export-ignore +codeception.dist.yml export-ignore +cs export-ignore +dev-workspace export-ignore +dist export-ignore +jsconfig.json export-ignore +node_modules export-ignore +package-lock.json export-ignore +package.json export-ignore +psalm.xml export-ignore +ray-dist.php export-ignore +ray.php export-ignore +screenshot-*.png export-ignore +tests export-ignore +version.txt export-ignore +webpack.config.js export-ignore +yarn.lock export-ignore +version.txt export-ignore diff --git a/.gitignore b/.gitignore index 827688ad..68d75f04 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,10 @@ wp-content/plugins/hello.php /sitemap.xml /sitemap.xml.gz -.idea/ -.vscode/ +/.idea +/.vscode modules/presspermit-collaboration/.vscode/launch.json + +/vendor +/dist +/version.txt diff --git a/composer.json b/composer.json index 63f17f28..89c76de3 100644 --- a/composer.json +++ b/composer.json @@ -17,17 +17,28 @@ } ], "config": { - "preferred-install": "dist" + "preferred-install": { + "*": "dist" + } }, "minimum-stability": "stable", "prefer-stable": true, "require": { "php": ">=7.2.5", "publishpress/vendor-locator-permissions": "^1.0", - "publishpress/pimple-pimple": "^3.5.0.9", - "publishpress/psr-container": "^2.0.1.9", - "publishpress/wordpress-reviews": "^1.1", + "publishpress/wordpress-reviews": "^1.1", "publishpress/instance-protection": "^2.0", "publishpress/wordpress-version-notices": "^2.1" + }, + "scripts": { + "build": "/project/dev-workspace/docker/scripts/ppbuild build", + "build:dir": "/project/dev-workspace/docker/scripts/ppbuild build-dir", + "build:clean": "/project/dev-workspace/docker/scripts/ppbuild clean", + "get-version": "/project/dev-workspace/docker/scripts/ppbuild version" + }, + "extra": { + "plugin-slug": "press-permit-core", + "plugin-name": "publishpress-permissions", + "plugin-folder": "press-permit-core" } } diff --git a/composer.lock b/composer.lock index 9b421ad4..afdfd2ba 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "86192053445aa8de6acea25ad68fe04e", + "content-hash": "b3d45132c0d877e6dd7ca98a858eeaa9", "packages": [ { "name": "publishpress/instance-protection", diff --git a/dev-workspace/build b/dev-workspace/build new file mode 100755 index 00000000..f938e856 --- /dev/null +++ b/dev-workspace/build @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +docker compose -f docker/compose.yaml build diff --git a/dev-workspace/build-push b/dev-workspace/build-push new file mode 100755 index 00000000..9f3f43e6 --- /dev/null +++ b/dev-workspace/build-push @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +# This command requires to be logged in on Docker Hub. Check `docker login --help` for more information. + +docker buildx build --platform linux/amd64,linux/arm64 --push -t publishpress/dev-workspace-terminal:permissions-free ./docker diff --git a/dev-workspace/cache/.gitignore b/dev-workspace/cache/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/dev-workspace/cache/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/dev-workspace/docker/Dockerfile b/dev-workspace/docker/Dockerfile new file mode 100644 index 00000000..ff93dc9f --- /dev/null +++ b/dev-workspace/docker/Dockerfile @@ -0,0 +1,218 @@ +FROM php:8.0-cli + +#################################################################################################### +# Install base dependencies +#################################################################################################### + +RUN set -ex; \ + \ + # Prepare for installing docker-cli + apt-get update && \ + apt-get install -y \ + apt-transport-https \ + ca-certificates \ + curl \ + gnupg-agent \ + software-properties-common && \ + curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - && \ + add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" && \ + \ + # Prepare for installing yarn + curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ + echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ + \ + # Install base dependencies + apt-get update; \ + apt-get install -y \ + build-essential \ + libyaml-dev \ + g++ \ + make \ + autoconf \ + libzip-dev \ + curl \ + libcurl4-openssl-dev \ + wget \ + bash \ + coreutils \ + git \ + openssh-client \ + patch \ + subversion \ + tini \ + unzip \ + zip \ + rsync \ + python3.5 \ + python3-pip \ + nano \ + vim \ + zsh \ + iputils-ping \ + net-tools \ + default-mysql-client \ + bsdmainutils \ + docker.io \ + docker-compose \ + yarn \ + ; \ + mkdir -p /usr/src/php/ext/yaml; \ + curl -fsSL https://pecl.php.net/get/yaml | tar xvz -C "/usr/src/php/ext/yaml" --strip 1; \ + \ + docker-php-ext-configure zip; \ + docker-php-ext-install zip gettext yaml mysqli pdo_mysql; \ + \ + apt-get purge -y --auto-remove; \ + rm -rf /var/lib/apt/lists/* + +#################################################################################################### +# Install ZSH +#################################################################################################### + +# More info: https://github.com/deluan/zsh-in-docker + +RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/v1.1.3/zsh-in-docker.sh)" -- \ + -t ys \ + -p git \ + -p asdf \ + -p ag \ + -p wp-cli + +COPY root/.zshrc /root/.zshrc + +#################################################################################################### +# Configure PHP ini +#################################################################################################### + +RUN { \ +# https://www.php.net/manual/en/errorfunc.constants.php +# https://github.com/docker-library/wordpress/issues/420#issuecomment-517839670 + echo 'error_reporting = E_ERROR | E_WARNING | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_RECOVERABLE_ERROR'; \ + echo 'display_errors = Off'; \ + echo 'display_startup_errors = Off'; \ + echo 'log_errors = On'; \ + echo 'error_log = /dev/stderr'; \ + echo 'log_errors_max_len = 1024'; \ + echo 'ignore_repeated_errors = On'; \ + echo 'ignore_repeated_source = Off'; \ + echo 'html_errors = Off'; \ + } > /usr/local/etc/php/conf.d/error-logging.ini + +#################################################################################################### +# Install Composer +#################################################################################################### + +RUN printf "# composer php cli ini settings\n\ +date.timezone=UTC\n\ +memory_limit=-1\n\ +" > $PHP_INI_DIR/php-cli.ini + +RUN mkdir /root/.composer + +ENV COMPOSER_ALLOW_SUPERUSER 1 +ENV COMPOSER_HOME /root/.composer +ENV COMPOSER_VERSION 2.3.9 + +RUN set -eux ; \ + # install https://github.com/mlocati/docker-php-extension-installer + curl \ + --silent \ + --fail \ + --location \ + --retry 3 \ + --output /usr/local/bin/install-php-extensions \ + --url https://github.com/mlocati/docker-php-extension-installer/releases/download/1.5.47/install-php-extensions \ + ; \ + echo a4703daabe294839f00d995675cdad02a19a5b585d9e96bf2a9ddda2306afa8de472473c83a02f70b86af88226f493a181b24cb602bfd32404f22ce2cb889349 /usr/local/bin/install-php-extensions | sha512sum --strict --check ; \ + chmod +x /usr/local/bin/install-php-extensions ; \ + # install public keys for snapshot and tag validation, see https://composer.github.io/pubkeys.html + curl \ + --silent \ + --fail \ + --location \ + --retry 3 \ + --output /tmp/keys.dev.pub \ + --url https://raw.githubusercontent.com/composer/composer.github.io/e7f28b7200249f8e5bc912b42837d4598c74153a/snapshots.pub \ + ; \ + echo 572b963c4b7512a7de3c71a788772440b1996d918b1d2b5354bf8ba2bb057fadec6f7ac4852f2f8a8c01ab94c18141ce0422aec3619354b057216e0597db5ac2 /tmp/keys.dev.pub | sha512sum --strict --check ; \ + curl \ + --silent \ + --fail \ + --location \ + --retry 3 \ + --output /tmp/keys.tags.pub \ + --url https://raw.githubusercontent.com/composer/composer.github.io/e7f28b7200249f8e5bc912b42837d4598c74153a/releases.pub \ + ; \ + echo 47f374b8840dcb0aa7b2327f13d24ab5f6ae9e58aa630af0d62b3d0ea114f4a315c5d97b21dcad3c7ffe2f0a95db2edec267adaba3f4f5a262abebe39aed3a28 /tmp/keys.tags.pub | sha512sum --strict --check ; \ + # download installer.php, see https://getcomposer.org/download/ + curl \ + --silent \ + --fail \ + --location \ + --retry 3 \ + --output /tmp/installer.php \ + --url https://raw.githubusercontent.com/composer/getcomposer.org/0a51b6fe383f7f61cf1d250c742ec655aa044c94/web/installer \ + ; \ + echo ba79d97d127330ad12538395723d3c6bdabacd010bb8b845b900f2e5e3de0ad199b41d21e9fbe7a9c01f5a88a827c9da2dac3ba09da64648e63ad4eef069e48e /tmp/installer.php | sha512sum --strict --check ; \ + # install composer phar binary + php /tmp/installer.php \ + --no-ansi \ + --install-dir=/usr/bin \ + --filename=composer \ + --version=${COMPOSER_VERSION} \ + ; \ + composer --ansi --version --no-interaction ; \ + composer diagnose ; \ + rm -f /tmp/installer.php ; \ + find /tmp -type d -exec chmod -v 1777 {} + + +#################################################################################################### +# Install node.js LTS version +#################################################################################################### + +ENV NODE_VERSION=14.19.3 +ENV NPM_VERSION=6.14.17 +ENV NVM_DIR=/root/.nvm +ENV PATH="/root/.nvm/versions/node/v${NODE_VERSION}/bin/:${PATH}" +RUN curl \ + --silent \ + --fail \ + --location \ + --retry 3 \ + --output /tmp/nvm-install.sh \ + --url https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh \ + ; \ + echo c6e6e30aa7fdba27a5e9b3d5b47cf5d93043b775f316e6aa2ee6981bcd3e074e88d35ed136bc050deb73e4db8047b4be86fb02a5b6bd83b8726fb068622072d9 /tmp/nvm-install.sh | sha512sum --strict --check ; \ + bash /tmp/nvm-install.sh + +RUN . "$NVM_DIR/nvm.sh" && nvm install ${NODE_VERSION} +RUN . "$NVM_DIR/nvm.sh" && nvm use v${NODE_VERSION} +RUN . "$NVM_DIR/nvm.sh" && nvm alias default v${NODE_VERSION} +RUN node --version + +RUN npm install -g npm@${NPM_VERSION} + +RUN npm --version +RUN yarn --version + +#################################################################################################### +# Install Python libs +#################################################################################################### + +# RUN pip3 install med2image + +#################################################################################################### +# Configure the image +#################################################################################################### + +RUN mkdir /project + +VOLUME /project + +WORKDIR /project + +COPY scripts/ppbuild /usr/local/bin/ppbuild + +ENV PATH="/project/node_modules/.bin:/project/vendor/bin:$PATH" + +RUN chmod +x /usr/local/bin/ppbuild diff --git a/dev-workspace/docker/compose.yaml b/dev-workspace/docker/compose.yaml new file mode 100644 index 00000000..6249b7d0 --- /dev/null +++ b/dev-workspace/docker/compose.yaml @@ -0,0 +1,23 @@ +name: devworkspace_permissions_free +services: + terminal: + build: ./docker + image: publishpress/dev-workspace-terminal:permissions-free + command: ["zsh"] + stdin_open: true + tty: true + working_dir: "/project" + volumes: + - ../../:/project + - ../cache/.zsh_history:/root/.zsh_history + - ../cache/.bash_history:/root/.bash_history + - ../cache/.npm/_cacache:/root/.npm/_cacache + - ../cache/.npm/_logs:/root/.npm/_logs + - ../cache/.oh-my-zsh/log:/root/.oh-my-zsh/log + - ../cache/.composer/cache:/root/.composer/cache + - ../cache/.composer/auth.json:/root/.composer/auth.json + - /var/run/docker.sock:/var/run/docker.sock + extra_hosts: + - "dockerhost:${DOCKER_HOST_IP}" + environment: + - DOCKER_HOST_IP=${DOCKER_HOST_IP} diff --git a/dev-workspace/docker/root/.zshrc b/dev-workspace/docker/root/.zshrc new file mode 100644 index 00000000..d04c137c --- /dev/null +++ b/dev-workspace/docker/root/.zshrc @@ -0,0 +1,119 @@ +# If you come from bash you might have to change your $PATH. +export PATH=/project/node_modules/.bin:/project/vendor/bin:$PATH + +# Path to your oh-my-zsh installation. +export ZSH="$HOME/.oh-my-zsh" + +# Set name of the theme to load --- if set to "random", it will +# load a random theme each time oh-my-zsh is loaded, in which case, +# to know which specific one was loaded, run: echo $RANDOM_THEME +# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes +ZSH_THEME="ys" + +# Set list of themes to pick from when loading at random +# Setting this variable when ZSH_THEME=random will cause zsh to load +# a theme from this variable instead of looking in $ZSH/themes/ +# If set to an empty array, this variable will have no effect. +# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" ) + +# Uncomment the following line to use case-sensitive completion. +# CASE_SENSITIVE="true" + +# Uncomment the following line to use hyphen-insensitive completion. +# Case-sensitive completion must be off. _ and - will be interchangeable. +# HYPHEN_INSENSITIVE="true" + +# Uncomment one of the following lines to change the auto-update behavior +# zstyle ':omz:update' mode disabled # disable automatic updates +# zstyle ':omz:update' mode auto # update automatically without asking +# zstyle ':omz:update' mode reminder # just remind me to update when it's time + +# Uncomment the following line to change how often to auto-update (in days). +# zstyle ':omz:update' frequency 13 + +# Uncomment the following line if pasting URLs and other text is messed up. +# DISABLE_MAGIC_FUNCTIONS="true" + +# Uncomment the following line to disable colors in ls. +# DISABLE_LS_COLORS="true" + +# Uncomment the following line to disable auto-setting terminal title. +# DISABLE_AUTO_TITLE="true" + +# Uncomment the following line to enable command auto-correction. +# ENABLE_CORRECTION="true" + +# Uncomment the following line to display red dots whilst waiting for completion. +# You can also set it to another string to have that shown instead of the default red dots. +# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f" +# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765) +# COMPLETION_WAITING_DOTS="true" + +# Uncomment the following line if you want to disable marking untracked files +# under VCS as dirty. This makes repository status check for large repositories +# much, much faster. +# DISABLE_UNTRACKED_FILES_DIRTY="true" + +# Uncomment the following line if you want to change the command execution time +# stamp shown in the history command output. +# You can set one of the optional three formats: +# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd" +# or set a custom format using the strftime function format specifications, +# see 'man strftime' for details. +# HIST_STAMPS="mm/dd/yyyy" + +# Would you like to use another custom folder than $ZSH/custom? +# ZSH_CUSTOM=/path/to/new-custom-folder + +# Which plugins would you like to load? +# Standard plugins can be found in $ZSH/plugins/ +# Custom plugins may be added to $ZSH_CUSTOM/plugins/ +# Example format: plugins=(rails git textmate ruby lighthouse) +# Add wisely, as too many plugins slow down shell startup. +plugins=(git asdf ag wp-cli docker) + +source $ZSH/oh-my-zsh.sh + +# User configuration + +# export MANPATH="/usr/local/man:$MANPATH" + +# You may need to manually set your language environment +# export LANG=en_US.UTF-8 + +# Preferred editor for local and remote sessions +# if [[ -n $SSH_CONNECTION ]]; then +# export EDITOR='vim' +# else +# export EDITOR='mvim' +# fi + +# Compilation flags +# export ARCHFLAGS="-arch x86_64" + +# Set personal aliases, overriding those provided by oh-my-zsh libs, +# plugins, and themes. Aliases can be placed here, though oh-my-zsh +# users are encouraged to define aliases within the ZSH_CUSTOM folder. +# For a full list of active aliases, run `alias`. +# +# Example aliases +# alias zshconfig="mate ~/.zshrc" +# alias ohmyzsh="mate ~/.oh-my-zsh" + +export PROJECT_PATH="/project" + +export PROMPT=" +%{$bg[magenta]%}%{$fg[white]%} 🐧 PublishPress Permissions - Dev-Workspace %{$reset_color%} %{$bg[cyan]%}%{$fg[black]%} FREE %{$reset_color%} +%{$terminfo[bold]$fg[blue]%}#%{$reset_color%} \ +%(#,%{$bg[yellow]%}%{$fg[black]%}%n%{$reset_color%},%{$fg[cyan]%}%n) \ +%{$reset_color%}@ \ +%{$fg[green]%}%m \ +%{$reset_color%}in \ +%{$terminfo[bold]$fg[yellow]%}%~%{$reset_color%}\ +${hg_info}\ +${git_info}\ +${svn_info}\ +${venv_info}\ + \ +[%*] $exit_code +%{$terminfo[bold]$fg[magenta]%}➜ %{$reset_color%}" diff --git a/dev-workspace/docker/scripts/host-ip b/dev-workspace/docker/scripts/host-ip new file mode 100755 index 00000000..074cccbf --- /dev/null +++ b/dev-workspace/docker/scripts/host-ip @@ -0,0 +1,12 @@ +#!/bin/bash + +if [[ $(uname) == "Linux" ]]; then + export DOCKER_HOST_IP=$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -f1 -d'/') +elif [[ $(uname) == "Darwin" ]]; then + export DOCKER_HOST_IP=$(ifconfig | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}') +else + echo "Unsupported operating system" + exit 1 +fi + +echo "$DOCKER_HOST_IP" diff --git a/dev-workspace/docker/scripts/modules/prompt-user.mjs b/dev-workspace/docker/scripts/modules/prompt-user.mjs new file mode 100644 index 00000000..6f014817 --- /dev/null +++ b/dev-workspace/docker/scripts/modules/prompt-user.mjs @@ -0,0 +1,22 @@ +import { execSync } from 'child_process'; +import inquirer from 'inquirer'; + +const exec = commands => { + execSync(commands, {stdio: 'inherit', shell: true}); +}; + +export const promptUser = () => { + return inquirer.prompt([ + { + type: "list", + name: "version", + message: "Select a PHP version", + choices: ["5.6", "7.2", "7.4", "8.0", "8.1", "8.2"] + }, + ]); +}; + +export const executeCommand = (command, version) => { + const commandWithVersion = command.replace('{{VERSION}}', version); + exec(commandWithVersion); +}; diff --git a/dev-workspace/docker/scripts/parse-json.php b/dev-workspace/docker/scripts/parse-json.php new file mode 100644 index 00000000..2ca82d75 --- /dev/null +++ b/dev-workspace/docker/scripts/parse-json.php @@ -0,0 +1,48 @@ +/dev/null 2>&1 + echo_step "Creating the zip file on dist/${zip_filename}" + zip -qr "${zip_path}" ./${plugin_folder} + popd >/dev/null 2>&1 +} + +####################################### +# Show the elapsed time since the script started. +# Globals: +# start_time +# Outputs: +# The runtime in seconds. +####################################### +show_time() { + if [ "${HIDE_HEADER}" != "1" ]; then + end_time=$(date +%s) + runtime=$((end_time - start_time)) + echo "" + echo "Runtime $runtime sec" + fi +} + +####################################### +# Repeats a string "n" times. +# Arguments: +# The string to be repeated. +# The number of times to repeat. +# Outputs: +# The repeated string. +####################################### +repeat() { + for ((c = 1; c <= "${2}"; c++)); do + echo -n "${1}" + done +} + +####################################### +# Show the header for the script, showing +# a few details of the plugin. +# Globals: +# script_version +# plugin_name +# plugin_version +# plugin_slug +# Outputs: +# The formatted header. +####################################### +echo_header() { + repeat "=" $cols + line=$(repeat "-" $(($cols - 16))) + echo " __ PUBLISHPRESS PLUGIN BUILDER - v${script_version}" + echo " -=(o '. ${line}" + echo " '.-.\ Name: ${plugin_name}" + echo " /| \\\ Slug: ${plugin_slug}" + echo " '| || Folder: ${plugin_folder}" + echo " _\_):,_ Version: ${plugin_version}" + echo "" + repeat "=" $cols + echo "" +} + +####################################### +if [ "${HIDE_HEADER}" != "1" ]; then + echo_header +fi + +case "${command}" in +"build-dir") + echo "Building to dist dir:" + echo "" + build_to_dir + echo "" + echo "Plugin successfully built to the dist dir!" + show_time + ;; +"build") + echo "Building to zip file:" + echo "" + build_to_dir + pack_built_dir + clean_dist + echo "" + echo "Plugin successfully built to a zip file!" + show_time + ;; +"clean") + echo "Cleaning directory on dist dir:" + echo "" + clean_dist + ;; +"version") + echo "${plugin_version}" > version.txt + ;; +*) + echo "invalid option ${command}" + ;; +esac diff --git a/dev-workspace/docker/scripts/pptests b/dev-workspace/docker/scripts/pptests new file mode 100755 index 00000000..6e6599cc --- /dev/null +++ b/dev-workspace/docker/scripts/pptests @@ -0,0 +1,552 @@ +#!/usr/bin/env bash +start_time=$(date +%s) + +script_version="2.0.0" + +scripts_path="${PROJECT_PATH}/dev-workspace/docker/scripts" +dev_workspace_path="${PROJECT_PATH}/dev-workspace" + +####################################### +# Get the plugin name from composer.json file. +# Globals: +# scripts_path +# PROJECT_PATH +# Returns: +# The plugin name. +####################################### +get_plugin_name() { + php "${scripts_path}/parse-json.php" "${PROJECT_PATH}/composer.json" name | awk -F/ '{print $NF}' +} +plugin_name=$(get_plugin_name) + +php_version="${1}" +command="${2}" +flat_php_version="${php_version//./}" +container_name="${plugin_name}-tests-${flat_php_version}" +wordpress_container_name="${container_name}_wordpress_1" +db_container_name="${container_name}_db_1" +codeception_envs_path="${PROJECT_PATH}/tests/codeception/_envs" +dir_in_test_container="/var/www/html" +cols=$(tput cols) + +####################################### +# Echo the string as an step in the output. +# Arguments: +# The message to display. +# Outputs: +# The passed string after an arrow. +####################################### +echo_step() { + echo "▶ ${1}" +} + +####################################### +# Start the docker services calling docker-compose +# for the compose file related to the selected +# PHP version. +# Globals: +# php_version +# container_name +# Outputs: +# Docker-compose output +####################################### +start_services() { + docker-compose -f $PROJECT_PATH/tests/docker/docker-compose-tests-$php_version.yml -p "${container_name}" up -d +} + +####################################### +# Stop the docker services calling docker-compose +# for the compose file related to the selected +# PHP version. +# Globals: +# php_version +# container_name +# Outputs: +# Docker-compose output +####################################### +stop_services() { + docker-compose -f "${PROJECT_PATH}/tests/docker/docker-compose-tests-${php_version}.yml" -p "${container_name}" down +} + +####################################### +# Get the service IP address. +# Globals: +# container_name +# Outputs: +# The IP address +####################################### +get_service_ip() { + container_name="${1}" + + docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "${container_name}" +} + +####################################### +# Get the service port. +# Arguments: +# container_name +# port +# Outputs: +# The port number +####################################### +get_service_port() { + container_name="${1}" + port="${2}" + + docker inspect -f "{{(index (index .NetworkSettings.Ports \"${port}/tcp\") 0).HostPort}}" "${container_name}" +} + +####################################### +# Show the IP addresses for all the services. +# Outputs: +# The IP address +####################################### +get_ip_addresses() { + wordpress_container_ip=$(get_service_ip "${wordpress_container_name}") + db_container_ip=$(get_service_ip "${db_container_name}") + + port_80=$(get_service_port "${wordpress_container_name}" 80) + port_443=$(get_service_port "${wordpress_container_name}" 443) + port_3306=$(get_service_port "${db_container_name}" 3306) + + output=$( + cat < "$file_path" +} + +####################################### +# Create the ray config file +####################################### + +create_ray_config() { + wordpress_container_ip=$(get_service_ip "${wordpress_container_name}") + mount_path=$(get_mount_path) + + config_content=$( + cat < true, + + /* + * The host used to communicate with the Ray app. + */ + 'host' => '${wordpress_container_ip}', + + /* + * The port number used to communicate with the Ray app. + */ + 'port' => 23517, + + /* + * Absolute base path for your sites or projects in Homestead, Vagrant, Docker, or another remote development server. + */ + 'remote_path' => '/var/www/html/', + + /* + * Absolute base path for your sites or projects on your local computer where your IDE or code editor is running on. + */ + 'local_path' => '${mount_path}', + + /* + * When this setting is enabled, the package will not try to format values sent to Ray. + */ + 'always_send_raw_values' => false, +]; + +EOF + ) + + echo "${config_content}" >"$mount_path"/ray.php +} + +####################################### +# Delete all the volumes containing the +# WordPress installation for tests. +# Globals: +# PROJECT_PATH +####################################### +clean_volumes() { + rm -rf "${PROJECT_PATH}/tests/docker/volumes/php*" +} + +####################################### +# Delete all the env files. +# Globals: +# codeception_envs_path +####################################### +clean_envs() { + rm -f "${codeception_envs_path}/php*" +} + +####################################### +# Add the current user to the www-data group, +# so it can read and write docker volume files. +####################################### +add_user_group() { + sudo usermod -a -G www-data "$(whoami)" +} + +####################################### +# Bootstrap the plugin into the container +# for being installed in the WordPress +# and tested. +####################################### +run_bootstrap() { + mount_path=$(get_mount_path) + $dev_workspace_path/docker/scripts/tests-bootstrap "${mount_path}" +} + +####################################### +# Run the builder command without showing +# the header. +# Outputs: The output of the builder command. +####################################### +run_builder() { + HIDE_HEADER=1 yarn run build:dir +} + +####################################### +# Show a list of available envs for different +# PHP versions for testing. +# Outputs: +# A list of codeception envs +####################################### +get_php_versions() { + find $PROJECT_PATH/tests/docker/ -type f -name 'docker-compose-tests-php*\.yml' | sed 's/tests\/docker\/docker-compose-tests-//g' | sed 's/\.yml//g' | sed 's/\/\//\//g' +} + +####################################### +# Start ChromeDriver +####################################### + +start_chromedriver() { + # Local chromedriver + # chromedriver --url-base=/wd/hub & + + # Docker based chromedriver + # Check: https://github.com/SeleniumHQ/docker-selenium + docker run -d -p 4444:4444 --shm-size="2g" selenium/standalone-chrome:4.8.3-20230404 +} + +####################################### +# Stop ChromeDriver +####################################### +stop_chromedriver() { + # Only needed for local chromedriver + # ps aux | pgrep chromedriver | awk ' { print $2 } ' | xargs kill -9 + echo 'ok' +} + +####################################### +# Show the elapsed time since the script started. +# Globals: +# start_time +# Outputs: +# The runtime in seconds. +####################################### +show_runtime() { + end_time=$(date +%s) + runtime=$((end_time - start_time)) + echo "" + echo "Runtime: $runtime sec" +} + +####################################### +# Show the elapsed time since the script started. +# Globals: +# start_time +# Outputs: +# The runtime in seconds. +####################################### +show_elapsed_time() { + end_time=$(date +%s) + runtime=$((end_time - start_time)) + echo "" + echo "Elapsed time: $runtime sec" +} + +####################################### +# Repeats a string "n" times. +# Arguments: +# The string to be repeated. +# The number of times to repeat. +# Outputs: +# The repeated string. +####################################### +repeat() { + for ((c = 1; c <= "${2}"; c++)); do + echo -n "${1}" + done +} + +####################################### +# Show the header for the script, showing +# a few details of the plugin. +# Globals: +# script_version +# plugin_name +# php_version +# Outputs: +# The formatted header. +####################################### +echo_header() { + repeat "=" "$cols" + line=$(repeat "-" "$cols"-16) + echo " __" + echo " -=(o '. PUBLISHPRESS TESTS ASSISTANT - v${script_version}" + echo " '.-.\ ${line}" + echo " /| \\ Name: ${plugin_name}" + echo " '| || " + echo " _\_):,_ PHP Version: ${php_version}" + echo "" + repeat "=" "$cols" + echo "" +} + +####################################### +echo_header +case "${command}" in +"setup") + add_user_group + ;; +"start") + echo "Start services:" + echo "" + echo_step "Starting the docker services" + echo "" + start_services + echo "" + + echo_step "Fixing volume permissions" + fix_volume_permissions + + echo_step "Creating Ray config file" + create_ray_config + + echo_step "Bootstrapping" + run_bootstrap + + echo_step "Creating the codeception env file" + create_env_file + + echo_step "IP and Ports" + echo "" + get_ip_addresses + echo "" + + echo_step "Starting ChromeDriver in the background" + echo "" + start_chromedriver + + echo "" + echo "Start process finished!" + show_runtime + ;; +"bootstrap") + echo "Bootstrapping the plugin for testing:" + echo "" + run_bootstrap + + echo "" + echo "Plugin bootstrapped successfully!" + show_runtime + ;; +"stop") + echo "Stop services:" + echo "" + + echo_step "Stopping docker services" + echo "" + stop_services + echo "" + + echo_step "Stopping ChromeDriver" + echo "" + stop_chromedriver + echo "" + + echo "" + echo "Stop process finished!" + show_runtime + ;; +"ip") + get_ip_addresses + ;; +"php-versions") + get_php_versions + ;; +"path") + mount_path=$(get_mount_path) + echo "WordPress path: ${mount_path}" + ;; +"clean") + echo "Cleaning:" + echo "" + + echo_step "Cleaning the volumes" + clean_volumes + + echo_step "Cleaning the codeception env files" + + echo "" + echo "Files cleaned successfully!" + clean_envs + ;; +"brun") + # Arguments passed to this command, after the third one, will all be passed to + # codeception run command + + echo_step "IP and Ports" + echo "" + get_ip_addresses + echo "" + + run_builder + echo "" + + echo_step "Bootstrapping the plugin" + run_bootstrap + + echo "" + show_elapsed_time + echo "" + + echo_step "Cleaning up codeception output" + "$PROJECT_PATH"/vendor/bin/codecept clean + + echo_step "Running codeception tests: ${*:3}, env: ${php_version}" + + echo "" + "$PROJECT_PATH"/vendor/bin/codecept run "${*:3}" --env "${php_version}" + + echo "" + echo "Finish running tests!" + show_runtime + ;; +"run") + echo_step "IP and Ports" + echo "" + get_ip_addresses + echo "" + + echo_step "Cleaning up codeception output" + "$PROJECT_PATH"/vendor/bin/codecept clean + + # Arguments passed to this command, after the third one, will all be passed to + # codeception run command + echo_step "Running codeception tests: ${*:3}, env: ${php_version}" + + echo "" + "$PROJECT_PATH"/vendor/bin/codecept run "${*:3}" --env "${php_version}" + + echo "" + echo "Finish running tests!" + show_runtime + ;; +*) echo "invalid option ${command}" ;; +esac diff --git a/dev-workspace/docker/scripts/prompt-tests-php-version.js b/dev-workspace/docker/scripts/prompt-tests-php-version.js new file mode 100755 index 00000000..c121d647 --- /dev/null +++ b/dev-workspace/docker/scripts/prompt-tests-php-version.js @@ -0,0 +1,18 @@ +#!/usr/bin/env node --experimental-modules + +/* + * Copyright (c) 2022. PublishPress, All rights reserved. + */ + +import { promptUser, executeCommand } from './modules/prompt-user.mjs'; + +const additionalArgs = process.argv.slice(2); + +promptUser() + .then((answers) => { + const command = additionalArgs.join(' '); + executeCommand(command, answers.version); + }) + .catch((error) => { + console.error(error); + }); diff --git a/dev-workspace/docker/scripts/tests-bootstrap b/dev-workspace/docker/scripts/tests-bootstrap new file mode 100755 index 00000000..1380e292 --- /dev/null +++ b/dev-workspace/docker/scripts/tests-bootstrap @@ -0,0 +1,49 @@ +#!/usr/bin/env php + $destination) { + $destination = str_replace('%WP_ROOT_FOLDER%', $wpRootPath, $destination); + $sourcePath = "$basePath/$source"; + + // Using rsync because it is faster + if (file_exists($sourcePath)) { + if (is_dir($sourcePath)) { + echo 'Copying dir ' . $source . "\n"; + + shell_exec("[ -e $destination ] && chmod -R 777 $destination && rm -rf $destination"); + shell_exec("mkdir -p $destination"); + shell_exec("rsync -r $sourcePath/* $destination"); + shell_exec("[ -e $destination ] && chmod -R 777 $destination"); + } else { + echo 'Copying file ' . $source . "\n"; + + shell_exec("[ -e $destination ] && chmod -R 666 $destination && rm -rf $destination"); + shell_exec("rsync -r $sourcePath $destination"); + shell_exec("[ -e $destination ] && chmod -R 666 $destination"); + } + } else { + throw new Exception('Source path not found: ' . $source); + } + } + + echo "\n"; +} diff --git a/dev-workspace/run b/dev-workspace/run new file mode 100755 index 00000000..6bbf55e3 --- /dev/null +++ b/dev-workspace/run @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +# Create empty cache files if not exists. +[[ -d cache/.npm/_cacache ]] || mkdir -p cache/.npm/_cacache +[[ -d cache/.npm/_logs ]] || mkdir -p cache/.npm/_logs +[[ -d cache/.composer/cache ]] || mkdir -p cache/.composer/cache +[[ -d cache/.oh-my-zsh/log ]] || mkdir -p cache/.oh-my-zsh/log +[[ -f cache/.zsh_history ]] || touch cache/.zsh_history +[[ -f cache/.bash_history ]] || touch cache/.bash_history +[[ -f cache/.composer/auth.json ]] || echo '{}' > cache/.composer/auth.json + +DOCKER_HOST_IP=$(./docker/scripts/host-ip) + +# Run the terminal service. +DOCKER_HOST_IP=$DOCKER_HOST_IP docker compose -f docker/compose.yaml run --rm terminal "$@" diff --git a/press-permit-core.php b/press-permit-core.php index ce535066..c14fe8dc 100644 --- a/press-permit-core.php +++ b/press-permit-core.php @@ -5,7 +5,7 @@ * Description: Advanced yet accessible content permissions. Give users or groups type-specific roles. Enable or block access for specific posts or terms. * Author: PublishPress * Author URI: https://publishpress.com/ - * Version: 3.9.1 + * Version: 3.9.3 * Text Domain: press-permit-core * Domain Path: /languages/ * Requires at least: 5.5 @@ -194,7 +194,7 @@ function presspermit_load() { return; } - define('PRESSPERMIT_VERSION', '3.9.1'); + define('PRESSPERMIT_VERSION', '3.9.3'); if (!defined('PRESSPERMIT_READ_PUBLIC_CAP')) { define('PRESSPERMIT_READ_PUBLIC_CAP', 'read'); diff --git a/readme.txt b/readme.txt index 0f9bc3dd..008f7386 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Tags: restrict, access, permissions, cms, user, private, category, pages, privac Requires at least: 5.5 Tested up to: 6.2 Requires PHP: 7.2.5 -Stable tag: 3.9.1 +Stable tag: 3.9.3 License: GPLv3 License URI: https://www.gnu.org/licenses/gpl-3.0.html @@ -240,6 +240,13 @@ Yes, we use the phrase "publishpress-ppcore-install" to share install links. You == Changelog == += 3.9.3 - 11 May 2023 = +* Change : Adjustment to composer.json +* Change : Adjustment to .gitignore + += 3.9.2 - 10 May 2023 = +* Fixed : Remove .git nested folders from some vendor libraries, using build script + = 3.9.1 - 9 May 2023 = * Fixed : Fatal error in Composer installs due to missing vendor libraries * Compat : PublishPress Planner - Status Change notifications were not sent