Page MenuHomePhorge

No OneTemporary

diff --git a/.arcconfig b/.arcconfig
new file mode 100644
index 0000000..60eb53d
--- /dev/null
+++ b/.arcconfig
@@ -0,0 +1,9 @@
+{
+ "phabricator.uri": "https://we.phorge.it/",
+ "load": [
+ "src/"
+ ],
+ "history.immutable": true,
+ "arc.land.onto": ["main"],
+ "arc.land.strategy": "squash"
+}
diff --git a/.arclint b/.arclint
new file mode 100644
index 0000000..bcfb403
--- /dev/null
+++ b/.arclint
@@ -0,0 +1,69 @@
+{
+ "exclude": [
+ "(^externals/)"
+ ],
+ "linters": {
+ "chmod": {
+ "type": "chmod"
+ },
+ "filename": {
+ "type": "filename"
+ },
+ "generated": {
+ "type": "generated"
+ },
+ "json": {
+ "type": "json",
+ "include": [
+ "(^resources/arclint/.*\\.arclint\\.example$)",
+ "(^\\.arcconfig$)",
+ "(^\\.arclint$)",
+ "(\\.json$)"
+ ]
+ },
+ "merge-conflict": {
+ "type": "merge-conflict"
+ },
+ "nolint": {
+ "type": "nolint"
+ },
+ "phutil-library": {
+ "type": "phutil-library",
+ "include": "(\\.php$)"
+ },
+ "spelling": {
+ "type": "spelling",
+ "exclude": "(^resources/spelling/.*\\.json$)"
+ },
+ "text": {
+ "type": "text",
+ "exclude": [
+ "(^src/(.*/)?__tests__/[^/]+/.*\\.(txt|json|expect)|/Makefile\\z)"
+ ]
+ },
+ "text-without-length": {
+ "type": "text",
+ "include": [
+ "(^src/(.*/)?__tests__/[^/]+/.*\\.(txt|json|expect))"
+ ],
+ "severity": {
+ "3": "disabled"
+ }
+ },
+ "text-without-tabs": {
+ "type": "text",
+ "include": [
+ "(/Makefile\\z)"
+ ],
+ "severity": {
+ "2": "disabled"
+ }
+ },
+ "xhpast": {
+ "type": "xhpast",
+ "include": "(\\.php$)",
+ "standard": "phutil.xhpast",
+ "xhpast.php-version": "5.5.0"
+ }
+ }
+}
diff --git a/.devcontainer/.env.sample b/.devcontainer/.env.sample
new file mode 100644
index 0000000..b62da80
--- /dev/null
+++ b/.devcontainer/.env.sample
@@ -0,0 +1,12 @@
+#.env sample file for the phorge-devcontainer
+
+# The HTTP Port that Phorge will run on
+PHORGE_WEB_PORT=80
+
+# The SSH Port that Phorge Repos will run on
+PHORGE_SSH_PORT=22280
+
+# The base URI that you will map on your local machine to 127.0.0.1
+# NOTE: If you use a PHORGE_WEB_PORT other than port 80, you will need to update this URI to include the port
+# For example, if PHORGE_WEB_PORT=8020 then set PHORGE_BASE_URI=http://phorge.localhost:8020
+PHORGE_BASE_URI=http://phorge.localhost
diff --git a/.devcontainer/.gitignore b/.devcontainer/.gitignore
new file mode 100644
index 0000000..4c49bd7
--- /dev/null
+++ b/.devcontainer/.gitignore
@@ -0,0 +1 @@
+.env
diff --git a/.devcontainer/.vscode/launch.json b/.devcontainer/.vscode/launch.json
new file mode 100644
index 0000000..8166a78
--- /dev/null
+++ b/.devcontainer/.vscode/launch.json
@@ -0,0 +1,14 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Listen for Xdebug",
+ "type": "php",
+ "request": "launch",
+ "port": 9003
+ },
+ ]
+}
diff --git a/.devcontainer/application/Dockerfile b/.devcontainer/application/Dockerfile
new file mode 100644
index 0000000..f9744d1
--- /dev/null
+++ b/.devcontainer/application/Dockerfile
@@ -0,0 +1,65 @@
+FROM debian:bookworm-backports
+
+
+# == Get ca-certificates up to date ==
+RUN apt-get -y update
+RUN apt-get -y install ca-certificates
+
+
+# == Copy Data ==
+COPY install_scripts /install_scripts
+
+# == Configure Ubuntu ==
+WORKDIR /install_scripts
+RUN sh install_dependencies.sh
+RUN sh add_users.sh
+
+# == Set up the Phorge code base ==
+RUN mkdir /srv/phorge
+RUN chown git:wwwgrp-phorge /srv/phorge
+USER git
+WORKDIR /srv/phorge
+RUN git clone https://we.phorge.it/source/phorge.git
+RUN git clone https://we.phorge.it/source/arcanist.git
+USER root
+WORKDIR /
+RUN mkdir -p /var/tmp/phd/log
+RUN chown phorge-daemon:2000 /var/tmp/phd/log
+
+# == Expose Ports ==
+
+# Nginx
+EXPOSE 80
+# Aphlict
+EXPOSE 22280
+# SSH
+EXPOSE 2222
+
+# == Add service config files ==
+ADD /config/nginx.conf.org /etc/nginx/
+ADD /config/fastcgi.conf /etc/nginx/
+ADD /config/php-fpm.conf /etc/php/8.2/fpm/
+ADD /config/php.ini /etc/php/8.2/fpm/
+ADD /config/php.ini /etc/php/8.2/cli/
+ADD /config/aphlict.phorge.json /install_scripts/
+
+# == Add Supervisord config files ==
+RUN mkdir -p /var/log/supervisor
+RUN mkdir -p /etc/supervisor/conf.d/
+
+ADD config/supervisord.conf /etc/supervisor/
+COPY config/*.sv.conf /etc/supervisor/conf.d/
+
+# == Configure Phorge SSH service ==
+RUN mkdir /etc/phorge-ssh
+RUN mkdir /var/run/sshd/
+RUN chmod 0755 /var/run/sshd
+ADD config/sshd_config.phorge /etc/phorge-ssh/
+ADD config/phorge-ssh-hook.sh /etc/phorge-ssh/
+RUN chown root:root /etc/phorge-ssh/*
+
+# == Copy other scripts == #
+COPY user-config /user-config
+COPY startup.sh /
+
+CMD bash ./startup.sh && supervisord
diff --git a/.devcontainer/application/config/aphlict.phorge.json b/.devcontainer/application/config/aphlict.phorge.json
new file mode 100644
index 0000000..24bfe08
--- /dev/null
+++ b/.devcontainer/application/config/aphlict.phorge.json
@@ -0,0 +1,13 @@
+[{
+ "type": "client",
+ "host": "phorge.localhost",
+ "port": 22280,
+ "protocol": "http"
+ },
+ {
+ "type": "admin",
+ "host": "127.0.0.1",
+ "port": 22281,
+ "protocol": "http"
+ }
+]
diff --git a/.devcontainer/application/config/aphlict.sv.conf b/.devcontainer/application/config/aphlict.sv.conf
new file mode 100644
index 0000000..a3005dc
--- /dev/null
+++ b/.devcontainer/application/config/aphlict.sv.conf
@@ -0,0 +1,3 @@
+[program:aphlict]
+command=/srv/phorge/phorge/bin/aphlict debug --config /srv/phorge/phorge/conf/aphlict/aphlict.default.json
+user=phorge-daemon
diff --git a/.devcontainer/application/config/fastcgi.conf b/.devcontainer/application/config/fastcgi.conf
new file mode 100644
index 0000000..4419b42
--- /dev/null
+++ b/.devcontainer/application/config/fastcgi.conf
@@ -0,0 +1,24 @@
+ fastcgi_param QUERY_STRING $query_string;
+ fastcgi_param REQUEST_METHOD $request_method;
+ fastcgi_param CONTENT_TYPE $content_type;
+ fastcgi_param CONTENT_LENGTH $content_length;
+
+ fastcgi_param SCRIPT_NAME $fastcgi_script_name;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ fastcgi_param REQUEST_URI $request_uri;
+ fastcgi_param DOCUMENT_URI $document_uri;
+ fastcgi_param DOCUMENT_ROOT $document_root;
+ fastcgi_param SERVER_PROTOCOL $server_protocol;
+
+ fastcgi_param GATEWAY_INTERFACE CGI/1.1;
+ fastcgi_param SERVER_SOFTWARE nginx;
+
+ fastcgi_param REMOTE_ADDR $remote_addr;
+ fastcgi_param REMOTE_PORT $remote_port;
+ fastcgi_param SERVER_ADDR $server_addr;
+ fastcgi_param SERVER_PORT $server_port;
+ fastcgi_param SERVER_NAME $server_name;
+
+ fastcgi_param HTTPS $https;
+
+ fastcgi_read_timeout 6000;
diff --git a/.devcontainer/application/config/nginx.conf.org b/.devcontainer/application/config/nginx.conf.org
new file mode 100644
index 0000000..bd81238
--- /dev/null
+++ b/.devcontainer/application/config/nginx.conf.org
@@ -0,0 +1,44 @@
+worker_processes 1;
+daemon off;
+pid /run/nginx.pid;
+
+events {
+ worker_connections 1024;
+ use epoll;
+}
+
+http {
+ include mime.types;
+ default_type application/octet-stream;
+ sendfile on;
+ keepalive_timeout 65;
+ gzip on;
+ client_max_body_size 200M;
+ client_body_buffer_size 200M;
+
+ server {
+ listen *:80;
+
+ access_log /var/log/nginx/access.log;
+ error_log /var/log/nginx/access.log;
+
+ root /srv/phorge/phorge/webroot;
+ try_files $uri $uri/ /index.php;
+
+ location / {
+ index index.php;
+
+ if ( !-f $request_filename )
+ {
+ rewrite ^/(.*)$ /index.php?__path__=/$1 last;
+ break;
+ }
+ }
+
+ location /index.php {
+ include /etc/nginx/fastcgi.conf;
+ fastcgi_param PATH "/usr/local/bin:/usr/bin:/sbin:/usr/sbin:/bin:/usr/games";
+ fastcgi_pass unix:/tmp/php-fpm-phorge.sock;
+ }
+ }
+}
diff --git a/.devcontainer/application/config/nginx.sv.conf b/.devcontainer/application/config/nginx.sv.conf
new file mode 100644
index 0000000..dfa1572
--- /dev/null
+++ b/.devcontainer/application/config/nginx.sv.conf
@@ -0,0 +1,2 @@
+[program:nginx]
+command=nginx
diff --git a/.devcontainer/application/config/phorge-phd.sv.conf b/.devcontainer/application/config/phorge-phd.sv.conf
new file mode 100644
index 0000000..836784e
--- /dev/null
+++ b/.devcontainer/application/config/phorge-phd.sv.conf
@@ -0,0 +1,32 @@
+[program:PhabricatorRepositoryPullLocalDaemon]
+user=phorge-daemon
+command=/srv/phorge/phorge/bin/phd debug PhabricatorRepositoryPullLocalDaemon
+stdout_logfile=/var/log/supervisor/PhabricatorRepositoryPullLocalDaemon.log
+stderr_logfile=/var/log/supervisor/PhabricatorRepositoryPullLocalDaemon_err.log
+
+[program:PhabricatorTaskmasterDaemon1]
+user=phorge-daemon
+command=/srv/phorge/phorge/bin/phd debug PhabricatorTaskmasterDaemon
+stdout_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon1.log
+stderr_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon1_err.log
+
+[program:PhabricatorTaskmasterDaemon2]
+user=phorge-daemon
+command=/srv/phorge/phorge/bin/phd debug PhabricatorTaskmasterDaemon
+stdout_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon2.log
+stderr_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon2_err.log
+
+[program:PhabricatorTaskmasterDaemon3]
+user=phorge-daemon
+command=/srv/phorge/phorge/bin/phd debug PhabricatorTaskmasterDaemon
+stdout_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon3.log
+stderr_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon3_err.log
+
+[program:PhabricatorTaskmasterDaemon4]
+user=phorge-daemon
+command=/srv/phorge/phorge/bin/phd debug PhabricatorTaskmasterDaemon
+stdout_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon4.log
+stderr_logfile=/var/log/supervisor/PhabricatorTaskmasterDaemon4_err.log
+
+[group:phd]
+programs=PhabricatorRepositoryPullLocalDaemon,PhabricatorTaskmasterDaemon1,PhabricatorTaskmasterDaemon2,PhabricatorTaskmasterDaemon3,PhabricatorTaskmasterDaemon4
diff --git a/.devcontainer/application/config/phorge-ssh-hook.sh b/.devcontainer/application/config/phorge-ssh-hook.sh
new file mode 100644
index 0000000..4008bdf
--- /dev/null
+++ b/.devcontainer/application/config/phorge-ssh-hook.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+# NOTE: Replace this with the username that you expect users to connect with.
+VCSUSER="git"
+
+ROOT="/srv/phorge/phorge"
+
+if [ "$1" != "$VCSUSER" ];
+then
+ exit 1
+fi
+
+exec "$ROOT/bin/ssh-auth" $@
diff --git a/.devcontainer/application/config/phorge-sshd.sv.conf b/.devcontainer/application/config/phorge-sshd.sv.conf
new file mode 100644
index 0000000..c7f5a8c
--- /dev/null
+++ b/.devcontainer/application/config/phorge-sshd.sv.conf
@@ -0,0 +1,2 @@
+[program:phorge-sshd]
+command=/usr/sbin/sshd -D -f /etc/phorge-ssh/sshd_config.phorge
diff --git a/.devcontainer/application/config/php-fpm.conf b/.devcontainer/application/config/php-fpm.conf
new file mode 100644
index 0000000..c202891
--- /dev/null
+++ b/.devcontainer/application/config/php-fpm.conf
@@ -0,0 +1,19 @@
+[global]
+pid = /run/php-fpm.pid
+error_log = /tmp/phorge.log
+daemonize = no
+
+[phorge]
+user = git
+group = wwwgrp-phorge
+listen = /tmp/php-fpm-phorge.sock
+listen.owner = git
+listen.group = wwwgrp-phorge
+listen.mode = 0666
+pm = dynamic
+pm.max_children = 4
+pm.start_servers = 2
+pm.min_spare_servers = 1
+pm.max_spare_servers = 4
+catch_workers_output = yes
+php_admin_value[error_log] = /tmp/phorge.php.log
diff --git a/.devcontainer/application/config/php.ini b/.devcontainer/application/config/php.ini
new file mode 100644
index 0000000..340dfa7
--- /dev/null
+++ b/.devcontainer/application/config/php.ini
@@ -0,0 +1,190 @@
+[PHP]
+engine = On
+short_open_tag = Off
+asp_tags = Off
+precision = 14
+y2k_compliance = On
+output_buffering = 4096
+zlib.output_compression = Off
+unserialize_callback_func =
+serialize_precision = 17
+allow_call_time_pass_reference = Off
+safe_mode = Off
+safe_mode_gid = Off
+safe_mode_include_dir =
+safe_mode_exec_dir =
+safe_mode_allowed_env_vars = PHP_
+safe_mode_protected_env_vars = LD_LIBRARY_PATH
+disable_functions =
+disable_classes =
+zend.enable_gc = On
+expose_php = On
+max_input_time = 60
+memory_limit = 4G
+error_reporting = E_ALL & ~E_DEPRECATED
+display_errors = On
+display_startup_errors = Off
+log_errors = On
+log_errors_max_len = 1024
+ignore_repeated_errors = Off
+ignore_repeated_source = Off
+report_memleaks = On
+track_errors = Off
+error_log = /tmp/php_errors.log
+variables_order = "GPCS"
+request_order = "GP"
+register_globals = Off
+register_long_arrays = Off
+auto_globals_jit = On
+post_max_size = 4G
+magic_quotes_gpc = Off
+magic_quotes_runtime = Off
+magic_quotes_sybase = Off
+auto_prepend_file =
+auto_append_file =
+default_mimetype = "text/html"
+include_path = ".:/usr/share/php7:/usr/share/php7/PEAR:/srv/phorge/PHPExcel/Classes"
+doc_root =
+user_dir =
+enable_dl = Off
+file_uploads = On
+upload_max_filesize = 4G
+max_file_uploads = 20
+allow_url_fopen = On
+allow_url_include = Off
+default_socket_timeout = 60
+opcache.validate_timestamps = On
+opcache.revalidate_freq = 0
+xdebug.mode=debug
+xdebug.start_with_request=true
+[Date]
+date.timezone = 'UTC'
+[filter]
+[iconv]
+[intl]
+[sqlite]
+[sqlite3]
+[Pcre]
+[Pdo]
+[Pdo_mysql]
+pdo_mysql.cache_size = 2000
+pdo_mysql.default_socket=
+[Phar]
+[Syslog]
+define_syslog_variables = Off
+[mail function]
+SMTP = localhost
+smtp_port = 25
+mail.add_x_header = On
+[SQL]
+sql.safe_mode = Off
+[ODBC]
+odbc.allow_persistent = On
+odbc.check_persistent = On
+odbc.max_persistent = -1
+odbc.max_links = -1
+odbc.defaultlrl = 4096
+odbc.defaultbinmode = 1
+[Interbase]
+ibase.allow_persistent = 1
+ibase.max_persistent = -1
+ibase.max_links = -1
+ibase.timestampformat = "%Y-%m-%d %H:%M:%S"
+ibase.dateformat = "%Y-%m-%d"
+ibase.timeformat = "%H:%M:%S"
+[MySQL]
+mysql.allow_local_infile = On
+mysql.allow_persistent = Off
+mysql.cache_size = 2000
+mysql.max_persistent = -1
+mysql.max_links = -1
+mysql.default_port =
+mysql.default_socket =
+mysql.default_host =
+mysql.default_user =
+mysql.default_password =
+mysql.connect_timeout = 3
+mysql.trace_mode = Off
+[MySQLi]
+mysqli.max_persistent = -1
+mysqli.allow_persistent = Off
+mysqli.max_links = -1
+mysqli.cache_size = 2000
+mysqli.default_port = 3306
+mysqli.default_socket =
+mysqli.default_host =
+mysqli.default_user =
+mysqli.default_pw =
+mysqli.reconnect = Off
+[mysqlnd]
+mysqlnd.collect_statistics = On
+mysqlnd.collect_memory_statistics = Off
+[OCI8]
+[PostgreSQL]
+pgsql.allow_persistent = On
+pgsql.auto_reset_persistent = Off
+pgsql.max_persistent = -1
+pgsql.max_links = -1
+pgsql.ignore_notice = 0
+pgsql.log_notice = 0
+[Sybase-CT]
+sybct.allow_persistent = On
+sybct.max_persistent = -1
+sybct.max_links = -1
+sybct.min_server_severity = 10
+sybct.min_client_severity = 10
+[bcmath]
+bcmath.scale = 0
+[browscap]
+[Session]
+session.save_handler = files
+session.save_path = "/var/lib/php5"
+session.use_cookies = 1
+session.use_only_cookies = 1
+session.name = PHPSESSID
+session.auto_start = 0
+session.cookie_lifetime = 0
+session.cookie_path = /
+session.cookie_domain =
+session.cookie_httponly =
+session.serialize_handler = php
+session.gc_probability = 1
+session.gc_divisor = 1000
+session.gc_maxlifetime = 1440
+session.bug_compat_42 = Off
+session.bug_compat_warn = Off
+session.referer_check =
+session.entropy_length = 32
+session.entropy_file = /dev/urandom
+session.cache_limiter = nocache
+session.cache_expire = 180
+session.use_trans_sid = 0
+session.hash_function = sha256
+session.hash_bits_per_character = 5
+url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry"
+[MSSQL]
+mssql.allow_persistent = On
+mssql.max_persistent = -1
+mssql.max_links = -1
+mssql.min_error_severity = 10
+mssql.min_message_severity = 10
+mssql.compatability_mode = Off
+mssql.secure_connection = Off
+[Assertion]
+[COM]
+[mbstring]
+[gd]
+[exif]
+[Tidy]
+tidy.clean_output = Off
+[soap]
+soap.wsdl_cache_enabled=1
+soap.wsdl_cache_dir="/tmp"
+soap.wsdl_cache_ttl=86400
+soap.wsdl_cache_limit = 5
+[sysvshm]
+[ldap]
+ldap.max_links = -1
+[mcrypt]
+[dba]
+[xsl]
diff --git a/.devcontainer/application/config/php8-fpm.sv.conf b/.devcontainer/application/config/php8-fpm.sv.conf
new file mode 100644
index 0000000..c46a972
--- /dev/null
+++ b/.devcontainer/application/config/php8-fpm.sv.conf
@@ -0,0 +1,2 @@
+[program:php-fpm8.2]
+command=php-fpm8.2 -F
diff --git a/.devcontainer/application/config/sshd_config.phorge b/.devcontainer/application/config/sshd_config.phorge
new file mode 100644
index 0000000..6477458
--- /dev/null
+++ b/.devcontainer/application/config/sshd_config.phorge
@@ -0,0 +1,23 @@
+# NOTE: You must have OpenSSHD 6.2 or newer; support for AuthorizedKeysCommand
+# was added in this version.
+
+# NOTE: Edit these to the correct values for your setup.
+
+AuthorizedKeysCommand /etc/phorge-ssh/phorge-ssh-hook.sh
+AuthorizedKeysCommandUser git
+AllowUsers git
+
+# You may need to tweak these options, but mostly they just turn off everything
+# dangerous.
+
+Port 2222
+Protocol 2
+PermitRootLogin no
+AllowAgentForwarding no
+AllowTcpForwarding no
+PrintMotd no
+PrintLastLog no
+PasswordAuthentication no
+AuthorizedKeysFile none
+
+PidFile /run/sshd-phorge.pid
diff --git a/.devcontainer/application/config/supervisord.conf b/.devcontainer/application/config/supervisord.conf
new file mode 100644
index 0000000..180e8ec
--- /dev/null
+++ b/.devcontainer/application/config/supervisord.conf
@@ -0,0 +1,29 @@
+; supervisor config file
+
+[unix_http_server]
+file=/var/run/supervisor.sock ; (the path to the socket file)
+chmod=0700 ; sockef file mode (default 0700)
+
+[supervisord]
+nodaemon=true
+logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
+pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
+childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP)
+
+; the below section must remain in the config file for RPC
+; (supervisorctl/web interface) to work, additional interfaces may be
+; added by defining them in separate rpcinterface: sections
+[rpcinterface:supervisor]
+supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
+
+[supervisorctl]
+serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket
+
+; The [include] section can just contain the "files" setting. This
+; setting can list multiple files (separated by whitespace or
+; newlines). It can also contain wildcards. The filenames are
+; interpreted as relative to this file. Included files *cannot*
+; include files themselves.
+
+[include]
+files = /etc/supervisor/conf.d/*.conf
diff --git a/.devcontainer/application/install_scripts/add_users.sh b/.devcontainer/application/install_scripts/add_users.sh
new file mode 100644
index 0000000..cb92425
--- /dev/null
+++ b/.devcontainer/application/install_scripts/add_users.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+# Add users
+echo "git:x:2000:2000:user for phorge ssh:/srv/phorge:/bin/bash" >> /etc/passwd
+echo "phorge-daemon:x:2001:2000:user for phorge daemons:/srv/phorge:/bin/bash" >> /etc/passwd
+echo "wwwgrp-phorge:!:2000:nginx" >> /etc/group
+
+usermod -p NP git
+
+# Add repo directory
+mkdir -p /var/repo/
+chown phorge-daemon:2000 /var/repo/
+mkdir -p /var/tmp/phd/pid
+chmod 0777 /var/tmp/phd/pid
+
+# Add git to sudoers
+echo "git ALL=(phorge-daemon) SETENV: NOPASSWD: /usr/bin/git-upload-pack, /usr/bin/git-receive-pack, /usr/bin/git, /usr/lib/git-core/git-http-backend" > /etc/sudoers.d/git
+
+echo 'export PATH="/srv/phorge/arcanist/bin:$PATH"' >> /root/.bashrc
+echo 'export PATH="/srv/phorge/phorge/bin:$PATH"' >> /root/.bashrc
diff --git a/.devcontainer/application/install_scripts/install_dependencies.sh b/.devcontainer/application/install_scripts/install_dependencies.sh
new file mode 100644
index 0000000..3808e39
--- /dev/null
+++ b/.devcontainer/application/install_scripts/install_dependencies.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+export DEBIAN_FRONTEND=noninteractive
+
+apt-get -qq update
+apt-get -y -qq install \
+ git \
+ nginx \
+ php \
+ php-fpm \
+ php-mysql \
+ php-gd \
+ php-curl \
+ php-apcu \
+ php-cli \
+ php-json \
+ php-mbstring \
+ php-zip \
+ php-xdebug \
+ ssh \
+ wget \
+ vim \
+ less \
+ zip \
+ cron \
+ lsof \
+ sudo \
+ supervisor \
+ python3-pygments \
+ mariadb-client \
+ gcc \
+ g++ \
+ nodejs \
+ npm
diff --git a/.devcontainer/application/setup.php b/.devcontainer/application/setup.php
new file mode 100644
index 0000000..09c4f61
--- /dev/null
+++ b/.devcontainer/application/setup.php
@@ -0,0 +1,68 @@
+#!/usr/bin/env php
+<?php
+
+require_once './scripts/__init_script__.php';
+
+$query = new PhabricatorAuthProviderConfigQuery();
+$config = $query
+ ->setViewer(PhabricatorUser::getOmnipotentUser())
+ ->withIDs(array(1))
+ ->executeOne();
+
+if ($config) {
+ echo phutil_console_wrap("User/Password Auth Provider already configured\n");
+ return;
+}
+
+echo phutil_console_wrap(
+ "Setting up dev environment with user admin/hunter2\n");
+
+$password1 = new PhutilOpaqueEnvelope('hunter2');
+
+$config = id(new PhabricatorAuthProviderConfig())
+ ->setIsEnabled(1)
+ ->setShouldAllowLogin(1)
+ ->setShouldAllowRegistration(true)
+ ->setShouldAllowLink(1)
+ ->setShouldAllowUnlink(true)
+ ->setProviderType('password')
+ ->setProviderDomain('self')
+ ->setProviderClass('PhabricatorPasswordAuthProvider')
+ ->save();
+
+$user = new PhabricatorUser();
+$user->setUsername('admin');
+$user->setRealName('admin');
+
+$email = id(new PhabricatorUserEmail())
+ ->setAddress('admin@example.com')
+ ->setIsVerified(1);
+
+$user->setIsApproved(1);
+
+id(new PhabricatorUserEditor())
+ ->setActor(PhabricatorUser::getOmnipotentUser())
+ ->createNewUser($user, $email);
+
+$xactions = array();
+$xactions[] = id(new PhabricatorUserTransaction())
+ ->setTransactionType(
+ PhabricatorUserEmpowerTransaction::TRANSACTIONTYPE)
+ ->setNewValue(true);
+
+$source = id(new PhabricatorUnknownContentSource());
+$actor = PhabricatorUser::getOmnipotentUser();
+$people_application_phid = id(new PhabricatorPeopleApplication())
+ ->getPHID();
+
+$editor = id(new PhabricatorUserTransactionEditor())
+ ->setActor($actor)
+ ->setContentSource($source)
+ ->setActingAsPHID($people_application_phid)
+ ->setContinueOnMissingFields(true);
+
+$editor->applyTransactions($user, $xactions);
+
+$pass = PhabricatorAuthPassword::initializeNewPassword($user, PhabricatorAuthPassword::PASSWORD_TYPE_ACCOUNT)
+ ->setPassword($password1, $user)
+ ->save();
diff --git a/.devcontainer/application/startup.sh b/.devcontainer/application/startup.sh
new file mode 100644
index 0000000..4e8d44f
--- /dev/null
+++ b/.devcontainer/application/startup.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+set -x
+
+echo "Waiting for mysql"
+until mysql -h"$SQL_HOST" -P"$SQL_PORT" -u"$SQL_USER" -p"$SQL_PASSWORD" &> /dev/null
+do
+ printf "."
+ sleep 1
+done
+
+echo -e "\nmysql ready"
+
+pushd /srv/phorge/phorge
+
+./bin/config set mysql.host $SQL_HOST
+./bin/config set mysql.port $SQL_PORT
+./bin/config set mysql.user $SQL_USER
+./bin/config set mysql.pass $SQL_PASSWORD
+
+./bin/config set phabricator.base-uri $BASE_URI
+
+./bin/config set phd.user phorge-daemon
+./bin/config set diffusion.ssh-user git
+./bin/config set diffusion.ssh-port 2222
+./bin/config set diffusion.allow-http-auth true
+
+./bin/config set phabricator.developer-mode true
+./bin/config set phabricator.show-prototypes true
+./bin/config set darkconsole.enabled true
+
+./bin/config set storage.mysql-engine.max-size 268435456
+./bin/config set pygments.enabled true
+
+./bin/config set environment.append-paths '["/usr/lib/git-core"]'
+
+./bin/config set notification.servers --stdin < /install_scripts/aphlict.phorge.json
+
+echo '["/srv/phorge/gantt/src"]' | ./bin/config set load-libraries --stdin
+
+popd
+
+pushd /srv/phorge/phorge/support/aphlict/server
+
+npm ci
+
+popd
+
+cp /etc/nginx/nginx.conf.org /etc/nginx/nginx.conf
+
+pushd /srv/phorge/phorge
+
+./bin/storage upgrade --force
+
+php setup.php
diff --git a/.devcontainer/application/user-config/.exists b/.devcontainer/application/user-config/.exists
new file mode 100644
index 0000000..e69de29
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 0000000..b2f30db
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,26 @@
+// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
+// https://github.com/microsoft/vscode-dev-containers/tree/v0.183.0/containers/docker-existing-docker-compose
+{
+ "name": "Deepclone Dev",
+ // Update the 'dockerComposeFile' list if you have more compose files or use different names.
+ // The .devcontainer/docker-compose.yml file contains any overrides you need/want to make.
+ "dockerComposeFile": [
+ "docker-compose.yml"
+ ],
+ // The 'service' property is the name of the service for the container that VS Code should
+ // use. Update this value and .devcontainer/docker-compose.yml to the real service name.
+ "service": "app",
+ // The optional 'workspaceFolder' property is the path VS Code should open by default when
+ // connected. This is typically a file mount in .devcontainer/docker-compose.yml
+ "workspaceFolder": "/srv/phorge",
+ // Add the IDs of extensions you want installed when the container is created.
+ "customizations": {
+ "vscode": {
+ "extensions": [
+ "bmewburn.vscode-intelephense-client",
+ "xdebug.php-debug",
+ "editorconfig.editorconfig"
+ ]
+ }
+ }
+}
diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml
new file mode 100644
index 0000000..424a75b
--- /dev/null
+++ b/.devcontainer/docker-compose.yml
@@ -0,0 +1,25 @@
+version: "3.9"
+services:
+ db:
+ image: mariadb
+ restart: always
+ volumes:
+ - ./mysql:/etc/mysql/conf.d:ro
+ environment:
+ MYSQL_ROOT_PASSWORD: phorge-dev
+ app:
+ build: ./application
+ ports:
+ - "${PHORGE_WEB_PORT:-80}:80"
+ - "${PHORGE_SSH_PORT:-22280}:22280"
+ environment:
+ SQL_HOST: db
+ SQL_PORT: 3306
+ SQL_USER: root
+ SQL_PASSWORD: phorge-dev
+ BASE_URI: "${PHORGE_BASE_URI:-http://phorge.localhost/}"
+ volumes:
+ - "./.vscode:/srv/phorge/.vscode"
+ - "..:/srv/phorge/gantt"
+ - "./application/startup.sh:/startup.sh"
+ - "./application/setup.php:/srv/phorge/phorge/setup.php"
diff --git a/.devcontainer/mysql/custom.cnf b/.devcontainer/mysql/custom.cnf
new file mode 100644
index 0000000..e716fac
--- /dev/null
+++ b/.devcontainer/mysql/custom.cnf
@@ -0,0 +1,5 @@
+[mysqld]
+sql_mode=STRICT_ALL_TABLES
+max_allowed_packet=33554432
+innodb_buffer_pool_size=1600M
+local_infile=0
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..ad4da41
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,8 @@
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+max_line_length = 80
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6b193c3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.phutil_module_cache
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d9a10c0
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,176 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/src/__phutil_library_init__.php b/src/__phutil_library_init__.php
new file mode 100644
index 0000000..f1d0ae2
--- /dev/null
+++ b/src/__phutil_library_init__.php
@@ -0,0 +1,3 @@
+<?php
+
+phutil_register_library('gantt', __FILE__);
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
new file mode 100644
index 0000000..3c65f16
--- /dev/null
+++ b/src/__phutil_library_map__.php
@@ -0,0 +1,18 @@
+<?php
+
+/**
+ * This file is automatically generated. Use 'arc liberate' to rebuild it.
+ *
+ * @generated
+ * @phutil-library-version 2
+ */
+phutil_register_library_map(array(
+ '__library_version__' => 2,
+ 'class' => array(
+ 'GanttApplication' => 'gantt/application/GanttApplication.php',
+ ),
+ 'function' => array(),
+ 'xmap' => array(
+ 'GanttApplication' => 'PhabricatorApplication',
+ ),
+));
diff --git a/src/gantt/application/GanttApplication.php b/src/gantt/application/GanttApplication.php
new file mode 100644
index 0000000..2d89c37
--- /dev/null
+++ b/src/gantt/application/GanttApplication.php
@@ -0,0 +1,7 @@
+<?php
+
+final class GanttApplication extends PhabricatorApplication {
+ public function getName() {
+ return pht('Gantt');
+ }
+}

File Metadata

Mime Type
text/x-diff
Expires
Jan 19 2025, 23:15 (6 w, 3 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1129784
Default Alt Text
(38 KB)

Event Timeline