mirror of
https://github.com/qgis/QGIS.git
synced 2025-06-27 00:02:51 -04:00
Compare commits
No commits in common. "pre_qt4_port" and "master" have entirely different histories.
pre_qt4_po
...
master
55
.ci/config.ctest
Normal file
55
.ci/config.ctest
Normal file
@ -0,0 +1,55 @@
|
||||
SET (CTEST_SOURCE_DIRECTORY $ENV{CTEST_SOURCE_DIR})
|
||||
SET (CTEST_BINARY_DIRECTORY $ENV{CTEST_BUILD_DIR})
|
||||
#SET (CTEST_SOURCE_DIRECTORY /usr/src/QGIS)
|
||||
#SET (CTEST_BINARY_DIRECTORY /usr/src/qgis-build)
|
||||
|
||||
SET (CTEST_CMAKE_COMMAND "cmake")
|
||||
SET (CTEST_BUILD_COMMAND $ENV{CTEST_BUILD_COMMAND})
|
||||
SET (CTEST_SITE "github.com")
|
||||
SET (CTEST_BUILD_NAME "$ENV{CTEST_BUILD_NAME}")
|
||||
SET (CTEST_BUILD_CONFIGURATION "Release")
|
||||
SET (CTEST_TEST_TIMEOUT 90) # 90 seconds
|
||||
IF(DEFINED ENV{CTEST_PARALLEL_LEVEL})
|
||||
SET(PARALLEL_LEVEL $ENV{CTEST_PARALLEL_LEVEL})
|
||||
ELSE(DEFINED ENV{CTEST_PARALLEL_LEVEL})
|
||||
SET(PARALLEL_LEVEL 2)
|
||||
ENDIF(DEFINED ENV{CTEST_PARALLEL_LEVEL})
|
||||
|
||||
SET (INITIAL_CACHE "
|
||||
BUILDNAME:STRING=${CTEST_BUILD_NAME}
|
||||
SITE:STRING=${CTEST_SITE}
|
||||
CTEST_USE_LAUNCHERS:BOOL=ON
|
||||
")
|
||||
|
||||
SET (CTEST_NOTES_FILES
|
||||
${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}
|
||||
${CTEST_BINARY_DIRECTORY}/CMakeCache.txt
|
||||
)
|
||||
|
||||
IF(NOT WIN32)
|
||||
STRING(ASCII 27 Esc)
|
||||
SET(ColorReset "${Esc}[m")
|
||||
SET(ColorBold "${Esc}[1m")
|
||||
SET(Red "${Esc}[31m")
|
||||
SET(Green "${Esc}[32m")
|
||||
SET(Yellow "${Esc}[33m")
|
||||
SET(Blue "${Esc}[34m")
|
||||
SET(Magenta "${Esc}[35m")
|
||||
SET(Cyan "${Esc}[36m")
|
||||
SET(White "${Esc}[37m")
|
||||
SET(BoldRed "${Esc}[1;31m")
|
||||
SET(BoldGreen "${Esc}[1;32m")
|
||||
SET(BoldYellow "${Esc}[1;33m")
|
||||
SET(BoldBlue "${Esc}[1;34m")
|
||||
SET(BoldMagenta "${Esc}[1;35m")
|
||||
SET(BoldCyan "${Esc}[1;36m")
|
||||
SET(BoldWhite "${Esc}[1;37m")
|
||||
ENDIF(NOT WIN32)
|
||||
|
||||
# Create link to test results
|
||||
# CDash on OTB requires the date to be set for the search to work (used to be UTC-6, seems to be UTC now)
|
||||
SET(ENV{TZ} "UTC")
|
||||
EXECUTE_PROCESS(COMMAND date +%Y-%m-%d OUTPUT_VARIABLE CDASH_DATE)
|
||||
SET(RESULT_LINK "http://cdash.orfeo-toolbox.org/index.php?project=QGIS&filtercount=1&showfilters=1&field1=buildname/string&compare1=63&value1=$ENV{CTEST_BUILD_NAME}&date=${CDASH_DATE}")
|
||||
EXECUTE_PROCESS(COMMAND curl --data-urlencode "url=${RESULT_LINK}" -s http://tinyurl.com/api-create.php
|
||||
OUTPUT_VARIABLE SHORTURL)
|
27
.ci/config_build.ctest
Normal file
27
.ci/config_build.ctest
Normal file
@ -0,0 +1,27 @@
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/config.ctest)
|
||||
|
||||
# Requires a track on the CDash server
|
||||
ctest_start(Experimental)
|
||||
|
||||
ctest_build (BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE BUILDRES NUMBER_WARNINGS NUMWARN NUMBER_ERRORS NUMERR)
|
||||
|
||||
|
||||
SET(IGNORE_BUILD_FAILURES $ENV{IGNORE_BUILD_FAILURES})
|
||||
IF(NOT IGNORE_BUILD_FAILURES)
|
||||
IF(NOT ${BUILDRES} EQUAL 0 OR NOT ${NUMERR} EQUAL 0)
|
||||
ctest_submit (RETRY_COUNT 3 RETRY_DELAY 30)
|
||||
MESSAGE("")
|
||||
MESSAGE(" ${Yellow}Test results submitted to:${ColorReset} ${SHORTURL}")
|
||||
MESSAGE("")
|
||||
MESSAGE( FATAL_ERROR " ${Red}Build failed. Not running tests.${ColorReset}" )
|
||||
MESSAGE("")
|
||||
ENDIF(NOT ${BUILDRES} EQUAL 0 OR NOT ${NUMERR} EQUAL 0)
|
||||
ENDIF(NOT IGNORE_BUILD_FAILURES)
|
||||
|
||||
IF(${BUILDRES} EQUAL 0 OR ${NUMERR} EQUAL 0)
|
||||
MESSAGE("")
|
||||
MESSAGE(" ${BoldGreen}Success${ColorReset}")
|
||||
MESSAGE(" ${Green}Build passed successfully.${ColorReset}")
|
||||
MESSAGE("")
|
||||
MESSAGE("")
|
||||
ENDIF(${BUILDRES} EQUAL 0 OR ${NUMERR} EQUAL 0)
|
26
.ci/config_test.ctest
Normal file
26
.ci/config_test.ctest
Normal file
@ -0,0 +1,26 @@
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/config.ctest)
|
||||
|
||||
# Requires a track on the CDash server
|
||||
ctest_start(Experimental)
|
||||
|
||||
ctest_test (BUILD "${CTEST_BINARY_DIRECTORY}" PARALLEL_LEVEL ${PARALLEL_LEVEL} RETURN_VALUE TESTRES)
|
||||
IF(NOT ${TESTRES} EQUAL 0)
|
||||
ctest_submit (RETRY_COUNT 3 RETRY_DELAY 30)
|
||||
MESSAGE("")
|
||||
MESSAGE(" ${Yellow}Test results submitted to:${ColorReset} ${SHORTURL}" )
|
||||
MESSAGE("")
|
||||
SET(LEVEL "")
|
||||
IF(NOT ${TESTRES} EQUAL 0)
|
||||
SET(TESTRES_MESSAGE " Tests failed.")
|
||||
SET(LEVEL FATAL_ERROR)
|
||||
ENDIF(NOT ${TESTRES} EQUAL 0)
|
||||
MESSAGE( ${LEVEL} " ${Red}${TESTRES_MESSAGE} ${ColorReset}" )
|
||||
ENDIF(NOT ${TESTRES} EQUAL 0)
|
||||
|
||||
IF(NOT ${TESTRES} EQUAL 0)
|
||||
MESSAGE("")
|
||||
MESSAGE(" ${BoldGreen}Success${ColorReset}")
|
||||
MESSAGE(" ${Green}All tests passed successfully.${ColorReset}")
|
||||
MESSAGE("")
|
||||
MESSAGE("")
|
||||
ENDIF(NOT ${TESTRES} EQUAL 0)
|
139
.ci/ctest2ci.py
Executable file
139
.ci/ctest2ci.py
Executable file
@ -0,0 +1,139 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
***************************************************************************
|
||||
ctest2ci.py
|
||||
---------------------
|
||||
Date : March 2017
|
||||
Copyright : (C) 2017 by Matthias Kuhn
|
||||
Email : matthias@opengis.ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************
|
||||
"""
|
||||
|
||||
__author__ = "Matthias Kuhn"
|
||||
__date__ = "March 2017"
|
||||
__copyright__ = "(C) 2017, Matthias Kuhn"
|
||||
|
||||
# This script parses output from ctest and injects
|
||||
#
|
||||
# - Colors for failing unit tests and test cases
|
||||
# - Group control sequences to hide uninteresting output by default
|
||||
|
||||
import re
|
||||
import string
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from termcolor import colored
|
||||
|
||||
fold_stack = list()
|
||||
printable = set(string.printable)
|
||||
|
||||
|
||||
def start_fold(tag):
|
||||
sys.stdout.write(f"::group::{tag}\n")
|
||||
fold_stack.append(tag)
|
||||
|
||||
|
||||
def end_fold():
|
||||
try:
|
||||
tag = fold_stack.pop()
|
||||
sys.stdout.write("::endgroup::\n")
|
||||
except IndexError:
|
||||
updated_line = colored("======================", "magenta")
|
||||
updated_line += colored(
|
||||
"ctest2ci error when processing the following line:", "magenta"
|
||||
)
|
||||
updated_line += colored("----------------------", "magenta")
|
||||
updated_line += colored(updated_line, "magenta")
|
||||
updated_line += colored("----------------------", "magenta")
|
||||
updated_line += colored(
|
||||
"Tried to end fold, but fold was never started.", "magenta"
|
||||
)
|
||||
updated_line += colored("======================", "magenta")
|
||||
|
||||
|
||||
test_count = 0
|
||||
|
||||
|
||||
def start_test_fold():
|
||||
global test_count
|
||||
sys.stdout.write("Running tests\n")
|
||||
start_fold(f"test.{test_count}")
|
||||
test_count += 1
|
||||
|
||||
|
||||
in_failing_test = False
|
||||
in_failure = False
|
||||
|
||||
p = subprocess.Popen(sys.argv[1:], stdout=subprocess.PIPE)
|
||||
|
||||
for line in p.stdout:
|
||||
updated_line = line.decode("utf-8")
|
||||
# remove non printable characters https://stackoverflow.com/a/8689826/1548052
|
||||
filter(lambda x: x in printable, updated_line)
|
||||
if re.match("Run dashboard with model Experimental", updated_line):
|
||||
start_fold("Run tests")
|
||||
updated_line = "{title}\n{line}".format(
|
||||
title=colored("Running tests...", "yellow", attrs=["bold"]),
|
||||
line=updated_line,
|
||||
)
|
||||
|
||||
elif re.match("Test project /home/runner/QGIS/QGIS/build", updated_line):
|
||||
end_fold() # tag=Run tests
|
||||
start_test_fold()
|
||||
|
||||
if re.search(r"\*\*\*Failed", updated_line) or re.search(
|
||||
r"\*\*\*Timeout", updated_line
|
||||
):
|
||||
end_fold()
|
||||
updated_line = colored(updated_line, "red")
|
||||
in_failing_test = True
|
||||
|
||||
if in_failing_test:
|
||||
if re.match(" Start", updated_line):
|
||||
start_test_fold()
|
||||
in_failing_test = False
|
||||
elif in_failure:
|
||||
if re.match("PASS", updated_line) or re.match("Ran", updated_line):
|
||||
in_failure = False
|
||||
else:
|
||||
updated_line = colored(updated_line, "yellow")
|
||||
elif re.search(r"\*\*\* Segmentation fault", updated_line):
|
||||
start_fold("segfault")
|
||||
updated_line = colored(updated_line, "magenta")
|
||||
elif re.match(" Test failed: Segmentation fault", updated_line):
|
||||
end_fold()
|
||||
|
||||
else:
|
||||
if re.match(r"(FAIL|ERROR)[:\!].*", updated_line):
|
||||
updated_line = colored(updated_line, "yellow")
|
||||
in_failure = True
|
||||
|
||||
if not in_failing_test and re.search(
|
||||
"[0-9]+% tests passed, [0-9]+ tests failed out of", updated_line
|
||||
):
|
||||
tests_failing = re.match(r".* ([0-9]+) tests failed", updated_line).group(1)
|
||||
# updated_line += '\n::set-output name=TESTS_FAILING::{}'.format(tests_failing)
|
||||
end_fold()
|
||||
|
||||
if re.search("100% tests passed", updated_line):
|
||||
updated_line = colored(updated_line, "green")
|
||||
|
||||
if re.match("Submit files", updated_line):
|
||||
start_fold("submit")
|
||||
elif re.search("Test results submitted to", updated_line):
|
||||
cdash_url = re.match(r".*(http.*)$", updated_line).group(1)
|
||||
# updated_line += '\n::set-output name=CDASH_URL::{}'.format(cdash_url)
|
||||
end_fold()
|
||||
|
||||
sys.stdout.write(updated_line)
|
||||
|
||||
exit(p.wait())
|
47
.ci/ogc/Dockerfile
Normal file
47
.ci/ogc/Dockerfile
Normal file
@ -0,0 +1,47 @@
|
||||
FROM ubuntu:latest
|
||||
RUN export DEBIAN_FRONTEND=noninteractive
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get upgrade -y \
|
||||
&& apt-get install -y \
|
||||
ccache \
|
||||
cmake \
|
||||
ninja-build \
|
||||
clang \
|
||||
flex \
|
||||
bison \
|
||||
libgeos-dev \
|
||||
libgdal-dev \
|
||||
libzip-dev \
|
||||
libprotobuf-dev \
|
||||
qtbase5-dev \
|
||||
libdraco-dev \
|
||||
libqt5svg5-dev \
|
||||
libqt5serialport5-dev \
|
||||
qttools5-dev \
|
||||
protobuf-compiler \
|
||||
qt5-qmake \
|
||||
qtbase5-dev-tools \
|
||||
qtchooser \
|
||||
qtpositioning5-dev \
|
||||
libqt5webkit5-dev \
|
||||
libqca-qt5-2-dev \
|
||||
libgsl-dev \
|
||||
libspatialindex-dev \
|
||||
qt5keychain-dev \
|
||||
libexiv2-dev \
|
||||
libfcgi-dev \
|
||||
libqt5scintilla2-dev \
|
||||
libqwt-qt5-dev \
|
||||
pyqt5-dev \
|
||||
python3-pyqt5 \
|
||||
python3-pyqt5.qsci \
|
||||
python3-all-dev \
|
||||
python3-dev \
|
||||
python3-sip-dev \
|
||||
pyqt5-dev-tools \
|
||||
spawn-fcgi
|
||||
|
||||
ADD qgis_mapserv.sh /root/qgis_mapserv.sh
|
||||
CMD ["sh", "/root/qgis_mapserv.sh"]
|
53
.ci/ogc/build.sh
Executable file
53
.ci/ogc/build.sh
Executable file
@ -0,0 +1,53 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
mkdir -p /usr/src/qgis/build
|
||||
cd /usr/src/qgis/build || exit 1
|
||||
|
||||
export CCACHE_TEMPDIR=/tmp
|
||||
# Github workflow cache max size is 2.0, but ccache data get compressed (roughly 1/5?)
|
||||
ccache -M 2.0G
|
||||
|
||||
# Temporarily uncomment to debug ccache issues
|
||||
# export CCACHE_LOGFILE=/tmp/cache.debug
|
||||
ccache -z
|
||||
|
||||
# To make ccache work properly with precompiled headers
|
||||
ccache --set-config sloppiness=pch_defines,time_macros,include_file_mtime,include_file_ctime
|
||||
|
||||
cmake -GNinja \
|
||||
-DUSE_CCACHE=ON \
|
||||
-DWITH_QUICK=OFF \
|
||||
-DWITH_3D=OFF \
|
||||
-DWITH_STAGED_PLUGINS=OFF \
|
||||
-DWITH_GRASS=OFF \
|
||||
-DENABLE_MODELTEST=OFF \
|
||||
-DENABLE_PGTEST=OFF \
|
||||
-DENABLE_MSSQLTEST=OFF \
|
||||
-DENABLE_TESTS=OFF \
|
||||
-DWITH_QSPATIALITE=OFF \
|
||||
-DWITH_QWTPOLAR=OFF \
|
||||
-DWITH_APIDOC=OFF \
|
||||
-DWITH_ASTYLE=OFF \
|
||||
-DWITH_ANALYSIS=ON \
|
||||
-DWITH_GSL=OFF \
|
||||
-DWITH_DESKTOP=OFF \
|
||||
-DWITH_GUI=OFF \
|
||||
-DWITH_BINDINGS=ON \
|
||||
-DWITH_SERVER=ON \
|
||||
-DWITH_SERVER_PLUGINS=ON \
|
||||
-DWITH_ORACLE=OFF \
|
||||
-DWITH_PDAL=OFF \
|
||||
-DWITH_QTPRINTER=OFF \
|
||||
-DDISABLE_DEPRECATED=ON \
|
||||
-DCXX_EXTRA_FLAGS="${CLANG_WARNINGS}" \
|
||||
-DCMAKE_C_COMPILER=/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=/bin/clang++ \
|
||||
-DADD_CLAZY_CHECKS=OFF \
|
||||
..
|
||||
|
||||
ninja
|
||||
|
||||
echo "ccache statistics"
|
||||
ccache -s
|
29
.ci/ogc/docker-compose.yml
Normal file
29
.ci/ogc/docker-compose.yml
Normal file
@ -0,0 +1,29 @@
|
||||
version: '3'
|
||||
services:
|
||||
|
||||
nginx:
|
||||
image: nginx:1.13
|
||||
container_name: qgis_server_nginx
|
||||
ports:
|
||||
- 8089:80
|
||||
networks:
|
||||
- qgis
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
||||
- ./../../data/metadata:/var/www/html/wms13/metadata
|
||||
depends_on:
|
||||
- qgis-server
|
||||
|
||||
qgis-server:
|
||||
image: ${DOCKER_IMAGE}
|
||||
container_name: qgis_server_deps
|
||||
volumes:
|
||||
- ./../../:/usr/src/qgis/
|
||||
- ./../../data:/data
|
||||
networks:
|
||||
- qgis
|
||||
privileged: true
|
||||
|
||||
networks:
|
||||
qgis:
|
||||
driver: bridge
|
49
.ci/ogc/nginx.conf
Normal file
49
.ci/ogc/nginx.conf
Normal file
@ -0,0 +1,49 @@
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
|
||||
root /var/www/html;
|
||||
|
||||
# Add index.php to the list if you are using PHP
|
||||
index index.html index.htm index.nginx-debian.html;
|
||||
|
||||
server_name _;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
|
||||
location /qgisserver_wms130 {
|
||||
fastcgi_pass qgis-server:5555;
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,X-Requested-With';
|
||||
fastcgi_param PATH_INFO $fastcgi_script_name;
|
||||
fastcgi_param REQUEST_METHOD $request_method;
|
||||
fastcgi_param QUERY_STRING $query_string;
|
||||
fastcgi_param CONTENT_TYPE $content_type;
|
||||
fastcgi_param CONTENT_LENGTH $content_length;
|
||||
fastcgi_param SERVER_PROTOCOL $server_protocol;
|
||||
fastcgi_param REQUEST_URI $request_uri;
|
||||
fastcgi_param HTTPS $https if_not_empty;
|
||||
fastcgi_param SERVER_PORT 80;
|
||||
fastcgi_param SERVER_NAME $server_addr;
|
||||
fastcgi_param QGIS_PROJECT_FILE /data/teamengine_wms_130.qgs;
|
||||
}
|
||||
|
||||
location /qgisserver_ogcapif {
|
||||
fastcgi_pass qgis-server:5555;
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,X-Requested-With';
|
||||
fastcgi_param PATH_INFO $fastcgi_script_name;
|
||||
fastcgi_param REQUEST_METHOD $request_method;
|
||||
fastcgi_param QUERY_STRING $query_string;
|
||||
fastcgi_param CONTENT_TYPE $content_type;
|
||||
fastcgi_param CONTENT_LENGTH $content_length;
|
||||
fastcgi_param SERVER_PROTOCOL $server_protocol;
|
||||
fastcgi_param REQUEST_URI $request_uri;
|
||||
fastcgi_param HTTPS $https if_not_empty;
|
||||
fastcgi_param SERVER_PORT 80;
|
||||
fastcgi_param SERVER_NAME $server_addr;
|
||||
fastcgi_param QGIS_PROJECT_FILE /data/QGIS-Training-Data/exercise_data/qgis-server-tutorial-data/world.qgs;
|
||||
}
|
||||
}
|
7
.ci/ogc/qgis_mapserv.sh
Normal file
7
.ci/ogc/qgis_mapserv.sh
Normal file
@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
export QGIS_SERVER_LOG_STDERR=true
|
||||
export QGIS_SERVER_LOG_LEVEL=0
|
||||
export QGIS_PREFIX_PATH=/usr/src/qgis/build/output
|
||||
|
||||
exec /usr/bin/spawn-fcgi -n -p 5555 /usr/src/qgis/build/output/bin/qgis_mapserv.fcgi
|
40
.ci/pr_has_label.py
Executable file
40
.ci/pr_has_label.py
Executable file
@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
|
||||
from urllib.error import URLError
|
||||
from urllib.request import ( # using urllib since it is a standard module (vs. requests)
|
||||
urlopen,
|
||||
)
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Determines if a pull request has a defined label"
|
||||
)
|
||||
parser.add_argument("pull_request", type=str, help="pull request id")
|
||||
parser.add_argument("label", type=int, help="label ID")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.pull_request == "false":
|
||||
print("false")
|
||||
sys.exit(1)
|
||||
|
||||
url = f"https://api.github.com/repos/qgis/QGIS/pulls/{args.pull_request}"
|
||||
|
||||
try:
|
||||
data = urlopen(url).read().decode("utf-8")
|
||||
except URLError as err:
|
||||
print(f"URLError: {err.reason}")
|
||||
sys.exit(1)
|
||||
|
||||
obj = json.loads(data)
|
||||
|
||||
for label in obj["labels"]:
|
||||
if label["id"] == args.label:
|
||||
print("true")
|
||||
sys.exit(0)
|
||||
|
||||
print("label not found")
|
||||
sys.exit(1)
|
152
.ci/run_tests.sh
Executable file
152
.ci/run_tests.sh
Executable file
@ -0,0 +1,152 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
DOCKER=$(command -v podman docker | head -1)
|
||||
|
||||
# check for docker availability
|
||||
test -n "${DOCKER}" || {
|
||||
echo "Please install podman or docker" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
DOCKER_COMPOSE=$(command -v podman-compose docker-compose | head -1)
|
||||
test -n "${DOCKER_COMPOSE}" || {
|
||||
DOCKER_COMPOSE="${DOCKER} compose"
|
||||
# check if supported
|
||||
${DOCKER_COMPOSE} > /dev/null || {
|
||||
echo "Cannot find podman-compose or docker-compose, and '${DOCKER_COMPOSE}' fails" >&2
|
||||
echo "HINT: try installing podman-compose" >&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
IMAGE_BUILD_DEPS=docker.io/qgis/qgis3-build-deps:latest
|
||||
UPDATE_IMAGES=yes
|
||||
INTERACTIVE=no
|
||||
FORCE_REBUILD=no
|
||||
export QT_VERSION=5 # TODO: ask user for this one
|
||||
export DISTRO_VERSION=21.10 # TODO: ask user for this one
|
||||
# can be: ALL, ALL_BUT_PROVIDERS, POSTGRES, HANA, ORACLE, SQLSERVER
|
||||
TESTS_TO_RUN=ALL_BUT_PROVIDERS # TODO: ask user for this one
|
||||
|
||||
usage() {
|
||||
echo "Usage: $(basename $0) [--skip-update-images] [--force-rebuild] [--interactive]"
|
||||
}
|
||||
|
||||
while test -n "$1"; do
|
||||
if test "$1" = '--help' || test "$1" = '-h'; then
|
||||
usage
|
||||
exit 0
|
||||
elif test "$1" = '--skip-update-images'; then
|
||||
UPDATE_IMAGES=no
|
||||
shift
|
||||
elif test "$1" = '--force-rebuild'; then
|
||||
FORCE_REBUILD=yes
|
||||
shift
|
||||
elif test "$1" = '--interactive'; then
|
||||
INTERACTIVE=yes
|
||||
shift
|
||||
else
|
||||
echo "Unrecognized option $1" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
cd $(dirname $0)/.. || exit 1
|
||||
#echo "--=[ PWD is $PWD"
|
||||
|
||||
export QGIS_BUILDDIR=build-ci
|
||||
|
||||
QGIS_WORKSPACE="$(pwd -P)"
|
||||
export QGIS_WORKSPACE
|
||||
echo "--=[ QGIS_WORKSPACE is $QGIS_WORKSPACE"
|
||||
|
||||
QGIS_WORKSPACE_MOUNTPOINT=${QGIS_WORKSPACE} # was /root/QGIS
|
||||
export QGIS_WORKSPACE_MOUNTPOINT
|
||||
echo "--=[ QGIS_WORKSPACE_MOUNTPOINT is $QGIS_WORKSPACE_MOUNTPOINT"
|
||||
|
||||
QGIS_GIT_DIR="$(git rev-parse --git-dir)"
|
||||
if test -f ${QGIS_GIT_DIR}/commondir; then
|
||||
QGIS_COMMON_GIT_DIR="$(cat ${QGIS_GIT_DIR}/commondir)"
|
||||
else
|
||||
QGIS_COMMON_GIT_DIR=${QGIS_WORKSPACE}
|
||||
fi
|
||||
QGIS_COMMON_GIT_DIR="$(cd ${QGIS_COMMON_GIT_DIR} && pwd -P)"
|
||||
export QGIS_COMMON_GIT_DIR
|
||||
echo "--=[ QGIS_COMMON_GIT_DIR is $QGIS_COMMON_GIT_DIR"
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Make qgis3-build-deps-binary-image available, building it if needed
|
||||
#
|
||||
|
||||
if test "$(${DOCKER} images -q ${IMAGE_BUILD_DEPS})" = ""; then
|
||||
echo "--=[ Fetching qgis build dependencies image"
|
||||
${DOCKER} pull ${IMAGE_BUILD_DEPS}
|
||||
elif test "${UPDATE_IMAGES}" = "yes"; then
|
||||
echo "--=[ Updating qgis build dependencies image"
|
||||
${DOCKER} pull ${IMAGE_BUILD_DEPS}
|
||||
fi
|
||||
|
||||
if test -d ${QGIS_BUILDDIR} -a "${FORCE_REBUILD}" = "no"; then
|
||||
echo "--=[ Testing against pre-existing build directory ${QGIS_BUILDDIR}. To rebuild use --force-rebuild or move it away"
|
||||
else
|
||||
echo "--=[ Building qgis inside the dependencies container"
|
||||
VOLUMES="-v ${QGIS_WORKSPACE}:${QGIS_WORKSPACE}:z"
|
||||
if test "${QGIS_WORKSPACE}" != "${QGIS_COMMON_GIT_DIR}"; then
|
||||
VOLUMES="${VOLUMES} -v ${QGIS_COMMON_GIT_DIR}:${QGIS_COMMON_GIT_DIR}:z"
|
||||
fi
|
||||
${DOCKER} run -t --name qgis_container \
|
||||
--rm \
|
||||
${VOLUMES} \
|
||||
--env-file .docker/docker-variables.env \
|
||||
--env PUSH_TO_CDASH=false \
|
||||
--env WITH_QT5=true \
|
||||
--env BUILD_WITH_QT6=false \
|
||||
--env WITH_QUICK=false \
|
||||
--env WITH_3D=false \
|
||||
--env PATCH_QT_3D=false \
|
||||
--env CTEST_SOURCE_DIR=${QGIS_WORKSPACE} \
|
||||
--env CTEST_BUILD_DIR=${QGIS_WORKSPACE}/${QGIS_BUILDDIR} \
|
||||
${IMAGE_BUILD_DEPS} \
|
||||
${QGIS_WORKSPACE_MOUNTPOINT}/.docker/docker-qgis-build.sh ||
|
||||
exit 1
|
||||
|
||||
test -d ${QGIS_BUILDDIR} || {
|
||||
echo "Building failed" >&2
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
|
||||
if test "$(${DOCKER} images -q qgis3-build-deps-binary-image)" = ""; then
|
||||
echo "--=[ Tagging qgis build dependencies image as required by .docker/docker-compose-testing.yml"
|
||||
${DOCKER} tag ${IMAGE_BUILD_DEPS} qgis3-build-deps-binary-image
|
||||
fi
|
||||
|
||||
if test "${INTERACTIVE}" = "no"; then
|
||||
echo "--=[ Running tests via docker compose"
|
||||
COMMAND=${QGIS_WORKSPACE_MOUNTPOINT}/.docker/docker-qgis-test.sh
|
||||
COMMAND_ARGS="${TESTS_TO_RUN}"
|
||||
else
|
||||
echo "--=[ Starting interactive shell into test environment"
|
||||
COMMAND=bash
|
||||
fi
|
||||
|
||||
# Create an empty minio folder with appropriate permissions so www user can write inside it
|
||||
mkdir -p /tmp/minio_tests/test-bucket && chmod -R 777 /tmp/minio_tests
|
||||
|
||||
# Create an empty webdav folder with appropriate permissions so www user can write inside it
|
||||
mkdir -p /tmp/webdav_tests && chmod 777 /tmp/webdav_tests
|
||||
|
||||
${DOCKER_COMPOSE} \
|
||||
-f .docker/docker-compose-testing.yml \
|
||||
run \
|
||||
-w "${QGIS_WORKSPACE_MOUNTPOINT}" \
|
||||
-e PUSH_TO_CDASH=false \
|
||||
-e CTEST_SOURCE_DIR="${QGIS_WORKSPACE}" \
|
||||
-e CTEST_BUILD_DIR="${QGIS_WORKSPACE}/${QGIS_BUILDDIR}" \
|
||||
qgis-deps \
|
||||
${COMMAND} ${COMMAND_ARGS}
|
19
.ci/test_blocklist_qt5.txt
Normal file
19
.ci/test_blocklist_qt5.txt
Normal file
@ -0,0 +1,19 @@
|
||||
# block list
|
||||
test_gui_queryresultwidget
|
||||
|
||||
# code layout tests are run on separate build
|
||||
qgis_spelling
|
||||
qgis_sipify
|
||||
qgis_sip_include
|
||||
qgis_sip_uptodate
|
||||
|
||||
# Need a local postgres installation
|
||||
PyQgsAuthManagerOgrPostgresTest
|
||||
PyQgsDbManagerPostgis
|
||||
|
||||
# Needs an OpenCL device, the library is not enough
|
||||
test_core_openclutils
|
||||
|
||||
# Relies on a broken/unreliable 3rd party service
|
||||
test_core_layerdefinition
|
||||
|
43
.ci/test_blocklist_qt6.txt
Normal file
43
.ci/test_blocklist_qt6.txt
Normal file
@ -0,0 +1,43 @@
|
||||
# Qt6 blocklist
|
||||
test_core_compositionconverter
|
||||
test_core_labelingengine
|
||||
test_core_layoutpicture
|
||||
test_core_vectortilelayer
|
||||
test_gui_processinggui
|
||||
test_app_advanceddigitizing
|
||||
test_app_vertextool
|
||||
|
||||
# Crashes -- also disabled on qt5 builds!
|
||||
test_gui_queryresultwidget
|
||||
|
||||
# code layout tests are run on separate build
|
||||
qgis_spelling
|
||||
qgis_sipify
|
||||
qgis_sip_include
|
||||
qgis_sip_uptodate
|
||||
|
||||
# Need a local postgres installation
|
||||
PyQgsAuthManagerOgrPostgresTest
|
||||
PyQgsDbManagerPostgis
|
||||
|
||||
# Needs an OpenCL device, the library is not enough
|
||||
test_core_openclutils
|
||||
|
||||
# Relies on a broken/unreliable 3rd party service
|
||||
test_core_layerdefinition
|
||||
|
||||
# MSSQL requires the MSSQL docker
|
||||
PyQgsProviderConnectionMssql
|
||||
PyQgsStyleStorageMssql
|
||||
|
||||
# To be fixed
|
||||
PyQgsAnnotation
|
||||
PyQgsAuthenticationSystem
|
||||
PyQgsEditWidgets
|
||||
PyQgsElevationProfileCanvas
|
||||
PyQgsLayoutHtml
|
||||
PyQgsPalLabelingPlacement
|
||||
PyQgsRasterLayerRenderer
|
||||
PyQgsSettings
|
||||
PyQgsSettingsEntry
|
||||
ProcessingQgisAlgorithmsTestPt4
|
6
.ci/test_flaky.txt
Normal file
6
.ci/test_flaky.txt
Normal file
@ -0,0 +1,6 @@
|
||||
# flaky
|
||||
test_gui_filedownloader
|
||||
test_provider_wcsprovider
|
||||
PyQgsWFSProviderGUI
|
||||
# See https://github.com/qgis/QGIS/issues/48927
|
||||
test_core_tiledownloadmanager
|
219
.clang-format
Normal file
219
.clang-format
Normal file
@ -0,0 +1,219 @@
|
||||
---
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -2
|
||||
AlignAfterOpenBracket: BlockIndent
|
||||
AlignArrayOfStructures: None
|
||||
AlignConsecutiveAssignments:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveBitFields:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveDeclarations:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveMacros:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
PadOperators: false
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments:
|
||||
Kind: Always
|
||||
OverEmptyLines: 0
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortEnumsOnASingleLine: true
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: No
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BitFieldColonSpacing: Both
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: true
|
||||
AfterClass: true
|
||||
AfterControlStatement: true
|
||||
AfterEnum: true
|
||||
AfterExternBlock: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: false
|
||||
BreakAfterAttributes: Never
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakArrays: true
|
||||
BreakBeforeBinaryOperators: All
|
||||
BreakBeforeConceptDeclarations: Always
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 0
|
||||
CommentPragmas: "^ IWYU pragma:"
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 2
|
||||
ContinuationIndentWidth: 2
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
EmptyLineAfterAccessModifier: Never
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
IncludeCategories:
|
||||
- Regex: "^<Q.*"
|
||||
Priority: 300
|
||||
- Regex: "^<qgs.*"
|
||||
Priority: 200
|
||||
- Regex: "<.*"
|
||||
Priority: 400
|
||||
- Regex: '^".*'
|
||||
Priority: 100
|
||||
- Regex: ".*"
|
||||
Priority: 1
|
||||
|
||||
IncludeIsMainRegex: false
|
||||
#IncludeBlocks: Regroup
|
||||
IncludeIsMainSourceRegex: ""
|
||||
IndentAccessModifiers: true
|
||||
IndentCaseBlocks: false
|
||||
IndentCaseLabels: true
|
||||
IndentExternBlock: AfterExternBlock
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentRequiresClause: true
|
||||
IndentWidth: 2
|
||||
IndentWrappedFunctionNames: true
|
||||
# should be:
|
||||
# InsertBraces: true
|
||||
# InsertNewlineAtEOF: true
|
||||
InsertBraces: false
|
||||
InsertNewlineAtEOF: false
|
||||
InsertTrailingCommas: None
|
||||
IntegerLiteralSeparator:
|
||||
Binary: 0
|
||||
BinaryMinDigits: 0
|
||||
Decimal: 0
|
||||
DecimalMinDigits: 0
|
||||
Hex: 0
|
||||
HexMinDigits: 0
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
# Do not add QT_BEGIN_NAMESPACE/QT_END_NAMESPACE as this will indent lines in between.
|
||||
MacroBlockBegin: ""
|
||||
MacroBlockEnd: ""
|
||||
MaxEmptyLinesToKeep: 2
|
||||
NamespaceIndentation: All
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 4
|
||||
ObjCBreakBeforeNestedBlockParam: true
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PackConstructorInitializers: BinPack
|
||||
PenaltyBreakAssignment: 150
|
||||
PenaltyBreakBeforeFirstCallParameter: 5000
|
||||
PenaltyBreakComment: 500
|
||||
PenaltyBreakFirstLessLess: 400
|
||||
PenaltyBreakOpenParenthesis: 0
|
||||
PenaltyBreakString: 600
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 10
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PenaltyReturnTypeOnItsOwnLine: 5000
|
||||
PointerAlignment: Right
|
||||
PPIndentWidth: -1
|
||||
QualifierAlignment: Leave
|
||||
ReferenceAlignment: Pointer
|
||||
# should be:
|
||||
# ReflowComments: true
|
||||
ReflowComments: false
|
||||
RemoveBracesLLVM: false
|
||||
RemoveSemicolon: false
|
||||
RequiresClausePosition: OwnLine
|
||||
RequiresExpressionIndentation: OuterScope
|
||||
SeparateDefinitionBlocks: Leave
|
||||
ShortNamespaceLines: 1
|
||||
SortIncludes: false
|
||||
SortJavaStaticImport: Before
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: true
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: true
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeParensOptions:
|
||||
AfterControlStatements: true
|
||||
AfterForeachMacros: true
|
||||
AfterFunctionDefinitionName: false
|
||||
AfterFunctionDeclarationName: false
|
||||
AfterIfMacros: true
|
||||
AfterOverloadedOperator: false
|
||||
AfterRequiresInClause: false
|
||||
AfterRequiresInExpression: false
|
||||
BeforeNonEmptyParentheses: false
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceBeforeSquareBrackets: false
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: Leave
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInCStyleCastParentheses: true
|
||||
SpacesInLineCommentPrefix:
|
||||
# should be:
|
||||
# Minimum: 1
|
||||
Minimum: 0
|
||||
Maximum: -1
|
||||
SpacesInParentheses: true
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
TabWidth: 2
|
||||
UseTab: Never
|
||||
Macros:
|
||||
- SIP_ENUM_BASETYPE(x)=x
|
||||
- SIP_MONKEYPATCH_SCOPEENUM_UNNEST(x,y)=x
|
||||
AttributeMacros:
|
||||
- SIP_SKIP
|
||||
|
||||
---
|
||||
|
||||
Language: ObjC
|
||||
|
||||
ObjCBlockIndentWidth: 4
|
2
.clang-tidy
Normal file
2
.clang-tidy
Normal file
@ -0,0 +1,2 @@
|
||||
Checks: 'bugprone-*,-bugprone-easily-swappable-parameters,-bugprone-virtual-near-miss,-bugprone-suspicious-include'
|
||||
HeaderFilterRegex: ''
|
16
.cvsignore
16
.cvsignore
@ -1,16 +0,0 @@
|
||||
autogen.sh
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
compile
|
||||
config.guess
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
libtool
|
||||
ltmain.sh
|
||||
qgis.spec
|
||||
qgsconfig.h
|
||||
qgsconfig.h.in
|
||||
stamp-h1
|
258
.docker/README.md
Normal file
258
.docker/README.md
Normal file
@ -0,0 +1,258 @@
|
||||
QGIS Docker images
|
||||
==================
|
||||
|
||||
The QGIS project provides a few official docker images that can be
|
||||
used for testing purposes.
|
||||
|
||||
These dockers are currently used to run continuous integration
|
||||
tests for the QGIS project itself and to run continuous integration
|
||||
tests for several third party Python plugins.
|
||||
|
||||
The images are automatically built every day and pushed on docker hub
|
||||
to the QGIS account: https://hub.docker.com/r/qgis/
|
||||
|
||||
# Available images
|
||||
|
||||
## Dependencies image
|
||||
|
||||
`qgis/qgis3-build-deps`
|
||||
|
||||
This is a simple base image that contains all the dependencies required to build
|
||||
QGIS, it is used by the other images.
|
||||
|
||||
Multiple versions of this image may be available: the suffix in the image name indicates the Ubuntu version they are based on.
|
||||
|
||||
## Main QGIS image
|
||||
|
||||
`qgis/qgis`
|
||||
|
||||
This is the main image containing a build of QGIS.
|
||||
|
||||
The docker tags for this image are assigned for each point release (prefixed with `final-`), for the active development branches (prefixed with `release-`) while the `latest` tag refers to a build of the current master branch.
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
The docker file builds QGIS from the current directory and
|
||||
sets up a testing environment suitable for running tests
|
||||
inside QGIS.
|
||||
|
||||
You can use this docker image to test QGIS and/or to run unit tests inside
|
||||
QGIS, `xvfb` (A fake X server) is available and running as a service inside
|
||||
the container to allow for fully automated headless testing in CI pipelines
|
||||
such as Travis or Circle-CI.
|
||||
|
||||
### Building
|
||||
|
||||
You can build the image from the main directory of the QGIS source tree with:
|
||||
|
||||
```
|
||||
$ docker build -t qgis/qgis:latest \
|
||||
--build-arg DOCKER_TAG=latest \
|
||||
-f .docker/qgis.dockerfile \
|
||||
.
|
||||
```
|
||||
|
||||
The `DOCKER_TAG` argument, can be used to specify the tag of the dependencies image.
|
||||
|
||||
|
||||
### Running QGIS
|
||||
|
||||
You can also use this image to run QGIS on your desktop.
|
||||
|
||||
To run a QGIS container, assuming that you want to use your current
|
||||
display to use QGIS and the image is tagged `qgis/qgis:latest` you can use a script like the one here below:
|
||||
|
||||
```bash
|
||||
# Allow connections from any host
|
||||
$ xhost +
|
||||
$ docker run --rm -it --name qgis \
|
||||
-v /tmp/.X11-unix:/tmp/.X11-unix \
|
||||
-e DISPLAY=unix$DISPLAY \
|
||||
qgis/qgis:latest qgis
|
||||
```
|
||||
|
||||
This code snippet will launch QGIS inside a container and display the
|
||||
application on your screen.
|
||||
|
||||
### Running unit tests inside QGIS
|
||||
|
||||
Suppose that you have local directory containing the tests you want to execute into QGIS:
|
||||
|
||||
```
|
||||
/my_tests/travis_tests/
|
||||
├── __init__.py
|
||||
└── test_TravisTest.py
|
||||
```
|
||||
|
||||
To run the tests inside the container, you must mount the directory that
|
||||
contains the tests (e.g. your local directory `/my_tests`) into a volume
|
||||
that is accessible by the container, see `-v /my_tests/:/tests_directory`
|
||||
in the example below:
|
||||
|
||||
```bash
|
||||
$ docker run -d --name qgis -v /tmp/.X11-unix:/tmp/.X11-unix \
|
||||
-v /my_tests/:/tests_directory \
|
||||
-e DISPLAY=:99 \
|
||||
qgis/qgis:latest
|
||||
```
|
||||
|
||||
Here is an extract of `test_TravisTest.py`:
|
||||
|
||||
```python
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
from qgis.testing import unittest
|
||||
|
||||
class TestTest(unittest.TestCase):
|
||||
|
||||
def test_passes(self):
|
||||
self.assertTrue(True)
|
||||
|
||||
def run_all():
|
||||
"""Default function that is called by the runner if nothing else is specified"""
|
||||
suite = unittest.TestSuite()
|
||||
suite.addTests(unittest.makeSuite(TestTest, 'test'))
|
||||
unittest.TextTestRunner(verbosity=3, stream=sys.stdout).run(suite)
|
||||
|
||||
```
|
||||
|
||||
When done, you can invoke the test runnner by specifying the test
|
||||
that you want to run, for instance:
|
||||
|
||||
```
|
||||
$ docker exec -it qgis sh -c "cd /tests_directory && qgis_testrunner.sh travis_tests.test_TravisTest.run_fail"
|
||||
|
||||
```
|
||||
|
||||
The test can be specified by using a dotted notation, similar to Python
|
||||
import notation, by default the function named `run_all` will be executed
|
||||
but you can pass another function name as the last item in the dotted syntax:
|
||||
|
||||
```bash
|
||||
# Call the default function "run_all" inside test_TravisTest module
|
||||
qgis_testrunner.sh travis_tests.test_TravisTest
|
||||
# Call the function "run_fail" inside test_TravisTest module
|
||||
qgis_testrunner.sh travis_tests.test_TravisTest.run_fail
|
||||
```
|
||||
|
||||
Please note that in order to make the test script accessible to Python
|
||||
the calling command must ensure that the tests are in Python path.
|
||||
Common patterns are:
|
||||
- change directory to the one containing the tests (like in the examples above)
|
||||
- add to `PYTHONPATH` the directory containing the tests
|
||||
|
||||
#### Running tests for a Python plugin
|
||||
|
||||
All the above considerations applies to this case too, however in order
|
||||
to simulate the installation of the plugin inside QGIS, you'll need to
|
||||
make an additional step: call `qgis_setup.sh <YourPluginName>` in the
|
||||
docker container before actually running the tests (see the paragraph
|
||||
about Running on Travis for a complete example).
|
||||
|
||||
The `qgis_setup.sh` script prepares QGIS to run in headless mode and
|
||||
simulate the plugin installation process:
|
||||
|
||||
- creates the QGIS profile folders
|
||||
- "installs" the plugin by making a symbolic link from the profiles folder to the plugin folder
|
||||
- installs `startup.py` monkey patches to prevent blocking dialogs
|
||||
- enables the plugin
|
||||
|
||||
Please note that depending on your plugin repository internal directory structure
|
||||
you may need to adjust (remove and create) the symbolic link created by `qgis_setup.sh`,
|
||||
this is required in particular if the real plugin code in your repository is contained
|
||||
in the main directory and not in a subdirectory with the same name of the plugin
|
||||
internal name (the name in `metadata.txt`).
|
||||
|
||||
#### Options for the test runner
|
||||
|
||||
The env var `QGIS_EXTRA_OPTIONS` defaults to an empty string and can
|
||||
contains extra parameters that are passed to QGIS by the test runner.
|
||||
|
||||
|
||||
#### Running on Travis
|
||||
|
||||
Here is a simple example for running unit tests of a small QGIS plugin (named *QuickWKT*), assuming that the tests are in `tests/test_Plugin.py` under
|
||||
the main directory of the QuickWKT plugin:
|
||||
|
||||
```yml
|
||||
services:
|
||||
- docker
|
||||
install:
|
||||
- docker run -d --name qgis-testing-environment -v ${TRAVIS_BUILD_DIR}:/tests_directory -e DISPLAY=:99 qgis/qgis:latest
|
||||
- sleep 10 # This is required to allow xvfb to start
|
||||
# Setup qgis and enables the plugin
|
||||
- docker exec -it qgis-testing-environment sh -c "qgis_setup.sh QuickWKT"
|
||||
# Additional steps (for example make or paver setup) here
|
||||
# Fix the symlink created by qgis_setup.sh
|
||||
- docker exec -it qgis-testing-environment sh -c "rm -f /root/.local/share/QGIS/QGIS3/profiles/default/python/plugins/QuickWKT"
|
||||
- docker exec -it qgis-testing-environment sh -c "ln -s /tests_directory/ /root/.local/share/QGIS/QGIS3/profiles/default/python/plugins/QuickWKT"
|
||||
|
||||
script:
|
||||
- docker exec -it qgis-testing-environment sh -c "cd /tests_directory && qgis_testrunner.sh tests.test_Plugin"
|
||||
```
|
||||
|
||||
Please note that `cd /tests_directory && ` before the call to `qgis_testrunner.sh` could be avoided here, because QGIS automatically
|
||||
adds the plugin main directory to Python path.
|
||||
|
||||
|
||||
#### Running on Circle-CI
|
||||
|
||||
Here is an example for running unit tests of a small QGIS plugin (named *QuickWKT*), assuming
|
||||
that the tests are in `tests/test_Plugin.py` under the main directory of the QuickWKT plugin:
|
||||
|
||||
```yml
|
||||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: qgis/qgis:latest
|
||||
environment:
|
||||
DISPLAY: ":99"
|
||||
working_directory: /tests_directory
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Setup plugin
|
||||
command: |
|
||||
qgis_setup.sh QuickWKT
|
||||
- run:
|
||||
name: Fix installation path created by qgis_setup.s
|
||||
command: |
|
||||
rm -f /root/.local/share/QGIS/QGIS3/profiles/default/python/plugins/QuickWKT
|
||||
ln -s /tests_directory/ /root/.local/share/QGIS/QGIS3/profiles/default/python/plugins/qgisce
|
||||
- run:
|
||||
name: run tests
|
||||
command: |
|
||||
sh -c "/usr/bin/Xvfb :99 -screen 0 1024x768x24 -ac +extension GLX +render -noreset -nolisten tcp &"
|
||||
qgis_testrunner.sh tests.test_Plugin
|
||||
```
|
||||
|
||||
|
||||
#### Implementation notes
|
||||
|
||||
The main goal of the test runner in this image is to execute unit tests
|
||||
inside a real instance of QGIS (not a mocked one).
|
||||
|
||||
The QGIS tests should be runnable from a Travis/Circle-CI CI job.
|
||||
|
||||
The implementation is:
|
||||
|
||||
- run the docker, mounting as volumes the unit tests folder in `/tests_directory`
|
||||
(or the QGIS plugin folder if the unit tests belong to a plugin and the
|
||||
plugin is needed to run the tests)
|
||||
- execute `qgis_setup.sh MyPluginName` script in docker that sets up QGIS to
|
||||
avoid blocking modal dialogs and installs the plugin into QGIS if needed
|
||||
- create config and python plugin folders for QGIS
|
||||
- enable the plugin in the QGIS configuration file
|
||||
- install the `startup.py` script to disable python exception modal dialogs
|
||||
- execute the tests by running `qgis_testrunner.sh MyPluginName.tests.tests_MyTestModule.run_my_tests_function`
|
||||
- the output of the tests is captured by the `test_runner.sh` script and
|
||||
searched for `FAILED` (that is in the standard unit tests output) and other
|
||||
string that indicate a failure or success condition, if a failure condition
|
||||
is identified, the script exits with `1` otherwise it exits with `0`.
|
||||
|
||||
`qgis_testrunner.sh` accepts a dotted notation path to the test module that
|
||||
can end with the function that has to be called inside the module to run the
|
||||
tests. The last part (`.run_my_tests_function`) can be omitted and defaults to
|
||||
`run_all`.
|
25
.docker/docker-compose-testing-mssql.yml
Normal file
25
.docker/docker-compose-testing-mssql.yml
Normal file
@ -0,0 +1,25 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
mssql:
|
||||
image: mcr.microsoft.com/mssql/server:2022-latest
|
||||
environment:
|
||||
ACCEPT_EULA: Y
|
||||
MSSQL_SA_PASSWORD: QGIStestSQLServer1234
|
||||
ports:
|
||||
- 1433:1433
|
||||
|
||||
qgis-deps:
|
||||
tty: true
|
||||
image: qgis3-build-deps-binary-image
|
||||
volumes:
|
||||
- ${QGIS_WORKSPACE}:/root/QGIS
|
||||
links:
|
||||
- mssql
|
||||
env_file:
|
||||
- docker-variables.env
|
||||
environment:
|
||||
- LANG=C.UTF-8
|
||||
- LC_ALL=en_US.UTF-8
|
||||
cap_add:
|
||||
- NET_ADMIN
|
24
.docker/docker-compose-testing-oracle.yml
Normal file
24
.docker/docker-compose-testing-oracle.yml
Normal file
@ -0,0 +1,24 @@
|
||||
services:
|
||||
|
||||
oracle:
|
||||
image: oslandia/oracle-slim-for-qgis:18.4.0-xe
|
||||
environment:
|
||||
- ORACLE_SID=XE
|
||||
- ORACLE_PWD=adminpass
|
||||
- ORACLE_PDB=ORCLPDBTEST
|
||||
- ORACLE_CHARACTERSET=AL32UTF8
|
||||
ports:
|
||||
- 1521:1521
|
||||
|
||||
qgis-deps:
|
||||
tty: true
|
||||
image: qgis3-build-deps-binary-image
|
||||
volumes:
|
||||
- ${QGIS_WORKSPACE}:/root/QGIS
|
||||
links:
|
||||
- oracle
|
||||
env_file:
|
||||
- docker-variables.env
|
||||
environment:
|
||||
- LANG=C.UTF-8
|
||||
- LC_ALL=en_US.UTF-8
|
27
.docker/docker-compose-testing-postgres.yml
Normal file
27
.docker/docker-compose-testing-postgres.yml
Normal file
@ -0,0 +1,27 @@
|
||||
version: '3'
|
||||
services:
|
||||
postgres:
|
||||
build:
|
||||
dockerfile: Dockerfile-postgis
|
||||
context: ../tests/testdata
|
||||
environment:
|
||||
- ALLOW_IP_RANGE="172.18.0.0/16"
|
||||
# The following files are added in Dockerfile-postgis
|
||||
- SSL_CERT_FILE=/etc/ssl/certs/postgres.crt
|
||||
- SSL_KEY_FILE=/etc/ssl/private/postgres.key
|
||||
- SSL_CA_FILE=/etc/ssl/certs/qgis_ca.crt
|
||||
|
||||
qgis-deps:
|
||||
tty: true
|
||||
image: qgis3-build-deps-binary-image
|
||||
volumes:
|
||||
- ${QGIS_WORKSPACE}:/root/QGIS
|
||||
links:
|
||||
- postgres
|
||||
env_file:
|
||||
- docker-variables.env
|
||||
environment:
|
||||
- LANG=C.UTF-8
|
||||
- LC_ALL=en_US.UTF-8
|
||||
cap_add:
|
||||
- NET_ADMIN
|
39
.docker/docker-compose-testing.yml
Executable file
39
.docker/docker-compose-testing.yml
Executable file
@ -0,0 +1,39 @@
|
||||
version: '3'
|
||||
services:
|
||||
|
||||
httpbin:
|
||||
image: kennethreitz/httpbin:latest
|
||||
|
||||
webdav:
|
||||
image: nginx
|
||||
volumes:
|
||||
- ${QGIS_WORKSPACE}/.docker/webdav/nginx.conf:/etc/nginx/conf.d/default.conf
|
||||
- ${QGIS_WORKSPACE}/.docker/webdav/passwords.list:/etc/nginx/.passwords.list
|
||||
- /tmp/webdav_tests:/tmp/webdav_tests_root/webdav_tests
|
||||
|
||||
minio:
|
||||
image: minio/minio
|
||||
volumes:
|
||||
- /tmp/minio_tests:/data
|
||||
environment:
|
||||
- MINIO_ROOT_USER=minioadmin
|
||||
- MINIO_ROOT_PASSWORD=adminio€
|
||||
command: server /data
|
||||
|
||||
qgis-deps:
|
||||
tty: true
|
||||
image: qgis3-build-deps-binary-image
|
||||
volumes:
|
||||
- ${QGIS_WORKSPACE}:/root/QGIS
|
||||
- ${QGIS_COMMON_GIT_DIR}:${QGIS_COMMON_GIT_DIR}
|
||||
links:
|
||||
- webdav
|
||||
- minio
|
||||
- httpbin
|
||||
env_file:
|
||||
- docker-variables.env
|
||||
environment:
|
||||
- LANG=C.UTF-8
|
||||
- LC_ALL=en_US.UTF-8
|
||||
- QGIS_HTTPBIN_HOST=httpbin
|
||||
- QGIS_TEST_ACCEPT_GITSTATUS_CHECK_FAILURE=1
|
149
.docker/docker-qgis-build.sh
Executable file
149
.docker/docker-qgis-build.sh
Executable file
@ -0,0 +1,149 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
CTEST_SOURCE_DIR=${CTEST_SOURCE_DIR-/root/QGIS}
|
||||
CTEST_BUILD_DIR=${CTEST_BUILD_DIR-/root/QGIS/build}
|
||||
|
||||
export LANG="C.UTF-8"
|
||||
|
||||
##############
|
||||
# Setup ccache
|
||||
##############
|
||||
export CCACHE_TEMPDIR=/tmp
|
||||
# Github workflow cache max size is 2.0, but ccache data get compressed (roughly 1/5?)
|
||||
ccache -M 2.0G
|
||||
|
||||
# Temporarily uncomment to debug ccache issues
|
||||
# export CCACHE_LOGFILE=/tmp/cache.debug
|
||||
ccache -z
|
||||
|
||||
# To make ccache work properly with precompiled headers
|
||||
ccache --set-config sloppiness=pch_defines,time_macros,include_file_mtime,include_file_ctime
|
||||
|
||||
##############################
|
||||
# Variables for output styling
|
||||
##############################
|
||||
|
||||
bold=$(tput bold)
|
||||
endbold=$(tput sgr0)
|
||||
|
||||
###########
|
||||
# Configure
|
||||
###########
|
||||
pushd ${CTEST_SOURCE_DIR} > /dev/null
|
||||
mkdir -p ${CTEST_BUILD_DIR}
|
||||
pushd ${CTEST_BUILD_DIR} > /dev/null
|
||||
|
||||
echo "${bold}Running cmake...${endbold}"
|
||||
echo "::group::cmake"
|
||||
|
||||
BUILD_TYPE=Release
|
||||
|
||||
export CC=/usr/bin/clang
|
||||
export CXX=/usr/bin/clang++
|
||||
|
||||
if [[ "${WITH_CLAZY}" = "ON" ]]; then
|
||||
# In release mode, all variables in QgsDebugMsg would be considered unused
|
||||
BUILD_TYPE=Debug
|
||||
export CXX=clazy
|
||||
|
||||
# ignore sip and external libraries
|
||||
export CLAZY_IGNORE_DIRS="(.*/external/.*)|(.*sip_.*part.*)"
|
||||
fi
|
||||
|
||||
if [[ ${BUILD_WITH_QT6} = "ON" ]]; then
|
||||
CLANG_WARNINGS="-Wrange-loop-construct"
|
||||
fi
|
||||
|
||||
CMAKE_EXTRA_ARGS=()
|
||||
|
||||
if [[ "${WITH_COMPILE_COMMANDS}" == "ON" ]]; then
|
||||
CMAKE_EXTRA_ARGS+=(
|
||||
"-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
|
||||
)
|
||||
fi
|
||||
|
||||
if [[ ${WITH_GRASS7} == "ON" || ${WITH_GRASS8} == "ON" ]]; then
|
||||
CMAKE_EXTRA_ARGS+=(
|
||||
"-DGRASS_PREFIX$( grass --config version | cut -b 1 )=$( grass --config path )"
|
||||
)
|
||||
fi
|
||||
|
||||
if [[ ${BUILD_WITH_QT6} = "ON" ]]; then
|
||||
CMAKE_EXTRA_ARGS+=(
|
||||
"-DUSE_ALTERNATE_LINKER=mold"
|
||||
)
|
||||
fi
|
||||
|
||||
cmake \
|
||||
-GNinja \
|
||||
-DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
||||
-DUSE_CCACHE=ON \
|
||||
-DBUILD_WITH_QT6=${BUILD_WITH_QT6} \
|
||||
-DWITH_DESKTOP=ON \
|
||||
-DWITH_ANALYSIS=ON \
|
||||
-DWITH_GUI=ON \
|
||||
-DWITH_QUICK=${WITH_QUICK} \
|
||||
-DWITH_3D=${WITH_3D} \
|
||||
-DWITH_STAGED_PLUGINS=ON \
|
||||
-DWITH_GRASS7=${WITH_GRASS7} \
|
||||
-DWITH_GRASS8=${WITH_GRASS8} \
|
||||
-DWITH_GRASS_PLUGIN=${WITH_GRASS8} \
|
||||
-DENABLE_TESTS=ON \
|
||||
-DENABLE_MODELTEST=${WITH_QT5} \
|
||||
-DENABLE_PGTEST=${WITH_QT5} \
|
||||
-DENABLE_MSSQLTEST=${WITH_QT5} \
|
||||
-DENABLE_MSSQLTEST_CPP=${WITH_QT5} \
|
||||
-DENABLE_HANATEST=${WITH_QT5} \
|
||||
-DENABLE_ORACLETEST=${WITH_QT5} \
|
||||
-DENABLE_UNITY_BUILDS=${ENABLE_UNITY_BUILDS} \
|
||||
-DPUSH_TO_CDASH=${PUSH_TO_CDASH} \
|
||||
-DWITH_HANA=ON \
|
||||
-DWITH_QGIS_PROCESS=ON \
|
||||
-DWITH_QSPATIALITE=${WITH_QT5} \
|
||||
-DWITH_QWTPOLAR=OFF \
|
||||
-DWITH_APIDOC=OFF \
|
||||
-DWITH_ASTYLE=OFF \
|
||||
-DWITH_BINDINGS=ON \
|
||||
-DWITH_SERVER=ON \
|
||||
-DWITH_SERVER_LANDINGPAGE_WEBAPP=${WITH_QT5} \
|
||||
-DWITH_ORACLE=ON \
|
||||
-DWITH_PDAL=ON \
|
||||
-DWITH_QTSERIALPORT=ON \
|
||||
-DWITH_QTWEBKIT=${WITH_QT5} \
|
||||
-DWITH_QTWEBENGINE=${WITH_QTWEBENGINE} \
|
||||
-DWITH_PDF4QT=${WITH_PDF4QT} \
|
||||
-DORACLE_INCLUDEDIR=/instantclient_21_16/sdk/include/ \
|
||||
-DORACLE_LIBDIR=/instantclient_21_16/ \
|
||||
-DDISABLE_DEPRECATED=ON \
|
||||
-DPYTHON_TEST_WRAPPER="timeout -sSIGSEGV 55s" \
|
||||
-DCXX_EXTRA_FLAGS="${CLANG_WARNINGS}" \
|
||||
-DWERROR=TRUE \
|
||||
-DAGGRESSIVE_SAFE_MODE=ON \
|
||||
-DWITH_CLAZY=${WITH_CLAZY} \
|
||||
"${CMAKE_EXTRA_ARGS[@]}" ..
|
||||
echo "::endgroup::"
|
||||
|
||||
# Workaround https://github.com/actions/checkout/issues/760
|
||||
git config --global --add safe.directory ${CTEST_SOURCE_DIR}
|
||||
git config --global --add safe.directory ${CTEST_BUILD_DIR}
|
||||
|
||||
#######
|
||||
# Build
|
||||
#######
|
||||
echo "${bold}Building QGIS...${endbold}"
|
||||
echo "::group::build"
|
||||
ctest -VV -S ${CTEST_SOURCE_DIR}/.ci/config_build.ctest
|
||||
echo "::endgroup::"
|
||||
|
||||
########################
|
||||
# Show ccache statistics
|
||||
########################
|
||||
echo "ccache statistics"
|
||||
ccache -s
|
||||
|
||||
popd > /dev/null # ${CTEST_BUILD_DIR}
|
||||
popd > /dev/null # ${CTEST_SOURCE_DIR}
|
||||
|
||||
[ -r /tmp/ctest-important.log ] && cat /tmp/ctest-important.log || true
|
50
.docker/docker-qgis-clangtidy.sh
Executable file
50
.docker/docker-qgis-clangtidy.sh
Executable file
@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bash
|
||||
###########################################################################
|
||||
# docker-qgis-clangtidy.sh
|
||||
# ---------------------
|
||||
# Date : September 2022
|
||||
# Copyright : (C) 2022 by Julien Cabieces
|
||||
# Email : julien dot cabieces at oslandia dot com
|
||||
###########################################################################
|
||||
# #
|
||||
# This program is free software; you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation; either version 2 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
###########################################################################
|
||||
|
||||
set -e
|
||||
|
||||
SRCDIR=${CTEST_SOURCE_DIR-/root/QGIS}
|
||||
cd ${SRCDIR}
|
||||
|
||||
# This is needed for `git status` to work, see
|
||||
# https://github.com/qgis/QGIS/runs/6733585841?check_suite_focus=true#step:13:89
|
||||
git config --global --add safe.directory ${SRCDIR}
|
||||
|
||||
# The clang-tidy version installed needs to match the one used to compile QGIS.
|
||||
# Otherwise, it will not be able to inspect the modified files.
|
||||
echo "::group::Install clang tidy"
|
||||
apt install -y \
|
||||
clang-tidy-15
|
||||
echo "::endgroup::"
|
||||
|
||||
cd ${SRCDIR}
|
||||
|
||||
echo "${bold}Disable unity build...${endbold}"
|
||||
cmake . -B build -DENABLE_UNITY_BUILDS=OFF
|
||||
|
||||
echo "${bold}Run clang-tidy on modifications...${endbold}"
|
||||
|
||||
# We need to add build/src/test dir as extra include directories because when clang-tidy tries to process qgstest.h
|
||||
# it has no compile_commands.json instructions to know what are include directories
|
||||
# It manages to figure out for other headers though, I don't get how...
|
||||
git diff -U0 HEAD^ | python3 /usr/bin/clang-tidy-diff-15.py -p1 -path=${CTEST_BUILD_DIR} -use-color -extra-arg=-I${CTEST_BUILD_DIR}/src/test/ -clang-tidy-binary /usr/bin/clang-tidy-15 | tee clang-tidy.log
|
||||
|
||||
echo -e "\e[1;34mTo reproduce locally:"
|
||||
echo -e "\e[1;34m - launch cmake with option -DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
|
||||
echo -e "\e[1;34m - update build by calling Ninja"
|
||||
echo -e "\e[1;34m - launch command ./scripts/clang-tidy.sh -p <your_build_dir> <source_file>"
|
||||
|
||||
exit $(grep -c "warning:" clang-tidy.log)
|
292
.docker/docker-qgis-test.sh
Executable file
292
.docker/docker-qgis-test.sh
Executable file
@ -0,0 +1,292 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
SRCDIR=${CTEST_SOURCE_DIR-/root/QGIS}
|
||||
cd ${SRCDIR}
|
||||
|
||||
# This is needed for `git status` to work, see
|
||||
# https://github.com/qgis/QGIS/runs/6733585841?check_suite_focus=true#step:13:89
|
||||
git config --global --add safe.directory ${SRCDIR}
|
||||
|
||||
usage() {
|
||||
echo "Usage; $(basename $0) [<TEST_BATCHNAME>]"
|
||||
echo "TEST_BATCHNAME can be any of:"
|
||||
echo " HANA Test the HANA provider"
|
||||
echo " POSTGRES Test the PostgreSQL provider"
|
||||
echo " ORACLE Test the Oracle provider"
|
||||
echo " SQLSERVER Test the SQL Server provider"
|
||||
echo " ALL_BUT_PROVIDERS Skip all providers tests"
|
||||
echo " ALL (default) Run all tests"
|
||||
}
|
||||
|
||||
if [ $# -eq 1 ] && [ $1 = "HANA" ]; then
|
||||
LABELS_TO_RUN="HANA"
|
||||
RUN_HANA=YES
|
||||
|
||||
elif [ $# -eq 1 ] && [ $1 = "POSTGRES" ]; then
|
||||
LABELS_TO_RUN="POSTGRES"
|
||||
RUN_POSTGRES=YES
|
||||
|
||||
elif [ $# -eq 1 ] && [ $1 = "ORACLE" ]; then
|
||||
LABELS_TO_RUN="ORACLE"
|
||||
RUN_ORACLE=YES
|
||||
|
||||
elif [ $# -eq 1 ] && [ $1 = "SQLSERVER" ]; then
|
||||
LABELS_TO_RUN="SQLSERVER"
|
||||
RUN_SQLSERVER=YES
|
||||
|
||||
elif [ $# -eq 1 ] && [ $1 = "ALL_BUT_PROVIDERS" ]; then
|
||||
LABELS_TO_EXCLUDE="HANA|POSTGRES|ORACLE|SQLSERVER"
|
||||
|
||||
elif [ $# -gt 0 ] && [ $1 != "ALL" ]; then
|
||||
echo "Invalid argument"
|
||||
usage >&2
|
||||
exit 1
|
||||
|
||||
else
|
||||
RUN_HANA=YES
|
||||
RUN_POSTGRES=YES
|
||||
RUN_ORACLE=YES
|
||||
RUN_SQLSERVER=YES
|
||||
fi
|
||||
|
||||
# Debug env
|
||||
echo "::group::Print env"
|
||||
env
|
||||
echo "::endgroup::"
|
||||
|
||||
# Temporarily uncomment to debug ccache issues
|
||||
# cat /tmp/cache.debug
|
||||
|
||||
|
||||
if [ -n "$LABELS_TO_RUN" ]; then
|
||||
echo "Only following test labels will be run: $LABELS_TO_RUN"
|
||||
CTEST_OPTIONS="-L $LABELS_TO_RUN"
|
||||
fi
|
||||
|
||||
if [ -n "$LABELS_TO_EXCLUDE" ]; then
|
||||
echo "Following test labels will be excluded: $LABELS_TO_EXCLUDE"
|
||||
CTEST_OPTIONS="$CTEST_OPTIONS -LE $LABELS_TO_EXCLUDE"
|
||||
fi
|
||||
|
||||
if [ ${RUN_HANA:-"NO"} == "YES" ]; then
|
||||
|
||||
##################################
|
||||
# Prepare HANA database connection
|
||||
##################################
|
||||
|
||||
echo "::group::hana"
|
||||
echo "${bold}Load HANA database...${endbold}"
|
||||
|
||||
export HANA_HOST=917df316-4e01-4a10-be54-eac1b6ab15fb.hana.prod-us10.hanacloud.ondemand.com
|
||||
export HANA_PORT=443
|
||||
export HANA_USER=QGISCI
|
||||
export HANA_PASSWORD="tQ&7W3Klr9!p"
|
||||
|
||||
export QGIS_HANA_TEST_DB='driver='/usr/sap/hdbclient/libodbcHDB.so' host='${HANA_HOST}' port='${HANA_PORT}' user='${HANA_USER}' password='${HANA_PASSWORD}' sslEnabled=true sslValidateCertificate=False'
|
||||
|
||||
# wait for the DB to be available
|
||||
echo "Wait a moment while trying to connect to a HANA database."
|
||||
while ! echo exit | hdbsql -n '${HANA_HOST}:${HANA_PORT}' -u '${HANA_USER}' -p '${HANA_PASSWORD}' &> /dev/null
|
||||
do
|
||||
printf "⚘"
|
||||
sleep 1
|
||||
done
|
||||
echo "🌊 done"
|
||||
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
|
||||
if [ ${RUN_POSTGRES:-"NO"} == "YES" ]; then
|
||||
|
||||
echo "::group::Setup PostgreSQL"
|
||||
|
||||
############################
|
||||
# Restore postgres test data
|
||||
############################
|
||||
echo "${bold}Load Postgres database...🐘${endbold}"
|
||||
|
||||
printf "[qgis_test]\nhost=postgres\nport=5432\ndbname=qgis_test\nuser=docker\npassword=docker" > ~/.pg_service.conf
|
||||
export PGUSER=docker
|
||||
export PGHOST=postgres
|
||||
export PGPASSWORD=docker
|
||||
export PGDATABASE=qgis_test
|
||||
|
||||
# wait for the DB to be available
|
||||
echo "Wait a moment while loading PostGreSQL database."
|
||||
while ! PGPASSWORD='docker' psql -h postgres -U docker -p 5432 -l &> /dev/null
|
||||
do
|
||||
printf "🐘"
|
||||
sleep 1
|
||||
done
|
||||
echo " done 🥩"
|
||||
|
||||
pushd ${SRCDIR} > /dev/null
|
||||
echo "Restoring postgres test data ..."
|
||||
${SRCDIR}/tests/testdata/provider/testdata_pg.sh
|
||||
echo "Postgres test data restored ..."
|
||||
popd > /dev/null # /root/QGIS
|
||||
|
||||
echo "::endgroup::"
|
||||
|
||||
fi
|
||||
|
||||
if [ ${RUN_ORACLE:-"NO"} == "YES" ]; then
|
||||
|
||||
echo "::group::Setup Oracle"
|
||||
|
||||
##############################
|
||||
# Restore Oracle test data
|
||||
##############################
|
||||
|
||||
echo "${bold}Load Oracle database...🙏${endbold}"
|
||||
|
||||
export ORACLE_HOST="oracle"
|
||||
export ORACLE_PDB="XEPDB1"
|
||||
export QGIS_ORACLETEST_DBNAME="${ORACLE_HOST}/${ORACLE_PDB}"
|
||||
export QGIS_ORACLETEST_DB="host=${ORACLE_HOST} dbname=${ORACLE_PDB} port=1521 user='QGIS' password='qgis'"
|
||||
|
||||
echo "Wait a moment while loading Oracle database."
|
||||
COUNT=0
|
||||
while ! echo exit | sqlplus -L SYSTEM/adminpass@$QGIS_ORACLETEST_DBNAME &> /dev/null
|
||||
do
|
||||
printf "🙏"
|
||||
sleep 5
|
||||
if [[ $(( COUNT++ )) -eq 40 ]]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ ${COUNT} -eq 41 ]]; then
|
||||
echo "timeout, no oracle, no 🙏"
|
||||
else
|
||||
echo " done 👀"
|
||||
pushd ${SRCDIR} > /dev/null
|
||||
${SRCDIR}/tests/testdata/provider/testdata_oracle.sh $ORACLE_HOST
|
||||
popd > /dev/null # /root/QGIS
|
||||
fi
|
||||
|
||||
echo "::endgroup::"
|
||||
|
||||
fi
|
||||
|
||||
if [ ${RUN_SQLSERVER:-"NO"} == "YES" ]; then
|
||||
|
||||
echo "::group::Setup SQL Server"
|
||||
|
||||
##############################
|
||||
# Restore SQL Server test data
|
||||
##############################
|
||||
|
||||
echo "Wait a moment before loading SQL Server database."
|
||||
sleep 15
|
||||
|
||||
echo "Importing SQL Server test data..."
|
||||
|
||||
export SQLUSER=sa
|
||||
export SQLHOST=mssql
|
||||
export SQLPORT=1433
|
||||
export SQLPASSWORD=QGIStestSQLServer1234
|
||||
export SQLDATABASE=qgis_test
|
||||
|
||||
export PATH=$PATH:/opt/mssql-tools/bin
|
||||
|
||||
pushd ${SRCDIR} > /dev/null
|
||||
${SRCDIR}/tests/testdata/provider/testdata_mssql.sh
|
||||
popd > /dev/null # ${SRCDIR}
|
||||
|
||||
echo "Setting up DSN for test SQL Server"
|
||||
|
||||
cat <<EOT > /etc/odbc.ini
|
||||
[ODBC Data Sources]
|
||||
testsqlserver = ODBC Driver 18 for SQL Server
|
||||
|
||||
[testsqlserver]
|
||||
Driver = ODBC Driver 18 for SQL Server
|
||||
Description = Test SQL Server
|
||||
Server = mssql
|
||||
Encrypt = no
|
||||
AllowSelfSignedServerCert=1
|
||||
EOT
|
||||
|
||||
echo "::endgroup::"
|
||||
|
||||
fi
|
||||
|
||||
#######################################
|
||||
# Wait for Minio container to be ready
|
||||
#######################################
|
||||
|
||||
if [ $# -eq 0 ] || [ $1 = "ALL_BUT_PROVIDERS" ] || [ $1 = "ALL" ] ; then
|
||||
|
||||
echo "::group::Setup Minio"
|
||||
|
||||
echo "Wait for minio to be ready..."
|
||||
COUNT=0
|
||||
while ! curl http://$QGIS_MINIO_HOST:$QGIS_MINIO_PORT &> /dev/null;
|
||||
do
|
||||
printf "."
|
||||
sleep 5
|
||||
if [[ $(( COUNT++ )) -eq 40 ]]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ ${COUNT} -eq 41 ]]; then
|
||||
echo "Error: Minio docker timeout!!!"
|
||||
else
|
||||
echo "done"
|
||||
fi
|
||||
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
|
||||
#######################################
|
||||
# Wait for WebDAV container to be ready
|
||||
#######################################
|
||||
|
||||
if [ $# -eq 0 ] || [ $1 = "ALL_BUT_PROVIDERS" ] || [ $1 = "ALL" ] ; then
|
||||
|
||||
echo "::group::Setup WebDAV"
|
||||
|
||||
echo "Wait for webdav to be ready..."
|
||||
COUNT=0
|
||||
while ! curl -f -X GET -u qgis:myPasswd! http://$QGIS_WEBDAV_HOST:$QGIS_WEBDAV_PORT/webdav_tests/ &> /dev/null;
|
||||
do
|
||||
printf "."
|
||||
sleep 5
|
||||
if [[ $(( COUNT++ )) -eq 40 ]]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ ${COUNT} -eq 41 ]]; then
|
||||
echo "Error: WebDAV docker timeout!!!"
|
||||
else
|
||||
echo "done"
|
||||
fi
|
||||
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
|
||||
###########
|
||||
# Run tests
|
||||
###########
|
||||
EXCLUDE_TESTS="^$(cat ${SRCDIR}/.ci/test_blocklist_qt${QT_VERSION}.txt | sed -r '/^(#.*?)?$/d' | paste -sd '~' | sed -r 's/~/\$|^/g' -)\$"
|
||||
if ! [[ ${RUN_FLAKY_TESTS} == true ]]; then
|
||||
echo "Flaky tests are skipped!"
|
||||
EXCLUDE_TESTS=${EXCLUDE_TESTS}"|^"$(cat ${SRCDIR}/.ci/test_flaky.txt | sed -r '/^(#.*?)?$/d' | paste -sd '~' | sed -r 's/~/\$|^/g' -)"$"
|
||||
else
|
||||
echo "Flaky tests are run!"
|
||||
fi
|
||||
echo "List of skipped tests: $EXCLUDE_TESTS"
|
||||
|
||||
echo "::group::Print disk space before running tests"
|
||||
df -h
|
||||
echo "::endgroup::"
|
||||
|
||||
export QTWEBENGINE_DISABLE_SANDBOX=1
|
||||
|
||||
python3 ${SRCDIR}/.ci/ctest2ci.py xvfb-run ctest -V $CTEST_OPTIONS -E "${EXCLUDE_TESTS}" -S ${SRCDIR}/.ci/config_test.ctest --output-on-failure
|
||||
|
||||
echo "::group::Print disk space after running tests"
|
||||
df -h
|
||||
echo "::endgroup::"
|
28
.docker/docker-variables.env
Normal file
28
.docker/docker-variables.env
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
# CTEST
|
||||
SEGFAULT_SIGNALS="abrt segv"
|
||||
CTEST_BUILD_COMMAND=/usr/bin/ninja
|
||||
CTEST_PARALLEL_LEVEL=1
|
||||
CTEST_SOURCE_DIR=/root/QGIS
|
||||
CTEST_BUILD_DIR=/root/QGIS/build
|
||||
|
||||
# CTEST vars defined in workflow
|
||||
CTEST_BUILD_NAME
|
||||
RUN_FLAKY_TESTS
|
||||
QT_VERSION
|
||||
|
||||
# Other vars
|
||||
QGIS_NO_OVERRIDE_IMPORT=1
|
||||
|
||||
# This is used in some tests to be skipped
|
||||
QGIS_CONTINUOUS_INTEGRATION_RUN=true
|
||||
|
||||
PUSH_TO_CDASH=false
|
||||
|
||||
XDG_RUNTIME_DIR=/tmp
|
||||
|
||||
QGIS_MINIO_HOST=minio
|
||||
QGIS_MINIO_PORT=9000
|
||||
|
||||
QGIS_WEBDAV_HOST=webdav
|
||||
QGIS_WEBDAV_PORT=80
|
79
.docker/qgis.dockerfile
Normal file
79
.docker/qgis.dockerfile
Normal file
@ -0,0 +1,79 @@
|
||||
|
||||
# see https://docs.docker.com/docker-cloud/builds/advanced/
|
||||
# using ARG in FROM requires min v17.05.0-ce
|
||||
ARG DOCKER_DEPS_TAG=latest
|
||||
|
||||
FROM qgis/qgis3-build-deps:${DOCKER_DEPS_TAG} AS BUILDER
|
||||
MAINTAINER Denis Rouzaud <denis@opengis.ch>
|
||||
|
||||
LABEL Description="Docker container with QGIS" Vendor="QGIS.org" Version="1.1"
|
||||
|
||||
# build timeout in seconds, so no timeout by default
|
||||
ARG BUILD_TIMEOUT=360000
|
||||
|
||||
ARG CC=/usr/lib/ccache/gcc
|
||||
ARG CXX=/usr/lib/ccache/g++
|
||||
ENV LANG=C.UTF-8
|
||||
|
||||
COPY . /QGIS
|
||||
|
||||
# If this directory is changed, also adapt script.sh which copies the directory
|
||||
# if ccache directory is not provided with the source
|
||||
RUN mkdir -p /QGIS/.ccache_image_build
|
||||
ENV CCACHE_DIR=/QGIS/.ccache_image_build
|
||||
RUN ccache -M 1G
|
||||
RUN ccache -s
|
||||
|
||||
RUN echo "ccache_dir: "$(du -h --max-depth=0 ${CCACHE_DIR})
|
||||
|
||||
WORKDIR /QGIS/build
|
||||
|
||||
RUN SUCCESS=OK \
|
||||
&& cmake \
|
||||
-GNinja \
|
||||
-DUSE_CCACHE=OFF \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DWITH_DESKTOP=ON \
|
||||
-DWITH_SERVER=ON \
|
||||
-DWITH_3D=ON \
|
||||
-DWITH_BINDINGS=ON \
|
||||
-DWITH_CUSTOM_WIDGETS=ON \
|
||||
-DBINDINGS_GLOBAL_INSTALL=ON \
|
||||
-DWITH_STAGED_PLUGINS=ON \
|
||||
-DWITH_GRASS=ON \
|
||||
-DDISABLE_DEPRECATED=ON \
|
||||
-DENABLE_TESTS=OFF \
|
||||
-DWITH_QSPATIALITE=ON \
|
||||
-DWITH_APIDOC=OFF \
|
||||
-DWITH_ASTYLE=OFF \
|
||||
.. \
|
||||
&& ninja install || SUCCESS=FAILED \
|
||||
&& echo "$SUCCESS" > /QGIS/build_exit_value
|
||||
|
||||
# Additional run-time dependencies
|
||||
RUN pip3 install jinja2 pygments pexpect && apt install -y expect
|
||||
|
||||
################################################################################
|
||||
# Python testing environment setup
|
||||
|
||||
# Add QGIS test runner
|
||||
COPY .docker/qgis_resources/test_runner/qgis_* /usr/bin/
|
||||
|
||||
# Make all scripts executable
|
||||
RUN chmod +x /usr/bin/qgis_*
|
||||
|
||||
# Add supervisor service configuration script
|
||||
COPY .docker/qgis_resources/supervisor/ /etc/supervisor
|
||||
|
||||
# Python paths are for
|
||||
# - kartoza images (compiled)
|
||||
# - deb installed
|
||||
# - built from git
|
||||
# needed to find PyQt wrapper provided by QGIS
|
||||
ENV PYTHONPATH=/usr/share/qgis/python/:/usr/share/qgis/python/plugins:/usr/lib/python3/dist-packages/qgis:/usr/share/qgis/python/qgis
|
||||
|
||||
WORKDIR /
|
||||
|
||||
# Run supervisor
|
||||
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]
|
249
.docker/qgis3-qt5-build-deps.dockerfile
Normal file
249
.docker/qgis3-qt5-build-deps.dockerfile
Normal file
@ -0,0 +1,249 @@
|
||||
|
||||
ARG DISTRO_VERSION=24.04
|
||||
ARG PDAL_VERSION=2.8.4
|
||||
|
||||
# Oracle Docker image is too large, so we add as less dependencies as possible
|
||||
# so there is enough space on GitHub runner
|
||||
FROM ubuntu:${DISTRO_VERSION} AS binary-for-oracle
|
||||
LABEL org.opencontainers.image.authors="Denis Rouzaud <denis@opengis.ch>"
|
||||
|
||||
LABEL Description="Docker container with QGIS dependencies" Vendor="QGIS.org" Version="1.0"
|
||||
|
||||
ARG PDAL_VERSION
|
||||
|
||||
# && echo "deb http://ppa.launchpad.net/ubuntugis/ubuntugis-unstable/ubuntu xenial main" >> /etc/apt/sources.list \
|
||||
# && echo "deb-src http://ppa.launchpad.net/ubuntugis/ubuntugis-unstable/ubuntu xenial main" >> /etc/apt/sources.list \
|
||||
# && apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 314DF160 \
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y software-properties-common \
|
||||
&& apt-get update \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
apt-transport-https \
|
||||
ca-certificates \
|
||||
clazy \
|
||||
cmake \
|
||||
curl \
|
||||
dh-python \
|
||||
git \
|
||||
gdal-bin \
|
||||
gnupg \
|
||||
gpsbabel \
|
||||
graphviz \
|
||||
'libaio1|libaio1t64' \
|
||||
'libdraco4|libdraco8' \
|
||||
libexiv2-27 \
|
||||
'libfcgi0ldbl|libfcgi0t64' \
|
||||
libgsl27 \
|
||||
'libprotobuf-lite17|libprotobuf-lite23|libprotobuf-lite32t64' \
|
||||
libqca-qt5-2-plugins \
|
||||
libqt53dextras5 \
|
||||
libqt53drender5 \
|
||||
'libqt5concurrent5|libqt5concurrent5t64' \
|
||||
libqt5keychain1 \
|
||||
libqt5positioning5 \
|
||||
libqt5multimedia5 \
|
||||
libqt5multimediawidgets5 \
|
||||
libqt5qml5 \
|
||||
libqt5quick5 \
|
||||
libqt5quickcontrols2-5 \
|
||||
libqt5quickwidgets5 \
|
||||
libqt5serialport5 \
|
||||
libqt5sql5-odbc \
|
||||
libqt5sql5-sqlite \
|
||||
'libqt5xml5|libqt5xml5t64' \
|
||||
libqt5webkit5 \
|
||||
libqwt-qt5-6 \
|
||||
libspatialindex6 \
|
||||
libsqlite3-mod-spatialite \
|
||||
'libzip4|libzip5|libzip4t64' \
|
||||
lighttpd \
|
||||
locales \
|
||||
poppler-utils \
|
||||
python3-future \
|
||||
python3-gdal \
|
||||
python3-mock \
|
||||
python3-nose2 \
|
||||
python3-numpy \
|
||||
python3-owslib \
|
||||
python3-pip \
|
||||
python3-psycopg2 \
|
||||
python3-pyproj \
|
||||
python3-pyqt5 \
|
||||
python3-pyqt5.qsci \
|
||||
python3-pyqt5.qtsql \
|
||||
python3-pyqt5.qtsvg \
|
||||
python3-pyqt5.qtwebkit \
|
||||
python3-pyqt5.qtpositioning \
|
||||
python3-pyqt5.qtmultimedia \
|
||||
python3-pyqt5.qtserialport \
|
||||
python3-sip \
|
||||
python3-termcolor \
|
||||
python3-yaml \
|
||||
qpdf \
|
||||
qt3d-assimpsceneimport-plugin \
|
||||
qt3d-defaultgeometryloader-plugin \
|
||||
qt3d-gltfsceneio-plugin \
|
||||
qt3d-scene2d-plugin \
|
||||
qt5-image-formats-plugins \
|
||||
saga \
|
||||
supervisor \
|
||||
unzip \
|
||||
xauth \
|
||||
xfonts-100dpi \
|
||||
xfonts-75dpi \
|
||||
xfonts-base \
|
||||
xfonts-scalable \
|
||||
xvfb \
|
||||
ocl-icd-libopencl1 \
|
||||
&& pip3 install --break-system-packages \
|
||||
numpy \
|
||||
nose2 \
|
||||
pyyaml \
|
||||
mock \
|
||||
future \
|
||||
termcolor \
|
||||
oauthlib \
|
||||
pyopenssl \
|
||||
pep8 \
|
||||
pexpect \
|
||||
capturer \
|
||||
sphinx \
|
||||
requests \
|
||||
six \
|
||||
hdbcli \
|
||||
shapely \
|
||||
&& apt-get clean
|
||||
|
||||
# Node.js and Yarn for server landingpage webapp
|
||||
RUN mkdir -p /etc/apt/keyrings
|
||||
RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
|
||||
RUN echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_22.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y nodejs
|
||||
RUN corepack enable
|
||||
|
||||
# Oracle : client side
|
||||
RUN curl https://download.oracle.com/otn_software/linux/instantclient/2116000/instantclient-basic-linux.x64-21.16.0.0.0dbru.zip > instantclient-basic-linux.x64-21.16.0.0.0dbru.zip
|
||||
RUN curl https://download.oracle.com/otn_software/linux/instantclient/2116000/instantclient-sdk-linux.x64-21.16.0.0.0dbru.zip > instantclient-sdk-linux.x64-21.16.0.0.0dbru.zip
|
||||
RUN curl https://download.oracle.com/otn_software/linux/instantclient/2116000/instantclient-sqlplus-linux.x64-21.16.0.0.0dbru.zip > instantclient-sqlplus-linux.x64-21.16.0.0.0dbru.zip
|
||||
|
||||
RUN unzip -n instantclient-basic-linux.x64-21.16.0.0.0dbru.zip
|
||||
RUN unzip -n instantclient-sdk-linux.x64-21.16.0.0.0dbru.zip
|
||||
RUN unzip -n instantclient-sqlplus-linux.x64-21.16.0.0.0dbru.zip
|
||||
|
||||
ENV PATH="/instantclient_21_16:${PATH}"
|
||||
ENV LD_LIBRARY_PATH="/instantclient_21_16"
|
||||
# workaround noble libaio SONAME issue -- see https://bugs.launchpad.net/ubuntu/+source/libaio/+bug/2067501
|
||||
RUN if [ -e /usr/lib/x86_64-linux-gnu/libaio.so.1t64 ] ; then ln -sf /usr/lib/x86_64-linux-gnu/libaio.so.1t64 /usr/lib/x86_64-linux-gnu/libaio.so.1 ; fi
|
||||
|
||||
# Avoid sqlcmd termination due to locale -- see https://github.com/Microsoft/mssql-docker/issues/163
|
||||
RUN echo "nb_NO.UTF-8 UTF-8" > /etc/locale.gen
|
||||
RUN echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen
|
||||
RUN locale-gen
|
||||
|
||||
RUN echo "alias python=python3" >> ~/.bash_aliases
|
||||
|
||||
# PDAL is not available in ubuntu 24.04
|
||||
# Install it from source
|
||||
# PDAL dependencies
|
||||
RUN apt-get update \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
ninja-build \
|
||||
libgdal-dev \
|
||||
libproj-dev
|
||||
# download PDAL and compile it
|
||||
RUN curl -L https://github.com/PDAL/PDAL/releases/download/${PDAL_VERSION}/PDAL-${PDAL_VERSION}-src.tar.gz --output PDAL-${PDAL_VERSION}-src.tar.gz \
|
||||
&& mkdir pdal \
|
||||
&& tar zxf PDAL-${PDAL_VERSION}-src.tar.gz -C pdal --strip-components=1 \
|
||||
&& rm -f PDAL-${PDAL_VERSION}-src.tar.gz \
|
||||
&& mkdir -p pdal/build \
|
||||
&& cd pdal/build \
|
||||
&& cmake -GNinja -DCMAKE_INSTALL_PREFIX=/usr/local -DWITH_TESTS=OFF .. \
|
||||
&& ninja \
|
||||
&& ninja install
|
||||
|
||||
FROM binary-for-oracle AS binary-only
|
||||
|
||||
RUN apt-get update \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
grass \
|
||||
iproute2 \
|
||||
postgresql-client \
|
||||
spawn-fcgi \
|
||||
&& pip3 install --break-system-packages \
|
||||
psycopg2 \
|
||||
&& apt-get clean
|
||||
|
||||
# HANA: client side
|
||||
# Install hdbsql tool
|
||||
RUN curl -j -k -L -H "Cookie: eula_3_2_agreed=tools.hana.ondemand.com/developer-license-3_2.txt" https://tools.hana.ondemand.com/additional/hanaclient-latest-linux-x64.tar.gz --output hanaclient-latest-linux-x64.tar.gz \
|
||||
&& tar -xvf hanaclient-latest-linux-x64.tar.gz \
|
||||
&& mkdir /usr/sap \
|
||||
&& ./client/hdbinst -a client --sapmnt=/usr/sap \
|
||||
&& rm -rf client \
|
||||
&& rm hanaclient*
|
||||
ENV PATH="/usr/sap/hdbclient:${PATH}"
|
||||
|
||||
# MSSQL: client side
|
||||
RUN curl -sSL -O https://packages.microsoft.com/config/ubuntu/$(grep VERSION_ID /etc/os-release | cut -d '"' -f 2)/packages-microsoft-prod.deb
|
||||
RUN dpkg -i packages-microsoft-prod.deb
|
||||
RUN rm packages-microsoft-prod.deb
|
||||
RUN apt-get update
|
||||
RUN ACCEPT_EULA=Y apt-get install -y --allow-unauthenticated msodbcsql18 mssql-tools18
|
||||
ENV PATH="/opt/mssql-tools18/bin:${PATH}"
|
||||
|
||||
FROM binary-only
|
||||
|
||||
RUN apt-get update \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
bison \
|
||||
ccache \
|
||||
clang \
|
||||
cmake \
|
||||
flex \
|
||||
grass-dev \
|
||||
libdraco-dev \
|
||||
libexiv2-dev \
|
||||
libexpat1-dev \
|
||||
libfcgi-dev \
|
||||
libgeos-dev \
|
||||
libgsl-dev \
|
||||
libpq-dev \
|
||||
libprotobuf-dev \
|
||||
libqca-qt5-2-dev \
|
||||
libqt5opengl5-dev \
|
||||
libqt5scintilla2-dev \
|
||||
libqt5svg5-dev \
|
||||
libqt5webkit5-dev \
|
||||
libqt5serialport5-dev \
|
||||
libqwt-qt5-dev \
|
||||
libspatialindex-dev \
|
||||
libspatialite-dev \
|
||||
libsqlite3-dev \
|
||||
libsqlite3-mod-spatialite \
|
||||
libzip-dev \
|
||||
libzstd-dev \
|
||||
protobuf-compiler \
|
||||
pyqt5-dev \
|
||||
pyqt5-dev-tools \
|
||||
pyqt5.qsci-dev \
|
||||
python3-all-dev \
|
||||
python3-dev \
|
||||
python3-sip-dev \
|
||||
qt3d5-dev \
|
||||
qt5keychain-dev \
|
||||
qtbase5-dev \
|
||||
qtdeclarative5-dev-tools \
|
||||
qtpositioning5-dev \
|
||||
qtmultimedia5-dev \
|
||||
qttools5-dev \
|
||||
qttools5-dev-tools \
|
||||
qtbase5-private-dev \
|
||||
opencl-headers \
|
||||
ocl-icd-opencl-dev \
|
||||
&& apt-get clean
|
||||
|
||||
ENV PATH="/usr/local/bin:${PATH}"
|
||||
|
||||
# environment variables shall be located in .docker/docker-variables.env
|
119
.docker/qgis3-qt6-build-deps.dockerfile
Normal file
119
.docker/qgis3-qt6-build-deps.dockerfile
Normal file
@ -0,0 +1,119 @@
|
||||
ARG DISTRO_VERSION=39
|
||||
|
||||
FROM fedora:${DISTRO_VERSION} AS binary-for-oracle
|
||||
LABEL org.opencontainers.image.authors="Matthias Kuhn <matthias@opengis.ch>"
|
||||
|
||||
RUN dnf -y --refresh install \
|
||||
bison \
|
||||
ccache \
|
||||
clang \
|
||||
clazy \
|
||||
curl \
|
||||
draco-devel \
|
||||
exiv2-devel \
|
||||
expat-devel \
|
||||
fcgi-devel \
|
||||
flex \
|
||||
fontconfig-devel \
|
||||
freetype-devel \
|
||||
git \
|
||||
gdal \
|
||||
gdal-devel \
|
||||
gdal-python-tools \
|
||||
geos-devel \
|
||||
gpsbabel \
|
||||
grass \
|
||||
grass-devel \
|
||||
gsl-devel \
|
||||
lcms2-devel \
|
||||
libjpeg-turbo-devel \
|
||||
libpq-devel \
|
||||
libspatialite-devel \
|
||||
libxml2-devel \
|
||||
libzip-devel \
|
||||
libzstd-devel \
|
||||
libaio \
|
||||
mold \
|
||||
netcdf-devel \
|
||||
ninja-build \
|
||||
ocl-icd-devel \
|
||||
openjpeg2-devel \
|
||||
PDAL \
|
||||
PDAL-libs \
|
||||
PDAL-devel \
|
||||
perl-YAML-Tiny \
|
||||
poppler-utils \
|
||||
proj-devel \
|
||||
protobuf-devel \
|
||||
protobuf-lite-devel \
|
||||
python3-devel \
|
||||
python3-mock \
|
||||
python3-oauthlib \
|
||||
python3-OWSLib \
|
||||
python3-pyqt6 \
|
||||
python3-pyqt6-devel \
|
||||
python3-qscintilla-qt6 \
|
||||
python3-qscintilla-qt6-devel \
|
||||
python3-termcolor \
|
||||
PyQt-builder \
|
||||
qca-qt6-devel \
|
||||
qpdf \
|
||||
qt6-qt3d-devel \
|
||||
qt6-qtbase-devel \
|
||||
qt6-qtbase-private-devel \
|
||||
qt6-qtdeclarative-devel \
|
||||
qt6-qttools-static \
|
||||
qt6-qtserialport-devel \
|
||||
qt6-qtsvg-devel \
|
||||
qt6-qtpositioning-devel \
|
||||
qt6-qtdeclarative-devel \
|
||||
qt6-qt5compat-devel \
|
||||
qt6-qtmultimedia-devel \
|
||||
qt6-qtwebengine-devel \
|
||||
qtkeychain-qt6-devel \
|
||||
qwt-qt6-devel \
|
||||
qscintilla-qt6-devel \
|
||||
sip6 \
|
||||
spatialindex-devel \
|
||||
sqlite-devel \
|
||||
unzip \
|
||||
unixODBC-devel \
|
||||
xorg-x11-server-Xvfb \
|
||||
util-linux \
|
||||
wget \
|
||||
openssl-devel \
|
||||
libsecret-devel \
|
||||
make \
|
||||
automake \
|
||||
gcc \
|
||||
gcc-c++ \
|
||||
kernel-devel \
|
||||
ninja-build \
|
||||
patch \
|
||||
dos2unix
|
||||
|
||||
|
||||
# Oracle : client side
|
||||
RUN curl https://download.oracle.com/otn_software/linux/instantclient/2116000/instantclient-basic-linux.x64-21.16.0.0.0dbru.zip > instantclient-basic-linux.x64-21.16.0.0.0dbru.zip
|
||||
RUN curl https://download.oracle.com/otn_software/linux/instantclient/2116000/instantclient-sdk-linux.x64-21.16.0.0.0dbru.zip > instantclient-sdk-linux.x64-21.16.0.0.0dbru.zip
|
||||
RUN curl https://download.oracle.com/otn_software/linux/instantclient/2116000/instantclient-sqlplus-linux.x64-21.16.0.0.0dbru.zip > instantclient-sqlplus-linux.x64-21.16.0.0.0dbru.zip
|
||||
|
||||
RUN unzip -n instantclient-basic-linux.x64-21.16.0.0.0dbru.zip
|
||||
RUN unzip -n instantclient-sdk-linux.x64-21.16.0.0.0dbru.zip
|
||||
RUN unzip -n instantclient-sqlplus-linux.x64-21.16.0.0.0dbru.zip
|
||||
|
||||
ENV PATH="/instantclient_21_16:${PATH}"
|
||||
ENV LD_LIBRARY_PATH="/instantclient_21_16"
|
||||
|
||||
ENV LANG=C.UTF-8
|
||||
|
||||
FROM binary-for-oracle AS binary-only
|
||||
|
||||
RUN dnf -y install \
|
||||
python3-gdal \
|
||||
python3-nose2 \
|
||||
python3-psycopg2 \
|
||||
python3-pyyaml \
|
||||
python3-shapely
|
||||
|
||||
FROM binary-only
|
7
.docker/qgis_resources/requirements.txt
Normal file
7
.docker/qgis_resources/requirements.txt
Normal file
@ -0,0 +1,7 @@
|
||||
pep8
|
||||
pexpect
|
||||
capturer
|
||||
sphinx
|
||||
requests
|
||||
future
|
||||
six
|
@ -0,0 +1,4 @@
|
||||
; Supervisor config file for Xvfb
|
||||
|
||||
[program:Xvfb]
|
||||
command=/usr/bin/Xvfb :99 -screen 0 1024x768x24 -ac +extension GLX +render -noreset -nolisten tcp
|
13
.docker/qgis_resources/supervisor/supervisord.conf
Normal file
13
.docker/qgis_resources/supervisor/supervisord.conf
Normal file
@ -0,0 +1,13 @@
|
||||
; Supervisor config file.
|
||||
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
logfile=/var/log/supervisor/supervisord.log
|
||||
logfile_maxbytes=50MB
|
||||
logfile_backups=10
|
||||
loglevel=info
|
||||
pidfile=/var/run/supervisord.pid
|
||||
childlogdir=/var/log
|
||||
|
||||
[include]
|
||||
files = /etc/supervisor/supervisor.d/*.conf
|
63
.docker/qgis_resources/test_runner/qgis_setup.sh
Normal file
63
.docker/qgis_resources/test_runner/qgis_setup.sh
Normal file
@ -0,0 +1,63 @@
|
||||
#!/bin/bash
|
||||
# Setup QGIS for the automated tests
|
||||
# This is normally called from Travis or rundockertests.sh
|
||||
# before running the tests for a particular plugin
|
||||
#
|
||||
# Note: on QGIS3 assumes the default profile for root user
|
||||
#
|
||||
# - create the folders
|
||||
# - install startup.py monkey patches
|
||||
# - disable tips
|
||||
# - enable the plugin (optionally)
|
||||
|
||||
PLUGIN_NAME=$1
|
||||
CONF_MASTER_FOLDER="/root/.local/share/QGIS/QGIS3/profiles/default/QGIS/"
|
||||
CONF_MASTER_FILE="${CONF_MASTER_FOLDER}/QGIS3.ini"
|
||||
|
||||
QGIS_MASTER_FOLDER="/root/.local/share/QGIS/QGIS3/profiles/default"
|
||||
PLUGIN_MASTER_FOLDER="${QGIS_MASTER_FOLDER}/python/plugins"
|
||||
|
||||
STARTUP_MASTER_FOLDER="/root/.local/share/QGIS/QGIS3/"
|
||||
|
||||
# Creates the config file
|
||||
mkdir -p $CONF_MASTER_FOLDER
|
||||
if [ -e "$CONF_MASTER_FILE" ]; then
|
||||
rm -f $CONF_MASTER_FILE
|
||||
fi
|
||||
touch $CONF_MASTER_FILE
|
||||
|
||||
# Creates plugin folder
|
||||
mkdir -p $PLUGIN_MASTER_FOLDER
|
||||
mkdir -p $STARTUP_MASTER_FOLDER
|
||||
|
||||
# Install the monkey patches to prevent modal stacktrace on python errors
|
||||
cp /usr/bin/qgis_startup.py ${STARTUP_MASTER_FOLDER}/startup.py
|
||||
|
||||
# Disable tips
|
||||
printf "[qgis]\n" >> $CONF_MASTER_FILE
|
||||
SHOW_TIPS=$(qgis --help 2>&1 | head -2 | grep 'QGIS - ' | perl -npe 'chomp; s/QGIS - (\d+)\.(\d+).*/showTips\1\2=false/')
|
||||
printf "%s\n\n" "$SHOW_TIPS" >> $CONF_MASTER_FILE
|
||||
|
||||
if [[ -n "$PLUGIN_NAME" ]]; then
|
||||
# Enable plugin
|
||||
printf '[PythonPlugins]\n' >> $CONF_MASTER_FILE
|
||||
printf "%s=true\n\n" "$PLUGIN_NAME" >> $CONF_MASTER_FILE
|
||||
# Install the plugin
|
||||
if [ ! -d "${PLUGIN_MASTER_FOLDER}/${PLUGIN_NAME}" ]; then
|
||||
plugin_dir="/tests_directory/${PLUGIN_NAME}"
|
||||
if [ ! -d "${plugin_dir}" ]; then
|
||||
echo "ERROR: ${plugin_dir} does not exist" >&2
|
||||
exit 1
|
||||
fi
|
||||
ln -s "${plugin_dir}" "${PLUGIN_MASTER_FOLDER}"
|
||||
echo "Plugin master folder linked in ${PLUGIN_MASTER_FOLDER}/${PLUGIN_NAME}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Disable firstRunVersionFlag for master
|
||||
echo "
|
||||
[migration]
|
||||
fileVersion=2
|
||||
firstRunVersionFlag=30500
|
||||
settings=true
|
||||
" >> $CONF_MASTER_FILE
|
29
.docker/qgis_resources/test_runner/qgis_startup.py
Normal file
29
.docker/qgis_resources/test_runner/qgis_startup.py
Normal file
@ -0,0 +1,29 @@
|
||||
"""
|
||||
Disable QGIS modal error dialog.
|
||||
|
||||
This script is meant to be run automatically when QGIS starts.
|
||||
Is should be renamed to `startup.py` and placed into
|
||||
~/.qgis3/python/startup.py
|
||||
|
||||
"""
|
||||
|
||||
import traceback
|
||||
|
||||
from qgis import utils
|
||||
from qgis.core import Qgis
|
||||
|
||||
|
||||
def _showException(type, value, tb, msg, messagebar=False, level=Qgis.Warning):
|
||||
print(msg)
|
||||
logmessage = ""
|
||||
for s in traceback.format_exception(type, value, tb):
|
||||
logmessage += s.decode("utf-8", "replace") if hasattr(s, "decode") else s
|
||||
print(logmessage)
|
||||
|
||||
|
||||
def _open_stack_dialog(type, value, tb, msg, pop_error=True):
|
||||
print(msg)
|
||||
|
||||
|
||||
utils.showException = _showException
|
||||
utils.open_stack_dialog = _open_stack_dialog
|
185
.docker/qgis_resources/test_runner/qgis_testrunner.py
Executable file
185
.docker/qgis_resources/test_runner/qgis_testrunner.py
Executable file
@ -0,0 +1,185 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
***************************************************************************
|
||||
Launches a unit test inside QGIS and exit the application.
|
||||
|
||||
Arguments:
|
||||
|
||||
accepts a single argument with the package name in python dotted notation,
|
||||
the program tries first to load the module and launch the `run_all`
|
||||
function of the module, if that fails it considers the last part of
|
||||
the dotted path to be the function name and the previous part to be the
|
||||
module.
|
||||
|
||||
Extra options for QGIS command line can be passed in the env var
|
||||
QGIS_EXTRA_OPTIONS
|
||||
|
||||
Example run:
|
||||
|
||||
# Will load geoserverexplorer.test.catalogtests and run `run_all`
|
||||
QGIS_EXTRA_OPTIONS='--optionspath .' \
|
||||
GSHOSTNAME=localhost \
|
||||
python qgis_testrunner.py geoserverexplorer.test.catalogtests
|
||||
|
||||
|
||||
GSHOSTNAME=localhost \
|
||||
python qgis_testrunner.py geoserverexplorer.test.catalogtests.run_my
|
||||
|
||||
|
||||
---------------------
|
||||
Date : May 2016
|
||||
Copyright : (C) 2016 by Alessandro Pasotti
|
||||
Email : apasotti at boundlessgeo dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************
|
||||
"""
|
||||
|
||||
__author__ = "Alessandro Pasotti"
|
||||
__date__ = "May 2016"
|
||||
|
||||
import importlib
|
||||
import os
|
||||
import re
|
||||
import signal
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
from shlex import quote
|
||||
|
||||
from pexpect import run
|
||||
from qgis.utils import iface
|
||||
|
||||
|
||||
def eprint(text):
|
||||
sys.__stderr__.write(text + "\n")
|
||||
|
||||
|
||||
def __get_test_function(test_module_name):
|
||||
"""
|
||||
Load the test module and return the test function
|
||||
"""
|
||||
print("QGIS Test Runner - Trying to import %s" % test_module_name)
|
||||
try:
|
||||
test_module = importlib.import_module(test_module_name)
|
||||
function_name = "run_all"
|
||||
except ImportError as e:
|
||||
# traceback.print_exc(file=sys.stdout)
|
||||
# Strip latest name
|
||||
pos = test_module_name.rfind(".")
|
||||
if pos <= 0:
|
||||
raise e
|
||||
test_module_name, function_name = (
|
||||
test_module_name[:pos],
|
||||
test_module_name[pos + 1 :],
|
||||
)
|
||||
print("QGIS Test Runner - Trying to import %s" % test_module_name)
|
||||
sys.stdout.flush()
|
||||
try:
|
||||
test_module = importlib.import_module(test_module_name)
|
||||
except ImportError as e:
|
||||
# traceback.print_exc(file=sys.stdout)
|
||||
raise e
|
||||
return getattr(test_module, function_name, None)
|
||||
|
||||
|
||||
if iface is None:
|
||||
"""
|
||||
Launch QGIS and passes itself as an init script
|
||||
"""
|
||||
sys.path.append(os.getcwd())
|
||||
test_module_name = sys.argv[-1]
|
||||
if __get_test_function(test_module_name) is None:
|
||||
print(
|
||||
"QGIS Test Runner - [ERROR] cannot load test function from %s"
|
||||
% test_module_name
|
||||
)
|
||||
sys.exit(1)
|
||||
try:
|
||||
me = __file__
|
||||
except NameError:
|
||||
me = sys.argv[0]
|
||||
os.environ["QGIS_DEBUG"] = "1"
|
||||
args = [
|
||||
"qgis",
|
||||
os.environ.get("QGIS_EXTRA_OPTIONS", ""),
|
||||
"--nologo",
|
||||
"--noversioncheck",
|
||||
"--code",
|
||||
me,
|
||||
test_module_name, # Must be the last one!
|
||||
]
|
||||
command_line = " ".join(args)
|
||||
print("QGIS Test Runner - launching QGIS as %s ..." % command_line)
|
||||
out, returncode = run("sh -c " + quote(command_line), withexitstatus=1)
|
||||
if isinstance(out, bytes):
|
||||
out = out.decode("utf-8")
|
||||
assert returncode is not None
|
||||
print("QGIS Test Runner - QGIS exited.")
|
||||
ok = (
|
||||
out.find("(failures=") < 0
|
||||
and len(re.findall(r"Ran \d+ tests in\s", out, re.MULTILINE)) > 0
|
||||
)
|
||||
print("=" * 60)
|
||||
if not ok:
|
||||
print(out)
|
||||
else:
|
||||
eprint(out)
|
||||
if len(out) == 0:
|
||||
print("QGIS Test Runner - [WARNING] subprocess returned no output")
|
||||
print("=" * 60)
|
||||
|
||||
print(
|
||||
"QGIS Test Runner - {} bytes returned and finished with exit code: {}".format(
|
||||
len(out), 0 if ok else 1
|
||||
)
|
||||
)
|
||||
sys.exit(0 if ok else 1)
|
||||
|
||||
else: # We are inside QGIS!
|
||||
# Start as soon as the initializationCompleted signal is fired
|
||||
from qgis.core import QgsApplication, QgsProject, QgsProjectBadLayerHandler
|
||||
from qgis.PyQt.QtCore import QDir
|
||||
from qgis.utils import iface
|
||||
|
||||
class QgsProjectBadLayerDefaultHandler(QgsProjectBadLayerHandler):
|
||||
def handleBadLayers(self, layers, dom):
|
||||
pass
|
||||
|
||||
# Monkey patch QGIS Python console
|
||||
from console.console_output import writeOut
|
||||
|
||||
def _write(self, m):
|
||||
sys.__stdout__.write(m)
|
||||
|
||||
writeOut.write = _write
|
||||
|
||||
# Add current working dir to the python path
|
||||
sys.path.append(QDir.current().path())
|
||||
|
||||
def __run_test():
|
||||
"""
|
||||
Run the test specified as last argument in the command line.
|
||||
"""
|
||||
# Disable modal handler for bad layers
|
||||
QgsProject.instance().setBadLayerHandler(QgsProjectBadLayerDefaultHandler())
|
||||
eprint("QGIS Test Runner Inside - starting the tests ...")
|
||||
try:
|
||||
test_module_name = QgsApplication.instance().arguments()[-1]
|
||||
function_name = __get_test_function(test_module_name)
|
||||
eprint("QGIS Test Runner Inside - executing function %s" % function_name)
|
||||
function_name()
|
||||
except Exception as e:
|
||||
eprint("QGIS Test Runner Inside - [FAILED] Exception: %s" % e)
|
||||
# Print tb
|
||||
traceback.print_exc(file=sys.stdout)
|
||||
app = QgsApplication.instance()
|
||||
os.kill(app.applicationPid(), signal.SIGTERM)
|
||||
|
||||
iface.initializationCompleted.connect(__run_test)
|
43
.docker/qgis_resources/test_runner/qgis_testrunner.sh
Executable file
43
.docker/qgis_resources/test_runner/qgis_testrunner.sh
Executable file
@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
# Run a python test inside QGIS
|
||||
# Note: the test module and function are specified in dotted notation
|
||||
# for example, to run the test function run_all (which is the default anyway)
|
||||
# $ qgis_testrunner.sh tests_folder.test_module.run_all
|
||||
# tests_folder must be in PYTHONPATH (plugins main folders are automatically added to path)
|
||||
|
||||
### Turn on debug mode ###
|
||||
#set -x
|
||||
|
||||
TEST_NAME=$1
|
||||
|
||||
TEST_RUNNER_PATH=${TEST_RUNNER_PATH:-/usr/bin/qgis_testrunner.py}
|
||||
QGIS_BUILD_PATH=${QGIS_BUILD_PATH:-qgis}
|
||||
|
||||
LOGFILE=/tmp/qgis_testrunner_$$
|
||||
|
||||
echo "Running test $1 ..."
|
||||
QGIS_TEST_MODULE=${TEST_NAME} unbuffer ${QGIS_BUILD_PATH} \
|
||||
--version-migration --nologo --code \
|
||||
${TEST_RUNNER_PATH} "$TEST_NAME" \
|
||||
2>/dev/null | \
|
||||
tee ${LOGFILE}
|
||||
|
||||
# NOTE: EXIT_CODE will always be 0 if "tee" works,
|
||||
# we could `set -o pipefail` to change this
|
||||
EXIT_CODE="$?"
|
||||
OUTPUT=$(cat $LOGFILE) # quick hack to avoid changing too many lines
|
||||
if [ -z "$OUTPUT" ]; then
|
||||
echo "ERROR: no output from the test runner! (exit code: ${EXIT_CODE})"
|
||||
exit 1
|
||||
fi
|
||||
echo "$OUTPUT" | grep -q 'FAILED'
|
||||
IS_FAILED="$?"
|
||||
echo "$OUTPUT" | grep -q 'OK' && echo "$OUTPUT" | grep -q 'Ran'
|
||||
IS_PASSED="$?"
|
||||
echo "$OUTPUT" | grep "QGIS died on signal"
|
||||
IS_DEAD="$?"
|
||||
echo "Finished running test $1 (codes: IS_DEAD=$IS_DEAD IS_FAILED=$IS_FAILED IS_PASSED=$IS_PASSED)."
|
||||
if [ "$IS_PASSED" -eq "0" ] && [ "$IS_FAILED" -eq "1" ] && [ "$IS_DEAD" -eq "1" ]; then
|
||||
exit 0;
|
||||
fi
|
||||
exit 1
|
21
.docker/webdav/nginx.conf
Normal file
21
.docker/webdav/nginx.conf
Normal file
@ -0,0 +1,21 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name localhost;
|
||||
|
||||
location /webdav_tests {
|
||||
|
||||
auth_basic realm_name;
|
||||
auth_basic_user_file /etc/nginx/.passwords.list;
|
||||
|
||||
dav_methods PUT DELETE MKCOL COPY MOVE;
|
||||
#dav_ext_methods PROPFIND OPTIONS;
|
||||
dav_access user:rw group:rw all:r;
|
||||
|
||||
autoindex on;
|
||||
|
||||
client_max_body_size 0;
|
||||
create_full_put_path on;
|
||||
root /tmp/webdav_tests_root;
|
||||
}
|
||||
}
|
1
.docker/webdav/passwords.list
Normal file
1
.docker/webdav/passwords.list
Normal file
@ -0,0 +1 @@
|
||||
qgis:$apr1$cxID/nB1$3tG4J0FkYvEHyWAB.yqjo.
|
4
.dockerignore
Normal file
4
.dockerignore
Normal file
@ -0,0 +1,4 @@
|
||||
/.ci
|
||||
/.git
|
||||
/.github
|
||||
build*
|
17
.editorconfig
Normal file
17
.editorconfig
Normal file
@ -0,0 +1,17 @@
|
||||
# See http://editorconfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# every file needs these
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
# python scripts have 4 spaces indent
|
||||
[*.py]
|
||||
indent_size = 4
|
4
.git-blame-ignore-revs
Normal file
4
.git-blame-ignore-revs
Normal file
@ -0,0 +1,4 @@
|
||||
0f032e5f2d78d0d0ba2edb4a20c4853e77ec0fc4 # python formatting after pre-commit introduction
|
||||
33ea41a100e8eea891c1d9d95fe34e346c3e71d1 # clang-format on non sipified files
|
||||
00fecc29bbe2e295d75c2dad4b9090f7afba739a # clang-format src/analysis
|
||||
3a4f8bcdad4f843d7217116ac1cb94b6b6c3fb8b # clang-format src/3d + server
|
3
.gitattributes
vendored
Normal file
3
.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
*.sip export-subst
|
||||
*.py export-subst
|
||||
tests/testdata/auth_system/certs_keys/donald_key_DSA_crlf.pem text eol=crlf
|
72
.github/ISSUE_TEMPLATE/10_bug_report.yml
vendored
Normal file
72
.github/ISSUE_TEMPLATE/10_bug_report.yml
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
name: Bug/Crash report but not related to a third party plugin, read below for plugins
|
||||
description: Create a bug report to help us improve QGIS.
|
||||
labels:
|
||||
- 'Bug'
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report correctly.
|
||||
|
||||
Please report only issues related to the QGIS application.
|
||||
|
||||
If the issue is related to a plugin, you should file the issue in the plugin code repository.
|
||||
You can find the URL in the QGIS Plugin Manager.
|
||||
|
||||
- type: textarea
|
||||
id: what
|
||||
attributes:
|
||||
label: What is the bug or the crash?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: steps
|
||||
attributes:
|
||||
label: Steps to reproduce the issue
|
||||
description: |
|
||||
Steps, sample datasets and qgis project file to reproduce the behavior. Screencasts or screenshots are more than welcome, you can drag&drop them in the text box.
|
||||
1. Go to '...'
|
||||
2. Click on '...'
|
||||
3. Scroll down to '...'
|
||||
4. See error
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: about-info
|
||||
attributes:
|
||||
label: Versions
|
||||
description: |
|
||||
In the QGIS Help menu -> About, click on the "Copy to Clipboard" button, then paste here.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
id: qgis-version
|
||||
attributes:
|
||||
label: Supported QGIS version
|
||||
description: |
|
||||
Each month, there is a new release of QGIS. According to the release schedule, you should at least be running a supported QGIS version.
|
||||
You can check the release schedule https://www.qgis.org/en/site/getinvolved/development/roadmap.html#release-schedule
|
||||
options:
|
||||
- label: I'm running a supported QGIS version according to [the roadmap](https://www.qgis.org/en/site/getinvolved/development/roadmap.html#release-schedule).
|
||||
|
||||
- type: checkboxes
|
||||
id: new-profile
|
||||
attributes:
|
||||
label: New profile
|
||||
description: |
|
||||
Did you try with a new QGIS profile? Some issues or crashes might be related to plugins or user configuration.
|
||||
You must try with a new profile to check if the issue remains.
|
||||
Read this link how to create a new profile
|
||||
https://docs.qgis.org/latest/en/docs/user_manual/introduction/qgis_configuration.html#working-with-user-profiles
|
||||
options:
|
||||
- label: I tried with a new [QGIS profile](https://docs.qgis.org/latest/en/docs/user_manual/introduction/qgis_configuration.html#working-with-user-profiles)
|
||||
|
||||
- type: textarea
|
||||
id: additional-context
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: |
|
||||
Add any other context about the problem here.
|
25
.github/ISSUE_TEMPLATE/15_feature_request.yml
vendored
Normal file
25
.github/ISSUE_TEMPLATE/15_feature_request.yml
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
name: Feature request
|
||||
description: Suggest a feature idea for QGIS.
|
||||
labels:
|
||||
- 'Feature Request'
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this feature request correctly.
|
||||
|
||||
- type: textarea
|
||||
id: what
|
||||
attributes:
|
||||
label: Feature description
|
||||
description: A clear and concise description of what you want to happen. Ex. QGIS would rock even more if [...]
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: Additional
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: |
|
||||
Add any other context or screenshots about the feature request here. Open source is community driven, please consider a way to support this work either by hiring developers, supporting the QGIS project, find someone to submit a pull request.
|
||||
If the change required is important, you should consider writing a [QGIS Enhancement Proposal](https://github.com/qgis/QGIS-Enhancement-Proposals/issues) (QEP) or hiring someone to, and announce your work on the lists.
|
19
.github/ISSUE_TEMPLATE/20_documentation.yml
vendored
Normal file
19
.github/ISSUE_TEMPLATE/20_documentation.yml
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
name: API documentation (C++ or PyQGIS)
|
||||
description: An issue about the C++ or PyQGIS documentation
|
||||
labels:
|
||||
- 'Documentation'
|
||||
- 'API'
|
||||
- 'PyQGIS'
|
||||
body:
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Report only an issue related to the C++ or PyQGIS documentation
|
||||
|
||||
- type: textarea
|
||||
id: what
|
||||
attributes:
|
||||
label: What is the issue about the documentation?
|
||||
validations:
|
||||
required: true
|
21
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
21
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
blank_issues_enabled: false
|
||||
|
||||
contact_links:
|
||||
- name: Documentation (desktop and server)
|
||||
url: https://github.com/qgis/QGIS-Documentation/issues
|
||||
about: Suggest improvements or report errors regarding https://docs.qgis.org
|
||||
|
||||
- name: Question
|
||||
url: https://gis.stackexchange.com/
|
||||
about: >
|
||||
Questions should go to the qgis-user mailing list at https://lists.osgeo.org/mailman/listinfo/qgis-user
|
||||
or other support forums such as https://gis.stackexchange.com/.
|
||||
GitHub issues are for bug reports and suggestions for new features.
|
||||
|
||||
- name: QGIS plugin issue
|
||||
# There must be a link to make this option valid for GitHub
|
||||
url: https://plugins.qgis.org
|
||||
about: >
|
||||
If the issue concerns a third party plugin (downloaded with the plugin manager) then it can't be fixed
|
||||
by the QGIS core team. Please raise your issue in the dedicated bug tracker for that specific plugin
|
||||
(as listed in the plugin's description)
|
33
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
33
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
## Description
|
||||
|
||||
[Replace this with some text explaining the rationale and details about this pull request]
|
||||
|
||||
<!--
|
||||
BEFORE HITTING SUBMIT -- Please BUILD AND TEST your changes thoroughly. This is YOUR responsibility! Do NOT rely on the QGIS code maintainers to do this for you!!
|
||||
|
||||
IMPORTANT NOTES FOR FIRST TIME CONTRIBUTORS
|
||||
===========================================
|
||||
|
||||
Congratulations, you are about to make a pull request to QGIS! To make this as easy and pleasurable for everyone, please take the time to read these lines before opening the pull request.
|
||||
|
||||
Include a few sentences describing the overall goals for this pull request (PR). If applicable also add screenshots or - even better - screencasts.
|
||||
Include both: *what* you changed and *why* you changed it.
|
||||
|
||||
If this is a pull request that adds new functionality which needs documentation, give an especially detailed explanation.
|
||||
In this case, start with a short abstract and then write some text that can be copied 1:1 to the documentation in the best case.
|
||||
|
||||
Also mention if you think this PR needs to be backported. And list relevant or fixed issues.
|
||||
|
||||
------------------------
|
||||
|
||||
Reviewing is a process done by project maintainers, mostly on a volunteer basis. We try to keep the overhead as small as possible and appreciate if you help us to do so by checking the following list.
|
||||
Feel free to ask in a comment if you have troubles with any of them.
|
||||
|
||||
- Commit messages are descriptive and explain the rationale for changes.
|
||||
|
||||
- Commits which fix bugs include `Fixes #11111` at the bottom of the commit message. If this is your first pull request and you forgot to do this, write the same statement into this text field with the pull request description.
|
||||
|
||||
- New unit tests have been added for relevant changes
|
||||
|
||||
- you have read the QGIS Developer Guide (https://docs.qgis.org/testing/en/docs/developers_guide/index.html) and your PR complies with its QGIS Coding Standards
|
||||
-->
|
34
.github/actions/get-workflow-artifact-ids/action.yml
vendored
Normal file
34
.github/actions/get-workflow-artifact-ids/action.yml
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
name: 'Get Workflow Artifact IDs'
|
||||
description: 'Generates consistent artifact IDs and names based on workflow trigger'
|
||||
|
||||
outputs:
|
||||
filename:
|
||||
description: 'Filename to use for artifacts (e.g. pr123)'
|
||||
value: ${{ steps.generate-ids.outputs.filename }}
|
||||
display-name:
|
||||
description: 'Human readable name (e.g. PR123)'
|
||||
value: ${{ steps.generate-ids.outputs.display_name }}
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- id: generate-ids
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" = "pull_request" ]; then
|
||||
ID="pr${{ github.event.pull_request.number }}"
|
||||
DISPLAY_ID="PR${{ github.event.pull_request.number }}"
|
||||
elif [[ "${{ github.ref }}" == refs/tags/* ]]; then
|
||||
TAG=${GITHUB_REF#refs/tags/}
|
||||
ID="$TAG"
|
||||
DISPLAY_ID="$TAG"
|
||||
else
|
||||
SHORT_SHA=$(echo ${{ github.sha }} | cut -c1-7)
|
||||
BRANCH_NAME=${GITHUB_REF#refs/heads/}
|
||||
ID="$BRANCH_NAME-$SHORT_SHA"
|
||||
DISPLAY_ID="$BRANCH_NAME-$SHORT_SHA"
|
||||
fi
|
||||
|
||||
# Set outputs
|
||||
echo "filename=$ID" >> $GITHUB_OUTPUT
|
||||
echo "display_name=$DISPLAY_ID" >> $GITHUB_OUTPUT
|
54
.github/actions/post_sticky_comment/action.yml
vendored
Normal file
54
.github/actions/post_sticky_comment/action.yml
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
name: Post Sticky Comment
|
||||
description: Post a sticky comment
|
||||
inputs:
|
||||
marker:
|
||||
description: Unique marker
|
||||
required: true
|
||||
type: string
|
||||
body:
|
||||
description: Body
|
||||
required: true
|
||||
type: string
|
||||
pr:
|
||||
description: Pull Request Number
|
||||
required: true
|
||||
type: string
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Create metadata
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
BODY: ${{ inputs.body }}
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
|
||||
try {
|
||||
// Get inputs from the GitHub Action
|
||||
const marker = "${{ inputs.marker }}";
|
||||
const body = process.env.BODY; // Transfer input via env variable as it's not possible to access it directly https://github.com/actions/github-script/issues/56#issuecomment-642188313
|
||||
const pr = ${{ inputs.pr }};
|
||||
|
||||
// Create the content of the JSON file
|
||||
const content = JSON.stringify({
|
||||
marker: marker,
|
||||
body: body,
|
||||
pr_number: pr
|
||||
}, null, 2);
|
||||
console.debug(content)
|
||||
|
||||
fs.writeFileSync('comment-${{ github.job }}.json', content);
|
||||
|
||||
console.log('comment.json file has been written successfully.');
|
||||
} catch (error) {
|
||||
core.setFailed(`Action failed with error: ${error}`);
|
||||
}
|
||||
|
||||
- name: 📤 Upload data
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: comment_artifacts-${{ github.job }}
|
||||
path: |
|
||||
comment-${{ github.job }}.json
|
31
.github/actions/setup-vcpkg/action.yml
vendored
Normal file
31
.github/actions/setup-vcpkg/action.yml
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
name: Setup Vcpkg
|
||||
description: Initialize vcpkg tool, does not checkout the registry
|
||||
# TODO, set VCPKG_BASE_VERSION based on this
|
||||
# inputs:
|
||||
# vcpkg-version:
|
||||
# description: Enter vcpkg version tag or stable or latest
|
||||
# required: false
|
||||
# default: latest
|
||||
# type: string
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Setup vcpkg
|
||||
if: runner.os != 'Windows'
|
||||
shell: bash
|
||||
run: |
|
||||
export VCPKG_ROOT=$HOME/.vcpkg
|
||||
wget https://aka.ms/vcpkg-init.sh -O /tmp/vcpkg-init.sh
|
||||
. /tmp/vcpkg-init.sh
|
||||
echo "VCPKG_ROOT=$VCPKG_ROOT" >> $GITHUB_ENV
|
||||
echo "$VCPKG_ROOT" >> $GITHUB_PATH
|
||||
|
||||
- name: Setup vcpkg
|
||||
if: runner.os == 'Windows'
|
||||
shell: powershell
|
||||
run: |
|
||||
$env:VCPKG_ROOT = "C:/.vcpkg"
|
||||
iex (iwr -useb https://aka.ms/vcpkg-init.ps1)
|
||||
echo "VCPKG_ROOT=$env:VCPKG_ROOT" >> $env:GITHUB_ENV
|
||||
echo "$env:VCPKG_ROOT" >> $env:GITHUB_PATH
|
54
.github/actions/vcpkg_update_report/action.yml
vendored
Normal file
54
.github/actions/vcpkg_update_report/action.yml
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
name: Compare vcpkg install changes
|
||||
description: Compares vcpkg install outputs between the base and head refs on pull requests and generates a report.
|
||||
|
||||
inputs:
|
||||
vcpkg-manifest-dir:
|
||||
description: 'Directory containing the vcpkg.json manifest'
|
||||
required: true
|
||||
default: '.'
|
||||
type: string
|
||||
triplet:
|
||||
description: 'Triplet to use for vcpkg installation'
|
||||
required: true
|
||||
default: 'x64-linux'
|
||||
type: string
|
||||
features:
|
||||
description: 'Comma separated list of features'
|
||||
required: false
|
||||
default: ''
|
||||
type: string
|
||||
|
||||
outputs:
|
||||
report:
|
||||
description: 'The report of added and removed packages after vcpkg installation comparison'
|
||||
value: ${{ steps.compare.outputs.report }}
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
# Run vcpkg install --dry-run on the head ref
|
||||
- name: Run vcpkg install (HEAD)
|
||||
shell: bash
|
||||
run: |
|
||||
vcpkg install --dry-run --triplet ${{ inputs.triplet }} --x-manifest-root=${{ inputs.vcpkg-manifest-dir }} $(awk -v FS=',' '{for(i=1; i<=NF; i++) printf "--x-feature=%s ", $i}' <<< "${{ inputs.features }}") --allow-unsupported > /tmp/vcpkg-head-output.txt
|
||||
|
||||
# Run vcpkg install --dry-run on the base ref
|
||||
- name: Run vcpkg install (BASE)
|
||||
shell: bash
|
||||
run: |
|
||||
git worktree add .base-ref ${{ github.event.pull_request.base.sha }}
|
||||
vcpkg install --dry-run --triplet ${{ inputs.triplet }} --x-manifest-root=.base-ref/${{ inputs.vcpkg-manifest-dir }} $(awk -v FS=',' '{for(i=1; i<=NF; i++) printf "--x-feature=%s ", $i}' <<< "${{ inputs.features }}") --allow-unsupported > /tmp/vcpkg-base-output.txt
|
||||
|
||||
|
||||
# Compare the outputs and generate a report
|
||||
- name: Compare vcpkg outputs
|
||||
shell: bash
|
||||
id: compare
|
||||
run: |
|
||||
python3 ${GITHUB_ACTION_PATH}/vcpkg-diff.py > /tmp/vcpkg-report.txt
|
||||
cat /tmp/vcpkg-report.txt
|
||||
{
|
||||
echo 'report<<EOF'
|
||||
cat /tmp/vcpkg-report.txt
|
||||
echo EOF
|
||||
} >> "$GITHUB_OUTPUT"
|
101
.github/actions/vcpkg_update_report/vcpkg-diff.py
vendored
Normal file
101
.github/actions/vcpkg_update_report/vcpkg-diff.py
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
import re
|
||||
|
||||
|
||||
def extract_packages(data):
|
||||
"""
|
||||
Extract package name, triplet, version, and features information from the file content.
|
||||
"""
|
||||
packages = {}
|
||||
lines = data.strip().split("\n")
|
||||
for line in lines:
|
||||
# Regex to match the package format and capture features inside brackets
|
||||
match = re.match(
|
||||
r"\s*\*?\s+([^\[\]:]+)(?:\[(.*?)\])?:([^\[\]@]+)@([^\s]+)\s+--", line
|
||||
)
|
||||
if match:
|
||||
package_name = match.group(1)
|
||||
features = match.group(2) if match.group(2) else ""
|
||||
triplet = match.group(3)
|
||||
version = match.group(4)
|
||||
features_list = (
|
||||
[feature.strip() for feature in features.split(",")] if features else []
|
||||
)
|
||||
packages[package_name] = (triplet, version, features_list)
|
||||
return packages
|
||||
|
||||
|
||||
def compare_features(features1, features2):
|
||||
"""
|
||||
Compare two feature lists and return the differences.
|
||||
"""
|
||||
added_features = set(features2) - set(features1)
|
||||
removed_features = set(features1) - set(features2)
|
||||
return added_features, removed_features
|
||||
|
||||
|
||||
def generate_report(file1_content, file2_content):
|
||||
# Extract package information from both files
|
||||
file1_packages = extract_packages(file1_content)
|
||||
file2_packages = extract_packages(file2_content)
|
||||
|
||||
added = []
|
||||
removed = []
|
||||
updated = []
|
||||
|
||||
# Identify removed and updated packages
|
||||
for pkg in file1_packages:
|
||||
if pkg not in file2_packages:
|
||||
removed.append(pkg)
|
||||
else:
|
||||
# Compare version and features
|
||||
triplet1, version1, features1 = file1_packages[pkg]
|
||||
triplet2, version2, features2 = file2_packages[pkg]
|
||||
updated_parts = []
|
||||
if version1 != version2 or triplet1 != triplet2:
|
||||
updated_parts.append(f"{version1} -> {version2}")
|
||||
added_features, removed_features = compare_features(features1, features2)
|
||||
if added_features:
|
||||
updated_parts.append("+" + ", ".join(added_features))
|
||||
if removed_features:
|
||||
updated_parts.append("-" + ", ".join(removed_features))
|
||||
if updated_parts:
|
||||
updated.append(f"{pkg}: " + " ".join(updated_parts))
|
||||
|
||||
# Identify added packages
|
||||
for pkg in file2_packages:
|
||||
if pkg not in file1_packages:
|
||||
added.append(pkg)
|
||||
|
||||
# Print the report
|
||||
if added:
|
||||
print("**Added packages:**")
|
||||
for pkg in added:
|
||||
triplet, version, features = file2_packages[pkg]
|
||||
print(f" 🍓 {pkg}: {version} (Features: {', '.join(features)})")
|
||||
|
||||
if removed:
|
||||
print("\n**Removed packages:**")
|
||||
for pkg in removed:
|
||||
triplet, version, features = file1_packages[pkg]
|
||||
print(f" 🍄 {pkg}: {version} (Features: {', '.join(features)})")
|
||||
|
||||
if updated:
|
||||
print("\n**Updated packages:**")
|
||||
for pkg in updated:
|
||||
print(f" 🍇 {pkg}")
|
||||
|
||||
|
||||
def read_file(file_path):
|
||||
"""
|
||||
Read the content of a file.
|
||||
"""
|
||||
with open(file_path) as file:
|
||||
return file.read()
|
||||
|
||||
|
||||
# Read files
|
||||
file1_content = read_file("/tmp/vcpkg-base-output.txt")
|
||||
file2_content = read_file("/tmp/vcpkg-head-output.txt")
|
||||
|
||||
# Generate the report
|
||||
generate_report(file1_content, file2_content)
|
6
.github/dependabot.yml
vendored
Normal file
6
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "monthly"
|
112
.github/labeler.yml
vendored
Normal file
112
.github/labeler.yml
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
"3D":
|
||||
- any: [
|
||||
'resources/3d/**/*',
|
||||
'src/3d/**/*',
|
||||
'src/app/3d/**/*',
|
||||
]
|
||||
|
||||
"Annotations":
|
||||
- any: [
|
||||
'src/core/annotations/**/*',
|
||||
'src/gui/annotations/**/*',
|
||||
]
|
||||
|
||||
"Chore":
|
||||
- any: [
|
||||
'.ci/**/*',
|
||||
'.docker/**/*',
|
||||
'.github/**/*',
|
||||
]
|
||||
|
||||
"DB Manager":
|
||||
- any: ['python/plugins/db_manager/**/*']
|
||||
|
||||
"Expressions":
|
||||
- any: [
|
||||
'src/core/expression/**/*',
|
||||
'resources/function_help/**/*',
|
||||
]
|
||||
|
||||
"Form":
|
||||
- any: [
|
||||
'src/core/editform/**/*',
|
||||
'src/gui/attributeformconfig/**/*',
|
||||
]
|
||||
|
||||
"GRASS":
|
||||
- any: ['python/plugins/grassprovider/**/*']
|
||||
|
||||
"GUI/UX":
|
||||
- any: [
|
||||
'images/**/*',
|
||||
'resources/themes/**/*',
|
||||
# 'src/gui/**/*', too broad
|
||||
]
|
||||
|
||||
"HANA data provider":
|
||||
- any: [
|
||||
'src/providers/hana/**/*',
|
||||
]
|
||||
|
||||
"Labeling":
|
||||
- any: [
|
||||
'src/app/labeling/**/*',
|
||||
'src/core/labeling/**/*',
|
||||
]
|
||||
|
||||
"Locator":
|
||||
- any: [
|
||||
'src/core/locator/**/*',
|
||||
'src/gui/locator/**/*',
|
||||
]
|
||||
|
||||
"Mesh":
|
||||
- any: [
|
||||
'external/mdal/**/*',
|
||||
'src/analysis/mesh/**/*',
|
||||
'src/core/mesh/**/*',
|
||||
'src/gui/mesh/**/*',
|
||||
]
|
||||
|
||||
"Metasearch":
|
||||
- any: ['python/plugins/MetaSearch/**/*']
|
||||
|
||||
"Point Clouds":
|
||||
- any: [
|
||||
'src/app/pointcloud/**/*',
|
||||
'src/core/pointcloud/**/*',
|
||||
'src/gui/pointcloud/**/*',
|
||||
]
|
||||
|
||||
"PostGIS data provider":
|
||||
- any: ['src/providers/postgres/**/*']
|
||||
|
||||
"Processing":
|
||||
- any: [
|
||||
'python/plugins/processing/**/*',
|
||||
'src/analysis/**/*',
|
||||
'src/core/processing/**/*',
|
||||
'src/process/**/*'
|
||||
]
|
||||
|
||||
"Python Console":
|
||||
- any: [
|
||||
'python/console/**/*',
|
||||
]
|
||||
|
||||
"Quick":
|
||||
- any: [
|
||||
'src/quickgui/**/*',
|
||||
]
|
||||
|
||||
"Server":
|
||||
- any: [
|
||||
'src/server/**/*',
|
||||
'resources/server/**/*'
|
||||
]
|
||||
|
||||
"Vector tiles":
|
||||
- any: [
|
||||
'src/core/vectortile/**/*',
|
||||
'src/gui/vectortile/**/*',
|
||||
]
|
25
.github/workflows/backport.yml
vendored
Normal file
25
.github/workflows/backport.yml
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
name: ♻ Backport
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- closed
|
||||
- labeled
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
backport:
|
||||
runs-on: ubuntu-22.04
|
||||
name: Backport
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Backport Bot
|
||||
id: backport
|
||||
if: github.event.pull_request.merged && ( ( github.event.action == 'closed' && contains( join( github.event.pull_request.labels.*.name ), 'backport') ) || contains( github.event.label.name, 'backport' ) )
|
||||
uses: m-kuhn/backport@7f3cab83e4b3b26aefcffda21851c3dc3d389f45 #v1.2.7
|
||||
with:
|
||||
github_token: ${{ secrets.GH_TOKEN_BOT }}
|
222
.github/workflows/build-macos-qt6.yml
vendored
Normal file
222
.github/workflows/build-macos-qt6.yml
vendored
Normal file
@ -0,0 +1,222 @@
|
||||
---
|
||||
name: 🍎 Build - MacOS Qt6
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
pull_request:
|
||||
release:
|
||||
types: ['published']
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: macos-13
|
||||
triplet: x64-osx-dynamic-release
|
||||
deployment-target: "10.15"
|
||||
- os: macos-14
|
||||
triplet: arm64-osx-dynamic-release
|
||||
deployment-target: "11.0"
|
||||
name: build (macos)
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: 🐣 Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 🐩 Install CMake and Ninja
|
||||
uses: lukka/get-cmake@ea004816823209b8d1211e47b216185caee12cc5 # latest
|
||||
with:
|
||||
# Pin to specific version to avoid rebuilding too often
|
||||
# Also helps to avoid spurious build failures like https://github.com/qgis/QGIS/pull/47098
|
||||
cmakeVersion: 3.30.4
|
||||
|
||||
- name: 🎡 Setup vcpkg
|
||||
id: setup-vcpkg
|
||||
uses: ./.github/actions/setup-vcpkg
|
||||
|
||||
- name: 🎲 Get artifact ids
|
||||
id: workflow-artifact-ids
|
||||
uses: ./.github/actions/get-workflow-artifact-ids
|
||||
|
||||
- name: 🔨 Prepare build env
|
||||
run: |
|
||||
brew install automake bison flex gnu-sed autoconf-archive nasm libtool fdupes
|
||||
echo $(brew --prefix bison)/bin >> $GITHUB_PATH
|
||||
echo $(brew --prefix flex)/bin >> $GITHUB_PATH
|
||||
echo $(brew --prefix libtool)/bin >> $GITHUB_PATH
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: 🍭 Setup XCode
|
||||
uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
|
||||
with:
|
||||
xcode-version: latest-stable
|
||||
|
||||
- name: 🛍️ Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
max-size: 500M
|
||||
key: build-ccache-${{ matrix.triplet }}-qt6-${{ github.event.pull_request.base.ref || github.ref_name }}
|
||||
save: ${{ github.event_name == 'push' }}
|
||||
|
||||
- name: 🛍️ Tune ccache configuration
|
||||
shell: bash
|
||||
run: |
|
||||
# To make ccache work properly with precompiled headers
|
||||
ccache --set-config sloppiness=pch_defines,time_macros,include_file_mtime,include_file_ctime
|
||||
|
||||
- name: 🌱 Install dependencies and generate project files
|
||||
env:
|
||||
X_VCPKG_ASSET_SOURCES: x-azurl,https://assetcache.open-vcpkg.org/assetcache,,read
|
||||
run: |
|
||||
echo "VCPKG_ROOT: ${VCPKG_ROOT}"
|
||||
|
||||
# Install first only with binarycaching, then deduplicate binaries and replace copies with symlinks.
|
||||
# Nuget doesn't understand the symlink concept
|
||||
cmake -S . \
|
||||
-G Ninja \
|
||||
-B build \
|
||||
-D QGIS_APP_NAME="QGIS-${{steps.workflow-artifact-ids.outputs.display-name}}" \
|
||||
-D WITH_VCPKG=ON \
|
||||
-D BUILD_WITH_QT6=ON \
|
||||
-D WITH_QTWEBKIT=OFF \
|
||||
-D WITH_BINDINGS=ON \
|
||||
-D WITH_ORACLE=ON \
|
||||
-D VCPKG_TARGET_TRIPLET="${{ matrix.triplet }}" \
|
||||
-D VCPKG_HOST_TRIPLET="${{ matrix.triplet }}" \
|
||||
-D VCPKG_INSTALL_OPTIONS="--only-binarycaching" \
|
||||
-D CMAKE_OSX_DEPLOYMENT_TARGET=${{ matrix.deployment-target }} \
|
||||
-D ENABLE_UNITY_BUILDS=ON \
|
||||
-D NUGET_USERNAME=${{ github.actor }} \
|
||||
-D NUGET_SOURCE="https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json" \
|
||||
-D NUGET_TOKEN=${{ secrets.GITHUB_TOKEN }} || true
|
||||
|
||||
fdupes -q -r -1 build/vcpkg_installed/${{ matrix.triplet }}/lib | grep libQt | while read line; do master=""; for file in ${line[*]}; do if [[ "x${master}" == "x" ]]; then master=$file; else rm "${file}"; ln -s $(basename "${master}") "${file}"; fi; done; done
|
||||
|
||||
cmake -D VCPKG_INSTALL_OPTIONS="" build
|
||||
|
||||
- name: 📑 Upload vcpkg build logs
|
||||
uses: actions/upload-artifact@v4
|
||||
if: failure()
|
||||
with:
|
||||
name: build-logs-${{ matrix.triplet }}
|
||||
path: |
|
||||
${{ env.VCPKG_ROOT }}/buildtrees/**/*.log
|
||||
|
||||
- name: 📦 Create SDK
|
||||
if: github.event_name == 'workflow_dispatch' || github.event_name == 'release'
|
||||
run: |
|
||||
./build/_deps/vcpkg-src/vcpkg export --zip --output-dir=./sdk --x-install-root=./build/vcpkg_installed --x-manifest-root=vcpkg
|
||||
|
||||
- name: 📤 Upload sdk
|
||||
if: github.event_name == 'workflow_dispatch' || github.event_name == 'release'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: qgis-sdk-${{ matrix.triplet }}
|
||||
path: |
|
||||
sdk/vcpkg-export-*.zip
|
||||
|
||||
- name: 🌋 Build
|
||||
run: |
|
||||
# We make sure the target "all" is built before bundling
|
||||
# Ideally, we would specify each target that is required to be installed, but this workaround is sufficient for now
|
||||
cmake --build build
|
||||
cmake --build build --target bundle
|
||||
|
||||
- name: Archive app
|
||||
run: |
|
||||
gtar -cpvzf qgis-app-${{steps.workflow-artifact-ids.outputs.filename}}-${{ matrix.triplet }}.tar.gz ./build/_CPack_Packages/Darwin/External/*/*.app
|
||||
|
||||
- name: 📤 Upload app
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: qgis-app-${{steps.workflow-artifact-ids.outputs.filename}}-${{ matrix.triplet }}
|
||||
path: |
|
||||
qgis-app-${{steps.workflow-artifact-ids.outputs.filename}}-${{ matrix.triplet }}.tar.gz
|
||||
|
||||
schedule_download_comment:
|
||||
name: Create dmg
|
||||
runs-on: macos-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: 🐣 Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 🔨 Prepare build env
|
||||
run: |
|
||||
brew install create-dmg
|
||||
|
||||
|
||||
- name: 🎲 Get artifact ids
|
||||
id: workflow-artifact-ids
|
||||
uses: ./.github/actions/get-workflow-artifact-ids
|
||||
|
||||
- name: 📤 Download app
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: qgis-app-${{steps.workflow-artifact-ids.outputs.filename}}-*
|
||||
path: |
|
||||
artifacts
|
||||
|
||||
- name: Create universal app
|
||||
run: |
|
||||
mkdir -p x64
|
||||
gtar --strip-components=5 -zxf ./artifacts/qgis-app-${{steps.workflow-artifact-ids.outputs.filename}}-x64-osx-dynamic-release/qgis-app-${{steps.workflow-artifact-ids.outputs.filename}}-x64-osx-dynamic-release.tar.gz -C x64
|
||||
mkdir -p arm64
|
||||
gtar --strip-components=5 -zxf ./artifacts/qgis-app-${{steps.workflow-artifact-ids.outputs.filename}}-arm64-osx-dynamic-release/qgis-app-${{steps.workflow-artifact-ids.outputs.filename}}-arm64-osx-dynamic-release.tar.gz -C arm64
|
||||
|
||||
pip install lipomerge
|
||||
lipomerge ./x64 ./arm64 universal
|
||||
|
||||
- name: Create dmg
|
||||
run: |
|
||||
QGIS_APP_NAME=QGIS-"${{steps.workflow-artifact-ids.outputs.display-name}}"
|
||||
create-dmg --volname "${QGIS_APP_NAME} Installer" \
|
||||
--hide-extension ${QGIS_APP_NAME}.app \
|
||||
--volicon "$(pwd)/images/icons/mac/qgis.icns" \
|
||||
--background "$(pwd)/platform/macos/installer_background.png" \
|
||||
--window-pos 200 120 \
|
||||
--window-size 512 320 \
|
||||
--icon-size 100 \
|
||||
--icon "${QGIS_APP_NAME}.app" 130 160 \
|
||||
--app-drop-link 400 155 \
|
||||
${QGIS_APP_NAME}-Installer.dmg \
|
||||
universal/*/*.app
|
||||
|
||||
- name: 📤 Upload app
|
||||
uses: actions/upload-artifact@v4
|
||||
id: artifact-mac-qt6
|
||||
with:
|
||||
name: qgis-${{steps.workflow-artifact-ids.outputs.filename}}-dmg
|
||||
path: |
|
||||
*.dmg
|
||||
|
||||
- name: Upload release assets
|
||||
uses: AButler/upload-release-assets@v3.0
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
with:
|
||||
files: '*.dmg'
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Schedule download comment
|
||||
uses: ./.github/actions/post_sticky_comment
|
||||
if: github.event_name == 'pull_request'
|
||||
with:
|
||||
marker: macos-qt6
|
||||
body: |
|
||||
### 🍎 MacOS Qt6 builds
|
||||
Download [MacOS Qt6 builds of this PR for testing](${{ steps.artifact-mac-qt6.outputs.artifact-url }}).
|
||||
_This installer is not signed, `control`+click > `open` the app to avoid the warning_
|
||||
*(Built from commit ${{ github.event.pull_request.head.sha }})*
|
||||
pr: ${{ github.event.number }}
|
157
.github/workflows/build_artifact_comment.yml
vendored
Normal file
157
.github/workflows/build_artifact_comment.yml
vendored
Normal file
@ -0,0 +1,157 @@
|
||||
name: Write build artifact comments
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- 🪟 MingW64 Windows 64bit Build
|
||||
- 🪟 Windows Qt6
|
||||
- 🧮 Vcpkg report
|
||||
- 🍎 Build - MacOS Qt6
|
||||
types:
|
||||
- completed
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
jobs:
|
||||
on-success:
|
||||
if: github.event.workflow_run.event == 'pull_request'
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 'Download artifact'
|
||||
id: download_artifact
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
|
||||
const allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
run_id: context.payload.workflow_run.id,
|
||||
});
|
||||
|
||||
let matchArtifacts = allArtifacts.data.artifacts.filter((artifact) => {
|
||||
return artifact.name.startsWith('comment_artifacts-');
|
||||
});
|
||||
|
||||
if (matchArtifacts.length > 0)
|
||||
{
|
||||
for (const artifact of matchArtifacts) {
|
||||
const suffix = artifact.name.split('comment_artifacts-')[1]; // Extract the suffix from the artifact name
|
||||
|
||||
// Download each matching artifact
|
||||
let download = await github.rest.actions.downloadArtifact({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
artifact_id: artifact.id,
|
||||
archive_format: 'zip',
|
||||
});
|
||||
|
||||
// Write each artifact to a zip file named after its suffix
|
||||
const zipFilePath = `${process.env.GITHUB_WORKSPACE}/data-${suffix}.zip`;
|
||||
fs.writeFileSync(zipFilePath, Buffer.from(download.data));
|
||||
console.log(`Downloaded and saved artifact: ${artifact.name} to ${zipFilePath}`);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
core.setOutput('artifact_id', 0);
|
||||
}
|
||||
|
||||
- name: 'Unzip artifact'
|
||||
run: |
|
||||
unzip data-*.zip
|
||||
|
||||
- name: 'Post artifact download link as comment on PR'
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
function updateCommentSection(prComment, marker, body) {
|
||||
// Create a regular expression to match the section between start and end markers
|
||||
const sectionRegex = new RegExp(`(<!-- ====startsection ${marker}-->\\n)([\\s\\S]*?)(<!-- ====endsection ${marker}-->)`, 'm');
|
||||
|
||||
// Check if the section with the marker exists
|
||||
if (sectionRegex.test(prComment)) {
|
||||
// Replace the existing body text between the markers
|
||||
return prComment.replace(sectionRegex, `$1${body}\n$3`);
|
||||
} else {
|
||||
// If the section doesn't exist, append the new section to the end
|
||||
return prComment.trim() + `\n\n<!-- ====startsection ${marker}-->\n${body}\n<!-- ====endsection ${marker}-->\n`;
|
||||
}
|
||||
}
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// Read all files matching the pattern 'comment*.json'
|
||||
const files = fs.readdirSync('.').filter(file => file.startsWith('comment') && file.endsWith('.json'));
|
||||
|
||||
if (files.length === 0) {
|
||||
console.log('No comment*.json files found');
|
||||
return;
|
||||
}
|
||||
|
||||
// Take the PR number from the first file
|
||||
const dataSample = JSON.parse(fs.readFileSync(files[0], 'utf8'));
|
||||
const prNumber = dataSample.pr_number;
|
||||
|
||||
const prComments = await github.rest.issues.listComments({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: prNumber,
|
||||
});
|
||||
|
||||
const PREFIX = "<!-- !!## stickymarker ##!! -->";
|
||||
|
||||
// Find the comment that starts with the specified PREFIX
|
||||
const comment = prComments.data?.find(c => c.body.startsWith(PREFIX));
|
||||
|
||||
let newPrComment;
|
||||
if (!!comment) {
|
||||
newPrComment = comment.body;
|
||||
} else {
|
||||
newPrComment = PREFIX + "\n";
|
||||
}
|
||||
|
||||
|
||||
// Loop through all the comment*.json files
|
||||
for (const file of files) {
|
||||
try {
|
||||
const data = JSON.parse(fs.readFileSync(file, 'utf8'));
|
||||
|
||||
const marker = data.marker;
|
||||
const body = data.body;
|
||||
console.debug(data);
|
||||
|
||||
newPrComment = updateCommentSection(newPrComment, marker, body);
|
||||
} catch (error) {
|
||||
console.error(`Failed to process file ${file}: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Update or create the PR comment after processing all the files
|
||||
if (!!comment) {
|
||||
// Update the existing comment
|
||||
await github.rest.issues.updateComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
comment_id: comment.id,
|
||||
body: newPrComment
|
||||
});
|
||||
} else {
|
||||
// Create a new comment
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: prNumber,
|
||||
body: newPrComment
|
||||
});
|
||||
}
|
106
.github/workflows/check-user-reported-qgis-version.yml
vendored
Normal file
106
.github/workflows/check-user-reported-qgis-version.yml
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
name: Check if user is running the latest version of QGIS
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
env:
|
||||
# Extract issue body
|
||||
ISSUE_BODY: ${{ github.event.issue.body }}
|
||||
|
||||
jobs:
|
||||
check_version_reported:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Get version details
|
||||
run: |
|
||||
python ./scripts/get_latest_qgis_versions.py --release="stable" --github_token=${{ secrets.GITHUB_TOKEN }} >> $GITHUB_ENV
|
||||
- name: Write comment
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const {ISSUE_BODY, QGIS_VERSION_LTR_PATCH, QGIS_VERSION_STABLE_PATCH} = process.env // Latest released version identified using get_latest_qgis_versions
|
||||
|
||||
compareSemanticVersions = (version1, version2) => {
|
||||
// Returns -1 if version1 < version2
|
||||
// Returns 1 if version1 > version2
|
||||
// Returns 0 if version1 = version2
|
||||
|
||||
// Assume parameters are string and follow the semantic version : major.minor.patch
|
||||
|
||||
var version1 = version1.split(".").map(x => parseInt(x))
|
||||
var version2 = version2.split(".").map(x => parseInt(x))
|
||||
|
||||
//Major version
|
||||
if ( version1[0] < version2[0] ){
|
||||
return -1
|
||||
}
|
||||
else if ( version1[0] > version2[0] ) {
|
||||
return 1
|
||||
}
|
||||
|
||||
//Minor version2
|
||||
|
||||
if ( version1[1] < version2[1] ){
|
||||
return -1
|
||||
}
|
||||
else if ( version1[1] > version2[1] ) {
|
||||
return 1
|
||||
}
|
||||
//Patch version
|
||||
if ( version1[2] < version2[2] ){
|
||||
return -1
|
||||
}
|
||||
else if ( version1[2] > version2[2] ) {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
// Match qgis version reported e.g : "3.40.0-Bratislava"
|
||||
// More example here : https://regex101.com/r/jvHJAf/2
|
||||
var regex = /QGIS [Vv]ersion(?:: | \| )(\d)\.(\d{2})\.(\d*)-[A-Z][a-z]+/
|
||||
|
||||
var m = ISSUE_BODY.match(regex)
|
||||
|
||||
if ( !m ){
|
||||
console.log("Debug: No version identified in the body")
|
||||
return
|
||||
}
|
||||
|
||||
major_version = m[1]
|
||||
minor_version = m[2]
|
||||
patch_version = m[3]
|
||||
user_version = `${major_version}.${minor_version}.${patch_version}`
|
||||
|
||||
if ( compareSemanticVersions(user_version, QGIS_VERSION_LTR_PATCH) === -1 ) {
|
||||
console.log("Debug: Suggest user to try latest LTR release")
|
||||
|
||||
let comment = `Thanks for reporting, however it looks like you are using an older version of QGIS (version ${user_version}) instead of latest (Version ${QGIS_VERSION_LTR_PATCH}). Your bug could already be resolved in the latest version. \nIt takes a lot of human effort to triage all the bugs in a project like QGIS, could you please retry with the latest version first?`
|
||||
github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: comment
|
||||
})
|
||||
}
|
||||
else if ( compareSemanticVersions(user_version, QGIS_VERSION_LTR_PATCH) === 0 ) {
|
||||
console.log("Debug: user is already running latest LTR version")
|
||||
}
|
||||
else if ( compareSemanticVersions(user_version, QGIS_VERSION_STABLE_PATCH) === -1 ) {
|
||||
console.log("Debug: Suggest user to try latest release")
|
||||
|
||||
let comment = `Thanks for reporting, however it looks like you are using an older version of QGIS (version ${user_version}) instead of latest (Version ${QGIS_VERSION_STABLE_PATCH}). Your bug could already be resolved in the latest version. \nIt takes a lot of human effort to triage all the bugs in a project like QGIS, could you please retry with the latest version first?`
|
||||
github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: comment
|
||||
})
|
||||
}
|
||||
else {
|
||||
console.log("Debug: pass, the user is running a supported version so do nothing")
|
||||
}
|
219
.github/workflows/code_layout.yml
vendored
Normal file
219
.github/workflows/code_layout.yml
vendored
Normal file
@ -0,0 +1,219 @@
|
||||
name: 🧹 Code Layout
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- release-**
|
||||
- queued_ltr_backports
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
DOXYGEN_VERSION: 1.9.8
|
||||
|
||||
jobs:
|
||||
documentation_checks:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- name: Install requirements
|
||||
run: |
|
||||
wget https://www.doxygen.nl/files/doxygen-${DOXYGEN_VERSION}.linux.bin.tar.gz
|
||||
tar -xzf doxygen-${DOXYGEN_VERSION}.linux.bin.tar.gz
|
||||
python -m pip install --upgrade pip
|
||||
pip install autopep8 nose2 mock termcolor
|
||||
- name: Make
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DUSE_CCACHE=OFF -DWITH_CORE=OFF -DWITH_APIDOC=ON -DWITH_ASTYLE=ON -DENABLE_TESTS=ON \
|
||||
-DWITH_DOT=NO -DWERROR=ON -DDOXYGEN_EXECUTABLE=../doxygen-${DOXYGEN_VERSION}/bin/doxygen ..
|
||||
make -j3 apidoc
|
||||
- name: Run Tests
|
||||
run: cd build && ctest -V -R PyQgsDocCoverage
|
||||
|
||||
license_check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Requirements
|
||||
run: |
|
||||
sudo apt install -y \
|
||||
cpanminus
|
||||
cpanm --notest App::Licensecheck
|
||||
|
||||
- name: Run License Check
|
||||
run: ./tests/code_layout/test_licenses.sh
|
||||
|
||||
shell_check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Requirements
|
||||
run: |
|
||||
sudo apt install -y \
|
||||
shellcheck
|
||||
|
||||
- name: Run Shellcheck
|
||||
run: ./tests/code_layout/test_shellcheck.sh
|
||||
|
||||
banned_keywords_check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Run Banned Keywords Test
|
||||
run: ./tests/code_layout/test_banned_keywords.sh
|
||||
|
||||
class_name_check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Run class naming conventions check
|
||||
run: ./tests/code_layout/test_class_names.sh
|
||||
|
||||
def_window_title_check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Def Window Title Test
|
||||
run: ./tests/code_layout/test_defwindowtitle.sh
|
||||
|
||||
qgsscrollarea_check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Run QgsScrollArea check
|
||||
run: ./tests/code_layout/test_qgsscrollarea.sh
|
||||
|
||||
qvariant_no_brace_init:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: No brace initialization of QVariant variables
|
||||
run: ./tests/code_layout/test_qvariant_no_brace_init.sh
|
||||
|
||||
qt_module_wide_imports:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: No module-wide imports of Qt modules
|
||||
run: ./tests/code_layout/test_qt_imports.sh
|
||||
|
||||
doxygen_layout_check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Requirements
|
||||
run: |
|
||||
sudo apt install -y \
|
||||
expect \
|
||||
silversearcher-ag
|
||||
- name: Doxygen Layout Test
|
||||
run: ./tests/code_layout/test_doxygen_layout.sh
|
||||
|
||||
indentation_check:
|
||||
if: github.event_name == 'pull_request'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 100
|
||||
- name: Install Requirements
|
||||
run: |
|
||||
sudo apt install -y \
|
||||
astyle \
|
||||
python3-autopep8 \
|
||||
flip
|
||||
- name: Indentation Test
|
||||
run: ./scripts/verify_indentation.sh HEAD~1
|
||||
|
||||
spell_check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Requirements
|
||||
run: |
|
||||
sudo apt install -y \
|
||||
expect \
|
||||
silversearcher-ag
|
||||
|
||||
- name: Retrieve changed files
|
||||
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c #v46
|
||||
id: changed_files
|
||||
with:
|
||||
separator: " "
|
||||
|
||||
- name: Spell Test
|
||||
if: steps.changed_files.outputs.any_changed == 'true'
|
||||
env:
|
||||
ALL_CHANGED_FILES: ${{ steps.changed_files.outputs.changed_files }}
|
||||
run: ./scripts/spell_check/check_spelling.sh
|
||||
|
||||
sip_check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Python 3.12
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
- name: Install Requirements
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install autopep8 nose2 mock termcolor pyyaml
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Sip Checks
|
||||
run: ./tests/code_layout/sipify/test_sipify.sh
|
||||
- name: Sip Include Test
|
||||
run: ./tests/code_layout/sipify/test_sip_include.sh
|
||||
- name: Sip Files Up To Date
|
||||
run: ./tests/code_layout/sipify/test_sipfiles.sh
|
||||
|
||||
cppcheck:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Requirements
|
||||
run: |
|
||||
sudo apt install -y cppcheck
|
||||
|
||||
- name: Run cppcheck test
|
||||
run: ./scripts/cppcheck.sh
|
||||
|
||||
moc_check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
- name: Run Check
|
||||
run: python3 scripts/includemocs.py src --dry-run
|
130
.github/workflows/mingw64.yml
vendored
Normal file
130
.github/workflows/mingw64.yml
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
name: 🪟 MingW64 Windows 64bit Build
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- release-**
|
||||
- queued_ltr_backports
|
||||
paths:
|
||||
- 'src/**'
|
||||
- 'external/**'
|
||||
- 'python/**'
|
||||
- 'tests/**'
|
||||
- 'ms-windows/**'
|
||||
- 'CMakeLists.txt'
|
||||
- '.github/workflows/mingw64.yml'
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
mingw64-build:
|
||||
name: MinGW64 Windows Build
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: fedora:40
|
||||
options: --security-opt seccomp=unconfined
|
||||
volumes:
|
||||
- ${{ github.workspace }}:/w
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# To be removed
|
||||
# Workaround a bug where the initial /etc/dnf/dnf.conf file contains
|
||||
# just the "tsflags=nodocs" line
|
||||
- name: Replace broken dnf.conf
|
||||
run: printf '[main]\ngpgcheck=True\ninstallonly_limit=3\nclean_requirements_on_remove=True\nbest=False\nskip_if_unavailable=True\ntsflags=nodocs' > /etc/dnf/dnf.conf
|
||||
|
||||
- name: Update system
|
||||
run: dnf -y update
|
||||
|
||||
- name: Install core dependencies
|
||||
run: dnf -y install zip
|
||||
|
||||
- name: Install build dependencies
|
||||
run: ./ms-windows/mingw/mingwdeps.sh
|
||||
|
||||
# Node.js and Yarn for server landingpage webapp
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '22'
|
||||
|
||||
- name: Make yarn available
|
||||
run: corepack enable
|
||||
|
||||
- name: Create ccache dir
|
||||
run: mkdir -p /w/.ccache/QGIS
|
||||
|
||||
- name: Restore build cache
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: /w/.ccache/QGIS
|
||||
key: build-ccache-mingw64-${{ github.event.pull_request.base.ref || github.ref_name }}
|
||||
restore-keys: |
|
||||
build-ccache-mingw64-master
|
||||
|
||||
- name: Build QGIS Application
|
||||
run: CCACHE_DIR=/w/.ccache/QGIS ./ms-windows/mingw/build.sh x86_64 nodebug 4
|
||||
|
||||
- name: Save build cache for push only
|
||||
uses: actions/cache/save@v4
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
with:
|
||||
path: /w/.ccache/QGIS
|
||||
key: build-ccache-mingw64-${{ github.ref_name }}-${{ github.run_id }}
|
||||
|
||||
- name: Create Portable zip
|
||||
run: |
|
||||
DISTROOT=build_mingw64/dist/usr/x86_64-w64-mingw32/sys-root/mingw
|
||||
DEBUGROOT=dist_debug
|
||||
for file in $(find $DISTROOT -name '*.debug' \( -type l -or -type f \)); do
|
||||
DEST=${file/$DISTROOT/$DEBUGROOT}
|
||||
mkdir -p "$(dirname $DEST)"
|
||||
sudo mv "$file" "$DEST"
|
||||
done
|
||||
sudo mv $DISTROOT QGIS-Portable
|
||||
zip -r qgis-portable-win64.zip QGIS-Portable
|
||||
(cd $DEBUGROOT && zip -r - *) > qgis-portable-win64-debugsym.zip
|
||||
|
||||
- name: Save PR number to zips
|
||||
run: |
|
||||
echo ${{ github.event.number }} | tee pr_number
|
||||
zip -u qgis-portable-win64.zip pr_number
|
||||
zip -u qgis-portable-win64-debugsym.zip pr_number
|
||||
echo ${{ github.event.pull_request.head.sha }} | tee git_commit
|
||||
zip -u qgis-portable-win64.zip git_commit
|
||||
zip -u qgis-portable-win64-debugsym.zip git_commit
|
||||
|
||||
- name: Upload QGIS for Windows 64bit
|
||||
uses: actions/upload-artifact@v4
|
||||
id: artifact-win64
|
||||
with:
|
||||
name: QGIS for Windows 64bit
|
||||
path: qgis-portable-win64.zip
|
||||
|
||||
- name: Upload QGIS for Windows 64bit Debug Symbols
|
||||
uses: actions/upload-artifact@v4
|
||||
id: artifact-win64-debug
|
||||
with:
|
||||
name: QGIS for Windows 64bit Debug Symbols
|
||||
path: qgis-portable-win64-debugsym.zip
|
||||
|
||||
- name: Schedule download comment
|
||||
uses: ./.github/actions/post_sticky_comment
|
||||
if: github.event_name == 'pull_request'
|
||||
with:
|
||||
marker: mingw64
|
||||
body: |
|
||||
### 🪟 Windows builds
|
||||
Download [Windows builds of this PR for testing](${{ steps.artifact-win64.outputs.artifact-url }}).
|
||||
Debug symbols for this build are available [here](${{ steps.artifact-win64-debug.outputs.artifact-url }}).
|
||||
*(Built from commit ${{ github.event.pull_request.head.sha }})*
|
||||
pr: ${{ github.event.number }}
|
100
.github/workflows/ogc.yml
vendored
Normal file
100
.github/workflows/ogc.yml
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
name: 🗺 OGC tests for QGIS Server
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- release-**
|
||||
- queued_ltr_backports
|
||||
paths:
|
||||
- 'src/core/**'
|
||||
- 'src/auth/**'
|
||||
- 'src/providers/**'
|
||||
- 'src/server/**'
|
||||
- 'src/CMakeLists.txt'
|
||||
- 'external/**'
|
||||
- 'CMakeLists.txt'
|
||||
- '.github/workflows/ogc.yml'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- release-**
|
||||
paths:
|
||||
- 'src/core/**'
|
||||
- 'src/auth/**'
|
||||
- 'src/providers/**'
|
||||
- 'src/server/**'
|
||||
- 'src/CMakeLists.txt'
|
||||
- 'external/**'
|
||||
- 'CMakeLists.txt'
|
||||
- '.github/workflows/ogc.yml'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Restore build cache
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: /home/runner/QGIS/.ccache
|
||||
key: build-ccache-ogc-${{ github.event.pull_request.base.ref || github.ref_name }}
|
||||
restore-keys: |
|
||||
build-ccache-ogc-master
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build Docker Container
|
||||
id: docker-build
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
tags: qgis/qgis-deps-ogc:${{ github.event.pull_request.base.ref || github.ref_name }}
|
||||
context: .ci/ogc
|
||||
file: .ci/ogc/Dockerfile
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
load: true
|
||||
|
||||
- name: Run build
|
||||
run: |
|
||||
docker run -v $(pwd):/usr/src/qgis -v /home/runner/QGIS/.ccache:/root/.ccache ${DOCKER_IMAGE} /usr/src/qgis/.ci/ogc/build.sh
|
||||
env:
|
||||
DOCKER_IMAGE: ${{ steps.docker-build.outputs.imageid }}
|
||||
|
||||
- name: Save build cache for push only
|
||||
uses: actions/cache/save@v4
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
with:
|
||||
path: /home/runner/QGIS/.ccache
|
||||
key: build-ccache-ogc-${{ github.ref_name }}-${{ github.run_id }}
|
||||
|
||||
- name: Install pyogctest
|
||||
run: |
|
||||
sudo apt-get update && sudo apt-get install python3-virtualenv virtualenv
|
||||
virtualenv -p /usr/bin/python3 venv && source venv/bin/activate && pip install pyogctest
|
||||
|
||||
- name: Run WMS 1.3.0 OGC tests
|
||||
run: |
|
||||
source venv/bin/activate && pyogctest -s wms130 -e
|
||||
docker compose -f .ci/ogc/docker-compose.yml up -d
|
||||
source venv/bin/activate && pyogctest -n ogc_qgis -s wms130 -v -u http://$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' qgis_server_nginx)/qgisserver_wms130
|
||||
env:
|
||||
DOCKER_IMAGE: ${{ steps.docker-build.outputs.imageid }}
|
||||
|
||||
- name: Run OGC API Features 1.0 tests
|
||||
run: |
|
||||
cd data && git clone https://github.com/qgis/QGIS-Training-Data && cd -
|
||||
docker compose -f .ci/ogc/docker-compose.yml up -d
|
||||
source venv/bin/activate && pyogctest -n ogc_qgis -s ogcapif -v -u http://$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' qgis_server_nginx)/qgisserver_ogcapif
|
||||
env:
|
||||
DOCKER_IMAGE: ${{ steps.docker-build.outputs.imageid }}
|
20
.github/workflows/pr-auto-label.yml
vendored
Normal file
20
.github/workflows/pr-auto-label.yml
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
name: "🌈 Triage"
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [ opened, synchronize, reopened ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
name: "Set on PR"
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/labeler@v5
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
148
.github/workflows/pr-auto-milestone.yml
vendored
Normal file
148
.github/workflows/pr-auto-milestone.yml
vendored
Normal file
@ -0,0 +1,148 @@
|
||||
name: 📅 Auto set milestone on PR
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
QGIS_MAJOR_VERSION: 3
|
||||
|
||||
jobs:
|
||||
pr-without-milestones:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'qgis/QGIS'
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
# list the tags and milestones
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: graphql_request
|
||||
with:
|
||||
query: |
|
||||
query {
|
||||
repository(owner: "qgis", name: "QGIS") {
|
||||
pullRequests(states: OPEN, last: 100) {
|
||||
edges {
|
||||
node {
|
||||
number
|
||||
title
|
||||
milestone {
|
||||
number
|
||||
}
|
||||
baseRef {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
milestones(orderBy: {field: CREATED_AT, direction: DESC}, first: 50) {
|
||||
edges {
|
||||
node {
|
||||
title
|
||||
number
|
||||
}
|
||||
}
|
||||
}
|
||||
refs(refPrefix: "refs/tags/", orderBy: {field: TAG_COMMIT_DATE, direction: DESC}, first: 30) {
|
||||
edges {
|
||||
node {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# take the first unprocessed PR and determine if some remain
|
||||
- name: Filter PR to check
|
||||
id: extract_data
|
||||
env:
|
||||
JSON_DATA: ${{ steps.graphql_request.outputs.data }}
|
||||
run: |
|
||||
# get PRs without milestones
|
||||
PRS_TO_PROCESS=$(echo "${JSON_DATA}" | jq '.repository.pullRequests.edges[] | select( .node.milestone.number | not ) | .node.number')
|
||||
|
||||
NUMBER_OF_PRS=$(echo "${PRS_TO_PROCESS}" | jq -s '. | length')
|
||||
echo "NUMBER_OF_PRS: ${NUMBER_OF_PRS}"
|
||||
# early exit
|
||||
[[ ${NUMBER_OF_PRS} == 0 ]] && echo "has_milestone_to_set=0" >> $GITHUB_OUTPUT && exit 0
|
||||
|
||||
# Take the first
|
||||
PR_NUMBER=$(echo "${PRS_TO_PROCESS}" | jq -s '. | first')
|
||||
echo "PR_NUMBER: ${PR_NUMBER}"
|
||||
|
||||
# Not used for now
|
||||
RE_RUN_JOB=$(echo "${JSON_DATA}" | jq -s '. | length > 1')
|
||||
echo "RE_RUN_JOB: ${RE_RUN_JOB}"
|
||||
|
||||
# Get the base branch
|
||||
BASE_BRANCH=$(echo "${JSON_DATA}" | jq -r ".repository.pullRequests.edges[] | select( .node.number == ${PR_NUMBER} ) | .node.baseRef.name")
|
||||
echo "BASE_BRANCH: ${BASE_BRANCH}"
|
||||
|
||||
# master => NOTHING, release_3-10 => _10
|
||||
MINOR_VERSION=$(echo ${BASE_BRANCH} | sed -r -e 's/^release-[0-9]_([0-9]+)/_\1/;t;d')
|
||||
echo "MINOR_VERSION: ${MINOR_VERSION}"
|
||||
|
||||
# get the max release from the tags
|
||||
MAX_RELEASE=$(echo "${JSON_DATA}" | jq ".repository.refs.edges[].node.name | select( . | test(\"^final-${QGIS_MAJOR_VERSION}${MINOR_VERSION}\") ) | sub(\"^final-${QGIS_MAJOR_VERSION}_(?<m>[0-9]+)_(?<p>.)\"; .m+\".\"+.p) | tonumber" | jq -s '. | max')
|
||||
echo "MAX_RELEASE: ${MAX_RELEASE}"
|
||||
|
||||
# increase the number to get milestone: round+2 for master, +0.1 for release_xxx branches
|
||||
INCREASE_OPERATION=$([[ -z ${MINOR_VERSION} ]] && echo "${MAX_RELEASE%.*} + 2.0" || echo "${MAX_RELEASE} + 0.1" )
|
||||
echo "INCREASE_OPERATION: ${INCREASE_OPERATION}"
|
||||
MILESTONE_TITLE="${QGIS_MAJOR_VERSION}."$(echo "${INCREASE_OPERATION}" | bc)
|
||||
echo "MILESTONE_TITLE: ${MILESTONE_TITLE}"
|
||||
|
||||
MILESTONE_NUMBER=$(echo "${JSON_DATA}" | jq ".repository.milestones.edges[] | select( .node.title == \"${MILESTONE_TITLE}\" ) | .node.number")
|
||||
echo "MILESTONE_NUMBER: ${MILESTONE_NUMBER}"
|
||||
|
||||
HAS_MILESTONE_TO_CREATE=$([[ -z ${MILESTONE_NUMBER} ]] && echo "1" || echo "0" )
|
||||
echo "HAS_MILESTONE_TO_CREATE: ${HAS_MILESTONE_TO_CREATE}"
|
||||
|
||||
echo "has_milestone_to_set=1" >> $GITHUB_OUTPUT
|
||||
echo "pr_number=${PR_NUMBER}" >> $GITHUB_OUTPUT
|
||||
echo "milestone_title=${MILESTONE_TITLE}" >> $GITHUB_OUTPUT
|
||||
echo "milestone_number=${MILESTONE_NUMBER}" >> $GITHUB_OUTPUT
|
||||
echo "has_milestone_to_create=${HAS_MILESTONE_TO_CREATE}" >> $GITHUB_OUTPUT
|
||||
|
||||
# create the milestone if needed
|
||||
- name: Create milestone if needed
|
||||
id: create_milestone
|
||||
if: steps.extract_data.outputs.has_milestone_to_set == 1 && steps.extract_data.outputs.has_milestone_to_create == 1
|
||||
uses: octokit/request-action@v2.x
|
||||
with:
|
||||
route: POST /repos/qgis/QGIS/milestones
|
||||
title: ${{ steps.extract_data.outputs.milestone_title }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Compute the milestone number
|
||||
- name: Compute milestone number from existing or created
|
||||
id: compute_milestone
|
||||
if: always() && steps.extract_data.outputs.has_milestone_to_set == 1
|
||||
env:
|
||||
MILESTONE_NUMBER_EXISTING: ${{ steps.extract_data.outputs.milestone_number }}
|
||||
MILESTONE_NUMBER_CREATED_JSON: ${{ steps.create_milestone.outputs.data }}
|
||||
run: |
|
||||
FINAL_MILESTONE_NUMBER=$([[ -n ${MILESTONE_NUMBER_EXISTING} ]] && echo "${MILESTONE_NUMBER_EXISTING}" || echo $(echo "${MILESTONE_NUMBER_CREATED_JSON}" | jq .number ))
|
||||
echo "FINAL_MILESTONE_NUMBER: ${FINAL_MILESTONE_NUMBER}"
|
||||
echo "milestone_number=${FINAL_MILESTONE_NUMBER}" >> $GITHUB_OUTPUT
|
||||
|
||||
# update PR with milestone
|
||||
- name: update PR milestone
|
||||
if: steps.extract_data.outputs.has_milestone_to_set == 1
|
||||
uses: octokit/request-action@v2.x
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
route: PATCH /repos/qgis/QGIS/issues/:pull_number
|
||||
pull_number: ${{ steps.extract_data.outputs.pr_number }}
|
||||
milestone: ${{ steps.compute_milestone.outputs.milestone_number }}
|
172
.github/workflows/pr-needs-documentation.yml
vendored
Normal file
172
.github/workflows/pr-needs-documentation.yml
vendored
Normal file
@ -0,0 +1,172 @@
|
||||
|
||||
name: 📖 PR needs documentation
|
||||
|
||||
# a message will be added to the PR to ping the author about her/his responsibility to handle the documentation issue
|
||||
# an issue is automatically created in the QGIS-Documentation repository when the PR gets merged
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- closed
|
||||
- labeled
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
ping-author-message:
|
||||
permissions:
|
||||
issues: write # for peter-evans/create-or-update-comment to create or update comment
|
||||
pull-requests: write # for peter-evans/create-or-update-comment to create or update comment
|
||||
if: github.event.action != 'closed'
|
||||
runs-on: ubuntu-latest
|
||||
name: Write comment to ping author about the pull request description
|
||||
steps:
|
||||
|
||||
- name: Create comment about documentation
|
||||
if: github.event.label.name == 'Needs Documentation'
|
||||
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0
|
||||
with:
|
||||
token: ${{ secrets.GH_TOKEN_BOT }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
@${{ github.event.pull_request.user.login }}
|
||||
This pull request has been tagged as **requiring documentation**.
|
||||
|
||||
A documentation ticket will be opened at https://github.com/qgis/QGIS-Documentation **when this PR is merged**.
|
||||
|
||||
**Please update the description** (not the comments) with helpful description and screenshot to help the work from documentors.
|
||||
Also, any commit having [needs-doc] or [Needs Documentation] in will see its message pushed to the issue, so please be as verbose as you can.
|
||||
|
||||
Thank you!
|
||||
reactions: 'rocket'
|
||||
|
||||
- name: Create comment about changelog
|
||||
if: github.event.label.name == 'Changelog'
|
||||
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0
|
||||
with:
|
||||
token: ${{ secrets.GH_TOKEN_BOT }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
@${{ github.event.pull_request.user.login }}
|
||||
|
||||
This pull request has been tagged for the [changelog](https://www.qgis.org/en/site/forusers/visualchangelogs.html).
|
||||
|
||||
* The description will be harvested so please provide a "nearly-ready" text for the final changelog
|
||||
* If possible, add a nice illustration of the feature. Only the **first** one in the description will be harvested (GIF accepted as well)
|
||||
* If you can, it's better to give credits to your sponsor, see below for different formats.
|
||||
|
||||
You can edit the description.
|
||||
|
||||
<details>
|
||||
<summary>Format available for credits</summary>
|
||||
<br />
|
||||
|
||||
- `Funded by NAME`
|
||||
- `Funded by URL`
|
||||
- `Funded by NAME URL`
|
||||
- `Sponsored by NAME`
|
||||
- `Sponsored by URL`
|
||||
- `Sponsored by NAME URL`
|
||||
|
||||
</details>
|
||||
|
||||
Thank you!
|
||||
reactions: '+1'
|
||||
|
||||
|
||||
update-milestone:
|
||||
if: github.event.pull_request.merged && ( ( github.event.action == 'closed' && contains( github.event.pull_request.labels.*.name, 'Needs Documentation') ) || github.event.label.name == 'Needs Documentation' )
|
||||
# Update the milestone (if necessary)
|
||||
name: Update final milestone
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
contents: read
|
||||
uses: ./.github/workflows/pr-auto-milestone.yml
|
||||
|
||||
create-doc-issue:
|
||||
if: github.event.pull_request.merged && ( ( github.event.action == 'closed' && contains( github.event.pull_request.labels.*.name, 'Needs Documentation') ) || github.event.label.name == 'Needs Documentation' )
|
||||
runs-on: ubuntu-latest
|
||||
name: Create issue on doc repo for labeled issue
|
||||
steps:
|
||||
|
||||
# transform the milestone (e.g. 3.10.4) to a doc label (3.10)
|
||||
- name: QGIS milestone to Doc label
|
||||
id: milestone2label
|
||||
env:
|
||||
MILESTONE: ${{ github.event.pull_request.milestone.title }}
|
||||
run: |
|
||||
LABEL=$(sed -r 's/^([[:digit:]]\.[[:digit:]]+)(\.[[:digit:]]+)?$/\1/' <<< ${MILESTONE})
|
||||
echo ${LABEL}
|
||||
echo "label=${LABEL}" >> $GITHUB_OUTPUT
|
||||
|
||||
# get the PR body
|
||||
- name: Get PR body as text
|
||||
id: get_pr_body
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PR_BODY: "${{ github.event.pull_request.body }}"
|
||||
run: |
|
||||
echo 'body<<EOF' >> $GITHUB_OUTPUT
|
||||
echo "$PR_BODY" >> $GITHUB_OUTPUT
|
||||
echo 'EOF' >> $GITHUB_OUTPUT
|
||||
|
||||
# get commits from the PR
|
||||
- name: Get PR commits
|
||||
uses: octokit/request-action@dad4362715b7fb2ddedf9772c8670824af564f0d # v2.4.0
|
||||
id: get_pr_commits
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
route: GET /repos/qgis/QGIS/pulls/{pull_number}/commits
|
||||
pull_number: ${{ github.event.pull_request.number }}
|
||||
|
||||
# extracts the matching commits
|
||||
- name: Filter commits with \[needs?.doc(umentation)?s?\]
|
||||
id: filtered_commits
|
||||
env:
|
||||
JSON_DATA: ${{ steps.get_pr_commits.outputs.data }}
|
||||
run: |
|
||||
COMMITS_MESSAGES=$(echo ${JSON_DATA} | jq '.[].commit.message | select( . |test("\\[(feature|needs?.doc(umentation)?s?)\\]"; "i")) | sub("\\[needs?.doc(umentation)?s?\\]"; "\n\n\n\n"; "i")')
|
||||
echo "commits=$(echo ${COMMITS_MESSAGES} | tr -d '\n' )" >> $GITHUB_OUTPUT
|
||||
|
||||
# create the documentation issue
|
||||
- name: Create Documentation issue
|
||||
id: doc_issue
|
||||
uses: dacbd/create-issue-action@cdb57ab6ff8862aa09fee2be6ba77a59581921c2 # v2.0.0
|
||||
with:
|
||||
token: ${{ secrets.GH_TOKEN_BOT }}
|
||||
owner: qgis
|
||||
repo: QGIS-Documentation
|
||||
title: ${{ format('{0} (Request in QGIS)', github.event.pull_request.title) }}
|
||||
# do not modify the QGIS version, an action automatically creates a label in the doc repo
|
||||
# this is not possible to set labels directly due to security reasons
|
||||
# the token is in clear, so no rights are given to qgis-bot
|
||||
body: |
|
||||
### Request for documentation
|
||||
From pull request qgis/QGIS#${{ github.event.pull_request.number }}
|
||||
Author: @${{ github.event.pull_request.user.login }}
|
||||
QGIS version: ${{ steps.milestone2label.outputs.label }}
|
||||
|
||||
**${{ github.event.pull_request.title }}**
|
||||
|
||||
### PR Description:
|
||||
${{ steps.get_pr_body.outputs.body }}
|
||||
|
||||
### Commits tagged with [need-docs] or [FEATURE]
|
||||
${{ steps.filtered_commits.outputs.commits }}
|
||||
|
||||
# write comment to ping the PR author
|
||||
- name: Create comment
|
||||
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0
|
||||
with:
|
||||
token: ${{ secrets.GH_TOKEN_BOT }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
@${{ github.event.pull_request.user.login }}
|
||||
A documentation ticket has been opened at https://github.com/qgis/QGIS-Documentation/issues/${{ steps.doc_issue.outputs.number }}
|
||||
It is **your** responsibility to visit this ticket and add as much detail as possible for the documentation team to correctly document this change.
|
||||
Thank you!
|
||||
reactions: 'rocket'
|
20
.github/workflows/pr_unstale_commit.yml
vendored
Normal file
20
.github/workflows/pr_unstale_commit.yml
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
name: Remove Labels PR Commit
|
||||
|
||||
on: pull_request_target
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
remove_labels:
|
||||
permissions:
|
||||
pull-requests: write # for actions-ecosystem/action-remove-labels to remove PR labels
|
||||
if: contains(github.event.pull_request.labels.*.name, 'stale')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions-ecosystem/action-remove-labels@2ce5d41b4b6aa8503e285553f75ed56e0a40bae0 #v1.0
|
||||
if: ${{ github.event.comment.user.url != 'https://github.com/apps/github-actions' }}
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
labels: |
|
||||
stale
|
106
.github/workflows/pre-commit.yaml
vendored
Normal file
106
.github/workflows/pre-commit.yaml
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
name: Pre-commit checks
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
push:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
pre-commit:
|
||||
if: github.event_name != 'issue_comment' || github.event.comment.body == '/fix-precommit'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
contents: write
|
||||
issues: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 200
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.13'
|
||||
|
||||
- name: Install pre-commit
|
||||
run: pip install pre-commit
|
||||
|
||||
- name: Run pre-commit
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" == "pull_request_target" ]; then
|
||||
git fetch origin ${{ github.event.pull_request.base.ref }}:refs/remotes/origin/${{ github.event.pull_request.base.ref }}
|
||||
git fetch origin pull/${{ github.event.pull_request.number }}/head:pr-head
|
||||
MODIFIED_FILES=($(git diff --name-only origin/${{ github.event.pull_request.base.ref }} pr-head))
|
||||
elif [ "${{ github.event_name }}" == "push" ]; then
|
||||
MODIFIED_FILES=($(git diff --name-only ${{ github.event.before }} ${{ github.sha }}))
|
||||
else
|
||||
echo "Unsupported event: ${{ github.event_name }}"
|
||||
exit 1
|
||||
fi
|
||||
echo "Modified files: ${MODIFIED_FILES[@]}"
|
||||
pre-commit run --files ${MODIFIED_FILES[@]} || (echo "pre-commit failed. Attempting to auto-fix..." && exit 1)
|
||||
|
||||
- name: Commit fixes
|
||||
if: failure()
|
||||
run: |
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add .
|
||||
git commit -m "auto-fix pre-commit issues" || echo "No changes to commit"
|
||||
|
||||
- name: Auto-commit fixes
|
||||
if: failure() && github.event_name == 'push'
|
||||
run: git push || echo "Failed to push changes. Please check permissions or conflicts."
|
||||
|
||||
- name: Push fixes to new branch
|
||||
if: failure() && github.event_name == 'issue_comment' && github.event.comment.body == '/fix-precommit' && github.event.issue.pull_request
|
||||
run: |
|
||||
git checkout -b fix/pre-commit-${{ github.event.pull_request.head.sha }}
|
||||
git push origin fix/pre-commit-${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Listen for `/fix-precommit` comment
|
||||
if: failure() && github.event_name == 'issue_comment' && github.event.comment.body == '/fix-precommit' && github.event.issue.pull_request
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const forkOwner = context.payload.pull_request.head.repo.owner.login;
|
||||
const forkRepo = context.payload.pull_request.head.repo.name;
|
||||
const forkBranch = context.payload.pull_request.head.ref;
|
||||
const baseRepoOwner = context.repo.owner;
|
||||
const baseRepoName = context.repo.repo;
|
||||
const headBranch = `fix/pre-commit-${context.payload.pull_request.head.sha}`;
|
||||
|
||||
await github.rest.pulls.create({
|
||||
owner: forkOwner,
|
||||
repo: forkRepo,
|
||||
title: "Auto-fix: Pre-commit issues",
|
||||
head: `${baseRepoOwner}:${headBranch}`,
|
||||
base: forkBranch,
|
||||
body: "This PR attempts to fix pre-commit issues automatically.",
|
||||
});
|
||||
|
||||
- name: Comment on PR if pre-commit failed
|
||||
if: failure() && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const { data: comments } = await github.rest.issues.listComments({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number
|
||||
});
|
||||
|
||||
const existingComment = comments.find(comment => comment.body.includes("⚠️ Pre-commit checks failed."));
|
||||
if (!existingComment) {
|
||||
await github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: "⚠️ Pre-commit checks failed. You can fix issues locally by running `pre-commit run --all-files`. Alternatively, comment `/fix-precommit` on this pull request, and I will attempt to auto-fix and open a new pull request for you."
|
||||
});
|
||||
}
|
50
.github/workflows/release.yml
vendored
Normal file
50
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
name: 🚀 Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'final-*_*_*'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
permissions:
|
||||
contents: none
|
||||
name: Create Release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Set env
|
||||
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
||||
|
||||
- name: Version URL
|
||||
run: |
|
||||
VERSION=$(echo ${RELEASE_VERSION} | cut -d '-' -f 2 )
|
||||
|
||||
if [ ${VERSION: -1} = "0" ]
|
||||
then
|
||||
VERSION=$(echo ${VERSION} | cut -d '_' -f1,2 | sed 's/_/\./g')
|
||||
echo "version_url=https://changelog.qgis.org/en/qgis/version/${VERSION}" >> $GITHUB_ENV
|
||||
else
|
||||
PREVIOUS=$(echo ${VERSION} | sed 's/_/\./g' | awk -F. -v OFS=. 'NF==1{print ++$NF}; NF>1{if(length($NF+1)>length($NF))$(NF-1)++; $NF=sprintf("%0*d", length($NF), ($NF-1)%(10^length($NF))); print}' | sed 's/\./_/g')
|
||||
echo "version_url=https://github.com/qgis/QGIS/compare/final-${PREVIOUS}%5E...final-${VERSION}" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Version name
|
||||
run: |
|
||||
VERSION_NAME=$(echo ${{ env.RELEASE_VERSION }} | cut -d '-' -f 2 | sed 's/_/\./g')
|
||||
echo "version_name=${VERSION_NAME}" >> $GITHUB_ENV
|
||||
|
||||
- name: Create release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN_BOT }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: ${{ env.version_name }}
|
||||
body: ${{ env.version_url }}
|
||||
draft: false
|
||||
prerelease: false
|
455
.github/workflows/run-tests.yml
vendored
Normal file
455
.github/workflows/run-tests.yml
vendored
Normal file
@ -0,0 +1,455 @@
|
||||
name: 🧪 QGIS tests
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- release-**
|
||||
- queued_ltr_backports
|
||||
paths:
|
||||
- 'src/**'
|
||||
- 'external/**'
|
||||
- 'python/**'
|
||||
- 'tests/**'
|
||||
- 'CMakeLists.txt'
|
||||
- '.github/workflows/run-tests.yml'
|
||||
- '.docker/**'
|
||||
- '.ci/**'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- release-**
|
||||
- queued_ltr_backports
|
||||
# paths cannot be filtered on this workflow on pull request as it is a required one in the branch protection
|
||||
# feature request and hacks: https://github.community/t/feature-request-conditional-required-checks/16761
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
env:
|
||||
QGIS_WORKSPACE: ${{ github.workspace }} # used in docker compose
|
||||
RUN_FLAKY_TESTS: ${{ contains( github.event.pull_request.labels.*.name, 'run flaky tests') }}
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- distro-version: '24.04'
|
||||
qt-version: 5
|
||||
run-tests: true
|
||||
with-qt6: OFF
|
||||
with-qt5: ON
|
||||
with-3d: ON
|
||||
with-quick: ON
|
||||
with-clazy: ON
|
||||
with-grass7: OFF
|
||||
with-grass8: OFF
|
||||
with-webengine: OFF
|
||||
with-pdf4qt: OFF
|
||||
with-compile-commands: ON
|
||||
# LD_PRELOAD: /lib/x86_64-linux-gnu/libSegFault.so
|
||||
experimental: false
|
||||
unity-builds: ON
|
||||
|
||||
- distro-version: '39'
|
||||
qt-version: 6
|
||||
run-tests: true
|
||||
with-qt6: ON
|
||||
with-qt5: OFF
|
||||
with-3d: ON
|
||||
with-quick: ON
|
||||
with-clazy: OFF
|
||||
with-grass7: OFF
|
||||
with-grass8: ON
|
||||
with-webengine: ON
|
||||
with-pdf4qt: ON
|
||||
with-compile-commands: OFF
|
||||
LD_PRELOAD: ''
|
||||
experimental: false
|
||||
unity-builds: ON
|
||||
|
||||
|
||||
fail-fast: false
|
||||
|
||||
outputs:
|
||||
compile_outcome: ${{ steps.compile.outcome }}
|
||||
tests_failing: ${{ steps.tests.outputs.TESTS_FAILING }}
|
||||
cdash_url: ${{ steps.tests.outputs.CDASH_URL }}
|
||||
runners_outcome: ${{ steps.runners.outcome }}
|
||||
|
||||
steps:
|
||||
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # main
|
||||
with:
|
||||
tool-cache: true
|
||||
large-packages: false
|
||||
docker-images: false
|
||||
swap-storage: true
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set vars
|
||||
env:
|
||||
GITHUB_EVENT_NAME: ${{ github.event_name }}
|
||||
GITHUB_REF: ${{ github.ref }}
|
||||
GITHUB_PR_NUMBER: ${{github.event.number}}
|
||||
run: |
|
||||
# Be aware that these instructions are duplicated in run-tests job
|
||||
DOCKER_TAG=$(echo $( [[ ${GITHUB_EVENT_NAME} == pull_request ]] && echo ${GITHUB_BASE_REF} || echo ${GITHUB_REF##*/} ) | sed 's/^master$/latest/')
|
||||
CTEST_BUILD_NAME=$( [[ ${GITHUB_EVENT_NAME} == pull_request ]] && echo "PR${GITHUB_PR_NUMBER}" || echo ${GITHUB_REF##*/} )"_${GITHUB_SHA}"
|
||||
echo "DOCKER_TAG=${DOCKER_TAG}" >> $GITHUB_ENV
|
||||
echo "CTEST_BUILD_NAME=${CTEST_BUILD_NAME}" >> $GITHUB_ENV
|
||||
echo "QT_VERSION=${{ matrix.qt-version }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Print vars
|
||||
run: |
|
||||
echo DOCKER_TAG: ${DOCKER_TAG}
|
||||
echo CTEST_BUILD_NAME: ${CTEST_BUILD_NAME}
|
||||
echo QT_VERSION: ${QT_VERSION}
|
||||
|
||||
- name: Login to Docker Hub
|
||||
if: ${{ github.event_name == 'push' && github.repository == 'qgis/QGIS' }}
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Build Docker Container with Build Environment
|
||||
id: docker-build
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: .docker/qgis3-qt${{ matrix.qt-version }}-build-deps.dockerfile
|
||||
tags: qgis/qgis3-build-deps-${{ matrix.distro-version }}-qt${{ matrix.qt-version }}:${{ github.event.pull_request.base.ref || github.ref_name }}
|
||||
push: ${{ github.event_name == 'push' && github.repository == 'qgis/QGIS' }}
|
||||
pull: true
|
||||
build-args:
|
||||
DISTRO_VERSION=${{ matrix.distro-version }}
|
||||
|
||||
- name: Tag image
|
||||
run: docker tag ${{ steps.docker-build.outputs.imageid }} qgis3-build-deps
|
||||
|
||||
- name: Restore build cache
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: /home/runner/QGIS/.ccache
|
||||
key: build-ccache-${{ matrix.distro-version }}-qt${{ matrix.qt-version }}-${{ github.event.pull_request.base.ref || github.ref_name }}
|
||||
restore-keys: |
|
||||
build-ccache-${{ matrix.distro-version }}-qt${{ matrix.qt-version }}-master
|
||||
|
||||
- name: Compile QGIS
|
||||
id: compile
|
||||
run: |
|
||||
docker run -t --name qgis_container \
|
||||
-v $(pwd):/root/QGIS \
|
||||
-v /home/runner/QGIS/.ccache:/root/.ccache \
|
||||
--env-file .docker/docker-variables.env \
|
||||
--env CCACHE_DIR=/root/.ccache \
|
||||
--env PUSH_TO_CDASH=true \
|
||||
--env WITH_QT5=${{ matrix.with-qt5 }} \
|
||||
--env BUILD_WITH_QT6=${{ matrix.with-qt6 }} \
|
||||
--env WITH_QUICK=${{ matrix.with-quick }} \
|
||||
--env WITH_3D=${{ matrix.with-3d }} \
|
||||
--env WITH_GRASS7=${{ matrix.with-grass7 }} \
|
||||
--env WITH_GRASS8=${{ matrix.with-grass8 }} \
|
||||
--env WITH_QTWEBENGINE=${{ matrix.with-webengine }} \
|
||||
--env WITH_PDF4QT=${{ matrix.with-pdf4qt }} \
|
||||
--env LD_PRELOAD=${{ matrix.LD_PRELOAD }} \
|
||||
--env WITH_CLAZY=${{ matrix.with-clazy }} \
|
||||
--env WITH_COMPILE_COMMANDS=${{ matrix.with-compile-commands }} \
|
||||
--env ENABLE_UNITY_BUILDS=${{ matrix.unity-builds }} \
|
||||
qgis3-build-deps \
|
||||
/root/QGIS/.docker/docker-qgis-build.sh
|
||||
|
||||
- name: Save build cache for push only
|
||||
uses: actions/cache/save@v4
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
with:
|
||||
path: /home/runner/QGIS/.ccache
|
||||
key: build-ccache-${{ matrix.distro-version }}-qt${{ matrix.qt-version }}-${{ github.ref_name }}-${{ github.run_id }}
|
||||
|
||||
- name: Push artifact
|
||||
id: push_artifact
|
||||
if: ${{ matrix.run-tests }}
|
||||
run: tar --exclude='*.o' -cvzf build.tgz build
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ matrix.run-tests }}
|
||||
with:
|
||||
name: build-${{ matrix.distro-version }}-qt${{ matrix.qt-version }}.tgz
|
||||
path: ./build.tgz
|
||||
retention-days: 1
|
||||
|
||||
# - name: Test QGIS runners
|
||||
# id: runners
|
||||
# if: ${{ matrix.distro-version == env.DEFAULT_DISTRO_VERSION }}
|
||||
# run: |
|
||||
# docker run -d --name qgis-testing-environment \
|
||||
# -v $(pwd):/root/QGIS \
|
||||
# -v $(pwd)/tests/src/python:/tests_directory \
|
||||
# -v $(pwd)/.docker/qgis_resources/test_runner:/usr/bin/test_runner \
|
||||
# -v $(pwd)/.docker/qgis_resources/supervisor:/etc/supervisor \
|
||||
# -e QGIS_BUILD_PATH=/root/QGIS/build/output/bin/qgis \
|
||||
# -e TEST_RUNNER_PATH=/usr/bin/test_runner/qgis_testrunner.py \
|
||||
# -e DISPLAY=:99 \
|
||||
# qgis_image \
|
||||
# /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
|
||||
# # Wait for xvfb to finish starting
|
||||
# printf "Waiting for the docker...🐳..."
|
||||
# sleep 10
|
||||
# echo " done 🥩"
|
||||
#
|
||||
# declare -A testrunners
|
||||
# # Passing cases:
|
||||
# testrunners["test_testrunner.run_passing"]=0
|
||||
# testrunners["test_testrunner.run_skipped_and_passing"]=0
|
||||
# # Failing cases:
|
||||
# testrunners["test_testrunner"]=1
|
||||
# testrunners["test_testrunner.run_all"]=1
|
||||
# testrunners["test_testrunner.run_failing"]=1
|
||||
# set +e # do not exit on error
|
||||
# # Run tests in the docker
|
||||
# for i in "${!testrunners[@]}"
|
||||
# do
|
||||
# echo "::group::docker_test_runner_${i}"
|
||||
# echo "test ${i}..."
|
||||
# docker exec -i qgis-testing-environment sh -c "cd /tests_directory && /usr/bin/test_runner/qgis_testrunner.sh ${i}"
|
||||
# [[ $? -eq "${testrunners[$i]}" ]] && echo "success" || exit 1
|
||||
# echo "::endgroup::"
|
||||
# done
|
||||
# set -e # switch back
|
||||
# docker stop qgis-testing-environment
|
||||
|
||||
run-tests:
|
||||
name: Run tests
|
||||
env:
|
||||
QGIS_WORKSPACE: ${{ github.workspace }} # used in docker compose
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: build
|
||||
if: always()
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
qt-version: [5, 6]
|
||||
test-batch: [ALL_BUT_PROVIDERS, POSTGRES, HANA, SQLSERVER]
|
||||
|
||||
include:
|
||||
- qt-version: 5
|
||||
distro-version: 24.04
|
||||
docker-target: binary-only
|
||||
|
||||
- qt-version: 6
|
||||
distro-version: 39
|
||||
docker-target: binary-only
|
||||
|
||||
- qt-version: 5
|
||||
distro-version: 24.04
|
||||
test-batch: ORACLE
|
||||
docker-target: binary-for-oracle
|
||||
|
||||
exclude:
|
||||
- qt-version: 6
|
||||
test-batch: HANA
|
||||
|
||||
- qt-version: 6
|
||||
test-batch: POSTGRES
|
||||
|
||||
- qt-version: 6
|
||||
test-batch: SQLSERVER
|
||||
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # main
|
||||
with:
|
||||
tool-cache: true
|
||||
large-packages: false
|
||||
docker-images: false
|
||||
swap-storage: true
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set vars
|
||||
env:
|
||||
GITHUB_EVENT_NAME: ${{ github.event_name }}
|
||||
GITHUB_REF: ${{ github.ref }}
|
||||
GITHUB_PR_NUMBER: ${{github.event.number}}
|
||||
run: |
|
||||
# Be aware that these instructions are duplicated in build job
|
||||
CTEST_BUILD_NAME=$( [[ ${GITHUB_EVENT_NAME} == pull_request ]] && echo "PR${GITHUB_PR_NUMBER}" || echo ${GITHUB_REF##*/} )"_${GITHUB_SHA}_${{ matrix.test-batch }}"
|
||||
echo "CTEST_BUILD_NAME=${CTEST_BUILD_NAME}" >> $GITHUB_ENV
|
||||
echo "QT_VERSION=${{ matrix.qt-version }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Print vars
|
||||
run: |
|
||||
echo CTEST_BUILD_NAME: ${CTEST_BUILD_NAME}
|
||||
|
||||
- name: Login to Docker Hub
|
||||
if: ${{ github.event_name == 'push' && github.repository == 'qgis/QGIS' }}
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Build Docker Container with Testing Environment
|
||||
id: docker-build
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: .docker/qgis3-qt${{ matrix.qt-version }}-build-deps.dockerfile
|
||||
tags: qgis/qgis3-qt${{ matrix.qt-version }}-build-deps-bin-only:${{ github.event.pull_request.base.ref || github.ref_name }}
|
||||
push: ${{ github.event_name == 'push' && github.repository == 'qgis/QGIS' }}
|
||||
pull: true
|
||||
target: ${{ matrix.docker-target }}
|
||||
build-args:
|
||||
DISTRO_VERSION=${{ matrix.distro-version }}
|
||||
|
||||
- name: Tag image
|
||||
run: docker tag ${{ steps.docker-build.outputs.imageid }} qgis3-build-deps-binary-image
|
||||
|
||||
- name: Print disk space
|
||||
run: |
|
||||
echo "DOCKER IMAGES"
|
||||
docker images
|
||||
echo "DF -H"
|
||||
sudo df -h
|
||||
|
||||
- name: Download build artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: build-${{ matrix.distro-version }}-qt${{ matrix.qt-version }}.tgz
|
||||
path: .
|
||||
|
||||
- name: Extract build artifact
|
||||
run: |
|
||||
tar xvzf build.tgz
|
||||
rm -Rf build.tgz
|
||||
|
||||
- name: Print disk space
|
||||
run: |
|
||||
echo "DF -H"
|
||||
sudo df -h
|
||||
|
||||
- name: Run tests
|
||||
id: tests
|
||||
env:
|
||||
TEST_BATCH: ${{matrix.test-batch}}
|
||||
QGIS_COMMON_GIT_DIR: ${{ github.workspace }}
|
||||
GITHUB_SHA: ${{ github.sha }}
|
||||
run: |
|
||||
DOCKERFILE=$( ( [[ ${{ matrix.test-batch }} == "ORACLE" ]] && echo "docker-compose-testing-oracle.yml" ) \
|
||||
|| ( [[ ${{ matrix.test-batch }} == "POSTGRES" ]] && echo "docker-compose-testing-postgres.yml" ) \
|
||||
|| ( [[ ${{ matrix.test-batch }} == "SQLSERVER" ]] && echo "docker-compose-testing-mssql.yml" ) \
|
||||
|| echo "docker-compose-testing.yml" )
|
||||
[[ ${{ matrix.test-batch }} == "ORACLE" ]] && sudo rm -rf /usr/share/dotnet/sdk
|
||||
echo "TEST_BATCH=$TEST_BATCH"
|
||||
echo "DOCKERFILE=$DOCKERFILE"
|
||||
mkdir -p /tmp/webdav_tests && chmod 777 /tmp/webdav_tests
|
||||
mkdir -p /tmp/minio_tests/test-bucket && chmod -R 777 /tmp/minio_tests
|
||||
docker compose -f .docker/$DOCKERFILE run -e GITHUB_SHA=$GITHUB_SHA qgis-deps /root/QGIS/.docker/docker-qgis-test.sh $TEST_BATCH
|
||||
|
||||
- name: Fix permissions on test report
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
sudo chmod -R 777 qgis_test_report
|
||||
|
||||
- name: Dump report contents
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
MD_REPORT_FILE="qgis_test_report/summary.md"; [ -f "$MD_REPORT_FILE" ] && cat "$MD_REPORT_FILE" || true
|
||||
|
||||
- name: Save PR number to test report
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
echo ${{ github.event.number }} | tee qgis_test_report/pr_number
|
||||
echo ${{ github.event.pull_request.head.sha }} | tee qgis_test_report/git_commit
|
||||
|
||||
- name: Archive test results report
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: test-results-qt${{ matrix.qt-version }}
|
||||
path: qgis_test_report
|
||||
|
||||
clang-tidy:
|
||||
if: github.event_name == 'pull_request'
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- distro-version: '24.04'
|
||||
qt-version: 5
|
||||
|
||||
steps:
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # main
|
||||
with:
|
||||
tool-cache: true
|
||||
large-packages: false
|
||||
docker-images: false
|
||||
swap-storage: true
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Login to Docker Hub
|
||||
if: ${{ github.event_name == 'push' && github.repository == 'qgis/QGIS' }}
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Build Docker Container with Testing Environment
|
||||
id: docker-build
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: .docker/qgis3-qt${{ matrix.qt-version }}-build-deps.dockerfile
|
||||
tags: qgis/qgis3-qt${{ matrix.qt-version }}-build-deps-bin-only:${{ github.event.pull_request.base.ref || github.ref_name }}
|
||||
push: ${{ github.event_name == 'push' && github.repository == 'qgis/QGIS' }}
|
||||
pull: true
|
||||
target: ${{ matrix.docker-target }}
|
||||
build-args:
|
||||
DISTRO_VERSION=${{ matrix.distro-version }}
|
||||
|
||||
- name: Tag image
|
||||
run: docker tag ${{ steps.docker-build.outputs.imageid }} qgis3-build-deps-binary-image
|
||||
|
||||
- name: Download build artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: build-${{ matrix.distro-version }}-qt${{ matrix.qt-version }}.tgz
|
||||
path: .
|
||||
|
||||
- name: Extract build artifact
|
||||
run: |
|
||||
tar xvzf build.tgz
|
||||
rm -Rf build.tgz
|
||||
|
||||
- name: Run Clang-Tidy
|
||||
run: |
|
||||
docker run -t --name qgis_container \
|
||||
-v $(pwd):/root/QGIS \
|
||||
-v /home/runner/QGIS/.ccache:/root/.ccache \
|
||||
--env-file .docker/docker-variables.env \
|
||||
qgis3-build-deps-binary-image \
|
||||
/root/QGIS/.docker/docker-qgis-clangtidy.sh
|
38
.github/workflows/sipify-bot.yml
vendored
Normal file
38
.github/workflows/sipify-bot.yml
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
name: Run sipify
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
|
||||
jobs:
|
||||
sipify:
|
||||
runs-on: [ubuntu-latest]
|
||||
steps:
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Install Requirements
|
||||
run: pip install nose2 mock termcolor pyyaml
|
||||
|
||||
- name: Get PR branch
|
||||
uses: alessbell/pull-request-comment-branch@ef3408c9757d05f89cb525036383033a313758a0 # v2.1.0
|
||||
if: ${{ github.event_name == 'issue_comment' }}
|
||||
id: comment-branch
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: run sipify
|
||||
run: ./scripts/sipify_all.sh -m
|
||||
|
||||
- name: commit
|
||||
run: |
|
||||
git config user.name qgis-bot
|
||||
git config user.email bot@qgis.org
|
||||
git add .
|
||||
git commit -m "auto sipify 🍺" || echo "nothing to commit"
|
||||
git push
|
93
.github/workflows/stale.yml
vendored
Normal file
93
.github/workflows/stale.yml
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
name: 👓 Handle stale issues
|
||||
on:
|
||||
schedule:
|
||||
- cron: "30 2 * * *"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
permissions:
|
||||
issues: write # for actions/stale to close stale issues
|
||||
pull-requests: write # for actions/stale to close stale PRs
|
||||
if: github.repository_owner == 'qgis'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-pr-message: >
|
||||
The QGIS project highly values your contribution and would love to see
|
||||
this work merged!
|
||||
Unfortunately this PR has not had any activity in the last 14 days and
|
||||
is being automatically marked as "stale".
|
||||
If you think this pull request should be merged, please check
|
||||
|
||||
- that all unit tests are passing
|
||||
|
||||
- that all comments by reviewers have been addressed
|
||||
|
||||
- that there is enough information for reviewers, in particular
|
||||
|
||||
- link to any issues which this pull request fixes
|
||||
|
||||
- add a description of workflows which this pull request fixes
|
||||
|
||||
- add screenshots if applicable
|
||||
|
||||
- that you have written unit tests where possible
|
||||
|
||||
In case you should have any uncertainty, please leave a comment and we will
|
||||
be happy to help you proceed with this pull request.
|
||||
|
||||
If there is no further activity on this pull request, it will be closed in a
|
||||
week.
|
||||
|
||||
|
||||
close-pr-message: >
|
||||
While we hate to see this happen, this PR has been automatically closed because
|
||||
it has not had any activity in the last 21 days. If this pull request should be
|
||||
reconsidered, please follow the guidelines in the previous comment and reopen
|
||||
this pull request. Or, if you have any further questions, just ask! We love to
|
||||
help, and if there's anything the QGIS project can do to help push this PR forward
|
||||
please let us know how we can assist.
|
||||
|
||||
|
||||
stale-pr-label: 'stale'
|
||||
exempt-pr-labels: 'Merge After Thaw,Frozen'
|
||||
days-before-pr-stale: 14
|
||||
days-before-pr-close: 7
|
||||
|
||||
stale-issue-message: >
|
||||
The QGIS project highly values your report and would love to see it addressed.
|
||||
However, this issue has been left in feedback mode for the last 14 days and is
|
||||
being automatically marked as "stale".
|
||||
|
||||
If you would like to continue with this issue, please provide any missing information
|
||||
or answer any open questions. If you could resolve the issue yourself meanwhile,
|
||||
please leave a note for future readers with the same problem and close the issue.
|
||||
|
||||
In case you should have any uncertainty, please leave a comment and we will be
|
||||
happy to help you proceed with this issue.
|
||||
|
||||
If there is no further activity on this issue, it will be closed in a week.
|
||||
|
||||
|
||||
close-issue-message: >
|
||||
While we hate to see this happen, this issue has been automatically closed because
|
||||
it has not had any activity in the last 42 days despite being marked as feedback.
|
||||
If this issue should be reconsidered, please follow the guidelines in the previous
|
||||
comment and reopen this issue.
|
||||
|
||||
Or, if you have any further questions, there are also
|
||||
[further support channels](https://www.qgis.org/en/site/forusers/support.html)
|
||||
that can help you.
|
||||
|
||||
|
||||
stale-issue-label: 'stale'
|
||||
only-issue-labels: 'feedback'
|
||||
days-before-issue-stale: 14
|
||||
days-before-issue-close: 28
|
||||
|
||||
operations-per-run: 1000
|
21
.github/workflows/unstale.yml
vendored
Normal file
21
.github/workflows/unstale.yml
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
name: Remove Labels
|
||||
|
||||
on: [issue_comment, pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
remove_labels:
|
||||
permissions:
|
||||
issues: write # for actions-ecosystem/action-remove-labels to remove issue labels
|
||||
pull-requests: write # for actions-ecosystem/action-remove-labels to remove PR labels
|
||||
if: contains(github.event.issue.labels.*.name, 'stale')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions-ecosystem/action-remove-labels@v1
|
||||
if: ${{ github.event.comment.user.url != 'https://github.com/apps/github-actions' }}
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
labels: |
|
||||
stale
|
36
.github/workflows/vcpkg-update-report.yml
vendored
Normal file
36
.github/workflows/vcpkg-update-report.yml
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
---
|
||||
name: 🧮 Vcpkg report
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'vcpkg/**'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
vcpkg-check:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 30
|
||||
|
||||
- name: Generate diff report
|
||||
id: vcpkg_diff
|
||||
uses: ./.github/actions/vcpkg_update_report
|
||||
with:
|
||||
vcpkg-manifest-dir: vcpkg
|
||||
triplet: x64-linux
|
||||
features: 3d,bindings,gui,opencl,quick,server
|
||||
|
||||
- name: Schedule report comment
|
||||
uses: ./.github/actions/post_sticky_comment
|
||||
if: github.event_name == 'pull_request'
|
||||
with:
|
||||
marker: vcpkg-report
|
||||
body: |
|
||||
### 🧮 Vcpkg update report
|
||||
${{ steps.vcpkg_diff.outputs.report }}
|
||||
pr: ${{ github.event.number }}
|
152
.github/workflows/windows-qt6.yml
vendored
Normal file
152
.github/workflows/windows-qt6.yml
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
---
|
||||
name: 🪟 Windows Qt6
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- release-**
|
||||
pull_request:
|
||||
release:
|
||||
types: ['published']
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: build (windows)
|
||||
runs-on: windows-2022
|
||||
|
||||
steps:
|
||||
- name: 🐣 Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: 🔨 Uninstall system cmake
|
||||
shell: bash
|
||||
run: |
|
||||
choco uninstall cmake.install
|
||||
|
||||
- name: 🐩 Install CMake and Ninja
|
||||
uses: lukka/get-cmake@ea004816823209b8d1211e47b216185caee12cc5
|
||||
with:
|
||||
cmakeVersion: 3.31.6
|
||||
|
||||
- name: 🧽 Developer Command Prompt for Microsoft Visual C++
|
||||
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 #v1
|
||||
|
||||
- name: 🎡 Setup vcpkg
|
||||
uses: ./.github/actions/setup-vcpkg
|
||||
|
||||
- name: 🦬 Setup flex/bison
|
||||
uses: robinraju/release-downloader@daf26c55d821e836577a15f77d86ddc078948b05 #v1.12
|
||||
with:
|
||||
repository: 'lexxmark/winflexbison'
|
||||
fileName: '*.zip'
|
||||
tag: 'v2.5.24'
|
||||
extract: true
|
||||
|
||||
- name: 🛍️ Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@63069e3931dedbf3b63792097479563182fe70d1 #v1.2
|
||||
with:
|
||||
max-size: 1G
|
||||
key: build-ccache-win64-qt6-${{ github.event.pull_request.base.ref || github.ref_name }}
|
||||
save: ${{ github.event_name == 'push' }}
|
||||
|
||||
- name: 🛍️ Tune ccache configuration
|
||||
shell: bash
|
||||
run: |
|
||||
# To make ccache work properly with precompiled headers
|
||||
ccache --set-config sloppiness=pch_defines,time_macros,include_file_mtime,include_file_ctime
|
||||
|
||||
- name: 🌱 Install dependencies and generate project files
|
||||
shell: bash
|
||||
env:
|
||||
X_VCPKG_ASSET_SOURCES: x-azurl,https://assetcache.open-vcpkg.org/assetcache,,read
|
||||
run: |
|
||||
BUILD_DIR=$( cygpath "${{ github.workspace }}/build" )
|
||||
SOURCE_DIR=$( cygpath "${{ github.workspace }}" )
|
||||
|
||||
cmake -S "${SOURCE_DIR}" \
|
||||
-B "${BUILD_DIR}" \
|
||||
-G Ninja \
|
||||
-D CMAKE_BUILD_TYPE=Release \
|
||||
-D WITH_VCPKG=ON \
|
||||
-D CREATE_ZIP=ON \
|
||||
-D VCPKG_TARGET_TRIPLET=x64-windows-release \
|
||||
-D VCPKG_HOST_TRIPLET=x64-windows-release \
|
||||
-D WITH_DESKTOP=ON \
|
||||
-D WITH_3D=ON \
|
||||
-D WITH_BINDINGS=ON \
|
||||
-D ENABLE_TESTS=OFF \
|
||||
-D BUILD_WITH_QT6=ON \
|
||||
-D USE_CCACHE=ON \
|
||||
-D ENABLE_UNITY_BUILDS=ON \
|
||||
-D FLEX_EXECUTABLE="${SOURCE_DIR}/win_flex.exe" \
|
||||
-D BISON_EXECUTABLE="${SOURCE_DIR}/win_bison.exe" \
|
||||
-D SIP_BUILD_EXECUTABLE="${BUILD_DIR}\vcpkg_installed\x64-windows-release\tools\python3\Scripts\sip-build.exe" \
|
||||
-D CMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-D CMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-D WITH_QTWEBKIT=OFF \
|
||||
-D VCPKG_INSTALL_OPTIONS="--x-buildtrees-root=C:/src" \
|
||||
-D NUGET_USERNAME=${{ github.actor }} \
|
||||
-D NUGET_TOKEN=${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: 🌋 Build
|
||||
shell: bash
|
||||
run: |
|
||||
cmake --build "${{ github.workspace }}/build" --config Release
|
||||
|
||||
# - uses: m-kuhn/action-tmate@patch-1
|
||||
# if: failure()
|
||||
|
||||
- name: 📦 Package
|
||||
shell: bash
|
||||
run: |
|
||||
cmake --build "${{ github.workspace }}/build" --target bundle --config Release
|
||||
|
||||
- name: 📦 Create SDK
|
||||
# if: github.event_name == 'workflow_dispatch' || github.event_name == 'release'
|
||||
run: |
|
||||
vcpkg.exe export --zip --output-dir=./sdk --x-install-root=./build/vcpkg_installed --x-manifest-root=vcpkg
|
||||
|
||||
- name: 📤 Upload sdk
|
||||
# if: github.event_name == 'workflow_dispatch' || github.event_name == 'release'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: qgis-sdk-x64-windows
|
||||
path: |
|
||||
sdk/vcpkg-export-*.zip
|
||||
|
||||
- name: 📑 Upload dep build logs
|
||||
uses: actions/upload-artifact@v4
|
||||
if: failure()
|
||||
with:
|
||||
name: build-logs-x64-windows
|
||||
path: |
|
||||
C:/src/**/*.log
|
||||
|
||||
- name: 📤 Upload bundle
|
||||
uses: actions/upload-artifact@v4
|
||||
id: artifact-win64-qt6
|
||||
with:
|
||||
name: qgis-windows-qt6
|
||||
path: |
|
||||
build/*-win64.zip
|
||||
|
||||
|
||||
- name: Schedule download comment
|
||||
uses: ./.github/actions/post_sticky_comment
|
||||
if: github.event_name == 'pull_request'
|
||||
with:
|
||||
marker: mingw64-qt6
|
||||
body: |
|
||||
### 🪟 Windows Qt6 builds
|
||||
Download [Windows Qt6 builds of this PR for testing](${{ steps.artifact-win64-qt6.outputs.artifact-url }}).
|
||||
*(Built from commit ${{ github.event.pull_request.head.sha }})*
|
||||
pr: ${{ github.event.number }}
|
101
.github/workflows/write_failure_comment.yml
vendored
Normal file
101
.github/workflows/write_failure_comment.yml
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
name: Write test failure comment
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [🧪 QGIS tests]
|
||||
types:
|
||||
- completed
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
on-failure:
|
||||
strategy:
|
||||
matrix:
|
||||
qt-version: [ 5, 6 ]
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 'Download artifact'
|
||||
id: download_artifact
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
run_id: context.payload.workflow_run.id,
|
||||
});
|
||||
let matchArtifacts = allArtifacts.data.artifacts.filter((artifact) => {
|
||||
return artifact.name == "test-results-qt${{ matrix.qt-version }}"
|
||||
});
|
||||
if (matchArtifacts.length>0)
|
||||
{
|
||||
let download = await github.rest.actions.downloadArtifact({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
artifact_id: matchArtifacts[0].id,
|
||||
archive_format: 'zip',
|
||||
});
|
||||
let fs = require('fs');
|
||||
fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/test-results-qt${{ matrix.qt-version }}.zip`, Buffer.from(download.data));
|
||||
core.setOutput('artifact_id', matchArtifacts[0].id);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.setOutput('artifact_id', 0);
|
||||
}
|
||||
|
||||
- name: 'Unzip artifact'
|
||||
if: fromJSON(steps.download_artifact.outputs.artifact_id) > 0
|
||||
run: unzip -j test-results-qt${{ matrix.qt-version }}.zip *.md pr_number git_commit || ( e=$? && if [ $e -ne 11 ]; then exit $e; fi )
|
||||
|
||||
- name: 'Post test report markdown summary as comment on PR'
|
||||
if: fromJSON(steps.download_artifact.outputs.artifact_id) > 0
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
let fs = require('fs');
|
||||
if (fs.existsSync('./summary.md'))
|
||||
{
|
||||
const issue_number = Number(fs.readFileSync('./pr_number'));
|
||||
const git_sha = String(fs.readFileSync('./git_commit')).trim();
|
||||
const prComments = await github.rest.issues.listComments({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issue_number,
|
||||
});
|
||||
|
||||
const PREFIX = "# Tests failed for Qt ${{ matrix.qt-version }}";
|
||||
|
||||
let body = PREFIX + "\n\n";
|
||||
body += "*One or more tests failed using the build from commit " + git_sha + "*\n\n";
|
||||
|
||||
body += String(fs.readFileSync('./summary.md')) +
|
||||
"\n\n**The full test report (included comparison of rendered vs expected images) can be found [here](https://github.com/qgis/QGIS/suites/" + context.payload.workflow_run.check_suite_id + "/artifacts/${{steps.download_artifact.outputs.artifact_id}}).**\n\n" +
|
||||
"Further documentation on the QGIS test infrastructure can be found in the [Developer's Guide](https://docs.qgis.org/latest/en/docs/developers_guide/unittesting.html).";
|
||||
|
||||
const failureComment = prComments.data?.find(c => c.body.startsWith(PREFIX));
|
||||
if (!!failureComment) {
|
||||
// update the existing comment
|
||||
await github.rest.issues.updateComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
comment_id: failureComment.id,
|
||||
body: body
|
||||
});
|
||||
} else {
|
||||
// submit a new comment
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issue_number,
|
||||
body: body
|
||||
});
|
||||
}
|
||||
}
|
115
.gitignore
vendored
Normal file
115
.gitignore
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
*-stamp
|
||||
*.*~
|
||||
*.autosave
|
||||
*.aux
|
||||
*.bak
|
||||
*.diff
|
||||
*.gpkg-shm
|
||||
*.gpkg-wal
|
||||
*.log*
|
||||
*.orig
|
||||
*.out
|
||||
*.prepare
|
||||
*.pro.user
|
||||
*.py.temp
|
||||
*.pyc
|
||||
*.sortinc
|
||||
*.stash
|
||||
*.tex
|
||||
*.tmp
|
||||
*.toc
|
||||
*~
|
||||
.*.swp
|
||||
.DS_Store
|
||||
.cache/
|
||||
.gdb_history
|
||||
.idea
|
||||
.kdev4/
|
||||
.project
|
||||
.pydevproject
|
||||
.venv
|
||||
.vscode
|
||||
.vs
|
||||
.devcontainer
|
||||
.worktrees
|
||||
CMakePresets.json
|
||||
/CMakeLists.txt.user
|
||||
/CMakeLists.txt.user.*
|
||||
/build*
|
||||
Makefile
|
||||
Testing/*
|
||||
Thumb.db
|
||||
api_doc
|
||||
compile_commands.json
|
||||
debian/*.debhelper
|
||||
debian/*.substvars
|
||||
debian/qgis.sh
|
||||
desktop.ini
|
||||
doc/INSTALL.tex
|
||||
i18n/*.qm
|
||||
ms-windows/*.exe*
|
||||
ms-windows/Installer-Files/postinstall.bat
|
||||
ms-windows/Installer-Files/preremove.bat
|
||||
ms-windows/nsis/
|
||||
ms-windows/osgeo4w/addons/
|
||||
ms-windows/osgeo4w/binary-*
|
||||
ms-windows/osgeo4w/build-*
|
||||
ms-windows/osgeo4w/nsis/
|
||||
ms-windows/osgeo4w/packages-x86/
|
||||
ms-windows/osgeo4w/packages-x86_64/
|
||||
ms-windows/osgeo4w/unpacked/
|
||||
ms-windows/osgeo4w/untgz/
|
||||
ms-windows/packages/
|
||||
ms-windows/progs/
|
||||
ms-windows/untgz/
|
||||
python/expressions/
|
||||
python/plugins/grassprovider/description/algorithms.json
|
||||
python/plugins/grassprovider/tests/testdata/directions.tif.aux.xml
|
||||
python/plugins/processing/tests/testdata/*.aux.xml
|
||||
python/plugins/processing/tests/testdata/custom/*.aux.xml
|
||||
python/plugins/processing/tests/testdata/custom/grass7/*.aux.xml
|
||||
python/plugins/processing/tests/testdata/dem.prj
|
||||
python/plugins/processing/tests/testdata/dem.tfw
|
||||
python/plugins/processing/tests/testdata/dem.wld
|
||||
qgis-test.ctest
|
||||
qgis.kdev4
|
||||
qgis.supp
|
||||
qtcreator-build/
|
||||
resources/themes/*/style.qss.auto
|
||||
resources/server/src/landingpage/node_modules/
|
||||
scripts/Debug
|
||||
scripts/RelWithDebInfo
|
||||
scripts/astyle.exe
|
||||
scripts/qgisstyle*
|
||||
src/core/qgsexpression_texts.cpp
|
||||
tags
|
||||
tests/testdata/*.aux.xml
|
||||
tests/testdata/cache/
|
||||
tests/testdata/checker360by180.asc.aux.xml
|
||||
tests/testdata/control_images/*/*.aux.xml
|
||||
tests/testdata/dPAOWM_styles.db
|
||||
tests/testdata/grass/wgs84/test/.gislock
|
||||
tests/testdata/grass/wgs84/test6/.gislock
|
||||
tests/testdata/grass/wgs84/test7/.gislock
|
||||
tests/testdata/landsat-int16-b1.tif.aux.xml
|
||||
tests/testdata/mGuhmd_styles.db
|
||||
tests/testdata/mesh/trap_steady_05_3D.nc.aux.xml
|
||||
tests/testdata/oOQkbL_styles.db
|
||||
tests/testdata/point_clouds/las/cloud.copc.laz
|
||||
tests/testdata/project_translation/points_translation_de_attachments.zip
|
||||
tests/testdata/qgstestproject_relative_path_test.qgs
|
||||
tests/testdata/qgstestproject_relative_path_test_attachments.zip
|
||||
tests/testdata/rKinSs_styles.db
|
||||
tests/testdata/raster/*.aux.xml
|
||||
tests/testdata/raster/band1_byte_noct_epsg4326.tif.aux.xml
|
||||
tests/testdata/raster/band1_float32_noct_epsg4326.tif.aux.xml
|
||||
tests/testdata/raster/band1_int16_noct_epsg4326.tif.aux.xml
|
||||
tests/testdata/raster/band3_float32_noct_epsg4326.tif.aux.xml
|
||||
tests/testdata/raster/band3_int16_noct_epsg4326.tif.aux.xml
|
||||
tests/testdata/tenbytenraster.asc.aux.xml
|
||||
tests/testdata/test_plugin_path/plugin_started.txt
|
||||
tests/testdata/test_qgis_config_path/profiles/default/*
|
||||
!tests/testdata/test_qgis_config_path/profiles/default/python
|
||||
tests/testdata/widget_config.qlr
|
||||
tests/testdata/zip/testtar.tgz.properties
|
||||
venv
|
223
.mailmap
Normal file
223
.mailmap
Normal file
@ -0,0 +1,223 @@
|
||||
Alessandro Pasotti <elpaso@itopen.it> <apasotti@boundlessgeo.com>
|
||||
Alessandro Pasotti <elpaso@itopen.it> <apasotti@gmail.com>
|
||||
Alessandro Pasotti <elpaso@itopen.it> <apasottis@boundlessgeo.com>
|
||||
Alessandro Pasotti <elpaso@itopen.it> elpaso <elpaso@itopen.it>
|
||||
|
||||
Alexander Bruy <alexander.bruy@gmail.com>
|
||||
Alexander Bruy <alexander.bruy@gmail.com> <alexbruy@c8812cc2-4d05-0410-92ff-de0c093fc19c>
|
||||
Alexander Bruy <alexander.bruy@gmail.com> <alexander.bruy@gmail.com@881b9c09-3ef8-f3c2-ec3d-21d735c97f4d>
|
||||
|
||||
Alexandre Neto <senhor.neto@gmail.com> Alexandre <senhor.neto@gmail.com>
|
||||
Alexandre Neto <senhor.neto@gmail.com> SrNetoChan <senhor.neto@gmail.com>
|
||||
|
||||
Alex <roya0045@users.noreply.github.com> roya0045 <roya0045@users.noreply.github.com>
|
||||
|
||||
Alister Hood <alister.hood@gmail.com> Alister <alister.hood@gmail.com>
|
||||
Alister Hood <alister.hood@gmail.com> Alister <alister.hood@synergine.com>
|
||||
Alister Hood <alister.hood@gmail.com> AlisterH <alister.hood@gmail.com>
|
||||
|
||||
Andreas Neumann <a.neumann@carto.net> andreasneumann <a.neumann@carto.net>
|
||||
|
||||
Anita Graser <anitagraser@gmx.at> anitagraser <anitagraser@gmx.at>
|
||||
|
||||
Arnaud Morvan <arnaud.morvan@camptocamp.com> arnaud.morvan@camptocamp.com <arnaud.morvan@camptocamp.com>
|
||||
|
||||
Asger Skovbo Petersen <asgerpetersen@gmail.com> AsgerPetersen <asgerpetersen@gmail.com>
|
||||
|
||||
Borys Jurgiel <info@borysjurgiel.pl> borys <info@borysjurgiel.pl>
|
||||
Borys Jurgiel <info@borysjurgiel.pl> <info at borysjurgiel dot pl>
|
||||
Borys Jurgiel <info@borysjurgiel.pl> borysiasty <borysiasty@c8812cc2-4d05-0410-92ff-de0c093fc19c>
|
||||
|
||||
Clemens Raffler <clemens.raffler@gmail.com> <root676@users.noreply.github.com>
|
||||
Clemens Raffler <clemens.raffler@gmail.com> root676 <clemens.raffler@gmail.com>
|
||||
Clemens Raffler <clemens.raffler@gmail.com> root676 <clemens.raffler@gmx.at>
|
||||
|
||||
D'Hont René-Luc <rldhont@gmail.com>
|
||||
|
||||
Damiano Lombardi <damiano@opengis.ch> Damiano <damiano@opengis.ch>
|
||||
Damiano Lombardi <damiano@opengis.ch> Damiano <lombardi.damiano@gmail.com>
|
||||
Damiano Lombardi <damiano@opengis.ch> <lombardi@customcut.ch>
|
||||
Damiano Lombardi <damiano@opengis.ch> <lombardi.damiano@gmail.com>
|
||||
Damiano Lombardi <damiano@opengis.ch> domi <lombardi@customcut.ch>
|
||||
|
||||
David Marteau <dmarteau@3liz.com> <david@innophi.com>
|
||||
David Marteau <dmarteau@3liz.com> <dhmarteau@gmail.com>
|
||||
|
||||
David Signer <david@opengis.ch> David <david@opengis.ch>
|
||||
David Signer <david@opengis.ch> signedav <david@opengis.ch>
|
||||
|
||||
Etienne Trimaille <etienne.trimaille@gmail.com> <etienne@Etiennes-MacBook-Pro.local>
|
||||
Etienne Trimaille <etienne.trimaille@gmail.com> <gustrimaille@yahoo.fr>
|
||||
Etienne Trimaille <etienne.trimaille@gmail.com> Étienne Trimaille <gustrimaille@yahoo.fr>
|
||||
|
||||
Even Rouault <even.rouault@spatialys.com> <even.rouault@mines-paris.org>
|
||||
|
||||
Francisco Raga <All4Gis@users.noreply.github.com> Fran Raga <All4Gis@users.noreply.github.com>
|
||||
|
||||
Gary Sherman <gsherman@geoapt.com> <gsherman@c8812cc2-4d05-0410-92ff-de0c093fc19c>
|
||||
|
||||
Germán Carrillo <gcarrillo@linuxmail.org> gacarrillor <gcarrillo@linuxmail.org>
|
||||
Germán Carrillo <gcarrillo@linuxmail.org> gacarrillor <geotux_tuxman@linuxmail.org>
|
||||
Germán Carrillo <gcarrillo@linuxmail.org> <geotux_tuxman@linuxmail.org>
|
||||
Germán Carrillo <gcarrillo@linuxmail.org> Germán <geotux_tuxman@linuxmail.org>
|
||||
Germán Carrillo <gcarrillo@linuxmail.org> Germap <gcarrillo@linuxmail.org>
|
||||
|
||||
Giovanni Allegri <giovanni.allegri@gmail.com> giohappy <giohappy@gmail.com>
|
||||
|
||||
Giovanni Manghi <giovanni.manghi@naturalgis.pt> gioman <giovanni.manghi@faunalia.pt>
|
||||
Giovanni Manghi <giovanni.manghi@naturalgis.pt> <gio@sibirica.(none)>
|
||||
Giovanni Manghi <giovanni.manghi@naturalgis.pt> <giovanni.manghi@faunalia.pt>
|
||||
Giovanni Manghi <giovanni.manghi@naturalgis.pt> Giovanni Manghi <giovanni@sibirica.(none)>
|
||||
|
||||
Giuseppe Sucameli <brush.tyler@gmail.com> <brushtyler@881b9c09-3ef8-f3c2-ec3d-21d735c97f4d>
|
||||
Giuseppe Sucameli <brush.tyler@gmail.com> <brushtyler@c8812cc2-4d05-0410-92ff-de0c093fc19c>
|
||||
|
||||
Harrissou Sant-anna <delazj@gmail.com> DelazJ <delazj@gmail.com>
|
||||
|
||||
Ivan Ivanov <ivan.ivanov@suricactus.com> <suricactus@users.noreply.github.com>
|
||||
|
||||
Jacky Volpes <jacky.volpes@oslandia.com> <34267385+Djedouas@users.noreply.github.com>
|
||||
|
||||
Jean-Roc Morreale <jr.morreale@enoreth.net> Jean Roc <jr.morreale@enoreth.net>
|
||||
Jean-Roc Morreale <jr.morreale@enoreth.net> MORREALE Jean-Roc <jr.morreale@enoreth.net>
|
||||
|
||||
Jorge Gustavo Rocha <jgr@geomaster.pt> <jgr@di.uminho.pt>
|
||||
|
||||
Julien Cabieces <julien.cabieces@oslandia.com> <julien@julien-laptop.home>
|
||||
|
||||
Jürgen E. Fischer <jef@norbit.de>
|
||||
Jürgen E. Fischer <jef@norbit.de> <fischer@linux-buechse.de>
|
||||
Jürgen E. Fischer <jef@norbit.de> <jef@c8812cc2-4d05-0410-92ff-de0c093fc19c>
|
||||
Jürgen E. Fischer <jef@norbit.de> <jef@FARAMIR>
|
||||
Jürgen E. Fischer <jef@norbit.de> Juergen E. Fischer <jef@norbit.de>
|
||||
Jürgen E. Fischer <jef@norbit.de> Juergen Fischer <jef@norbit.de>
|
||||
Jürgen E. Fischer <jef@norbit.de> Jürgen Fischer <jef@norbit.de>
|
||||
|
||||
Larry Shaffer <lshaffer@federal.planet.com> <lshaffer@boundlessgeo.com>
|
||||
Larry Shaffer <lshaffer@federal.planet.com> <dakcarto@users.noreply.github.com>
|
||||
Larry Shaffer <lshaffer@federal.planet.com> <larrys@dakotacarto.com>
|
||||
|
||||
Loïc Bartoletti <loic.bartoletti@oslandia.com>
|
||||
Loïc Bartoletti <loic.bartoletti@oslandia.com> <l.bartoletti@free.fr>
|
||||
Loïc Bartoletti <loic.bartoletti@oslandia.com> <coder@tuxfamily.org>
|
||||
Loïc Bartoletti <loic.bartoletti@oslandia.com> <lbartoletti@tuxfamily.org>
|
||||
Loïc Bartoletti <loic.bartoletti@oslandia.com> <lbartoletti@users.noreply.github.com>
|
||||
|
||||
Luigi Pirelli <luipir@gmail.com> luipir <luipir@gmail.com>
|
||||
|
||||
Marco Bernasocchi <marco@opengis.ch> <marco@bernawebdesign.ch>
|
||||
Marco Bernasocchi <marco@opengis.ch> <marco@muse.(none)>
|
||||
Marco Bernasocchi <marco@opengis.ch> <marco@placebo.(none)>
|
||||
|
||||
Marco Hugentobler <marco.hugentobler@sourcepole.ch> <marco@hugis1.(none)>
|
||||
Marco Hugentobler <marco.hugentobler@sourcepole.ch> <marco@marco-laptop.(none)>
|
||||
Marco Hugentobler <marco.hugentobler@sourcepole.ch> <marco@sourcepole.ch>
|
||||
Marco Hugentobler <marco.hugentobler@sourcepole.ch> mhugent <marco.hugentobler@sourcepole.ch>
|
||||
Marco Hugentobler <marco.hugentobler@sourcepole.ch> mhugent <mhugent@c8812cc2-4d05-0410-92ff-de0c093fc19c>
|
||||
|
||||
Mario Baranzini <mario.baranzini@gmail.com> <mario@opengis.ch>
|
||||
Mario Baranzini <mario.baranzini@gmail.com> <marioba@users.noreply.github.com>
|
||||
|
||||
Markus Neteler <neteler@gmail.com> <neteler@osgeo.org>
|
||||
Markus Neteler <neteler@gmail.com> <neteler@oboe.localdomain>
|
||||
|
||||
Martin Dobias <wonder.sk@gmail.com> <wonder@c8812cc2-4d05-0410-92ff-de0c093fc19c>
|
||||
|
||||
Mathieu Pellerin <nirvn.asia@gmail.com>
|
||||
|
||||
Matteo Ghetta <matteo.ghetta@gmail.com> ghtmtt <matteo.ghetta@gmail.com>
|
||||
Matteo Ghetta <matteo.ghetta@gmail.com> matteo <matteo.ghetta@gmail.com>
|
||||
Matteo Ghetta <matteo.ghetta@gmail.com> Matteo <matteo.ghetta@gmail.com>
|
||||
|
||||
Matthias Kuhn <matthias@opengis.ch> <matthias.kuhn@gmx.ch>
|
||||
Matthias Kuhn <matthias@opengis.ch> <kk@kk-office.gslwd>
|
||||
Matthias Kuhn <matthias@opengis.ch> matthias-kuhn <matthias.kuhn@gmx.ch>
|
||||
|
||||
Nathan Woodrow <madmanwoo@gmail.com> Nathan <nathan_woodrow@technologyonecorp.com>
|
||||
Nathan Woodrow <madmanwoo@gmail.com> <nathan.woodrow@mapsolutions.com.au>
|
||||
Nathan Woodrow <madmanwoo@gmail.com> <nathan_woodrow@technologyonecorp.com>
|
||||
Nathan Woodrow <madmanwoo@gmail.com> <woodrow.nathan@gmail.com>
|
||||
Nathan Woodrow <madmanwoo@gmail.com> <woo@woo-mint.(none)>
|
||||
|
||||
Nedjima Belgacem <gb_nedjima@esi.dz> NEDJIMAbelgacem <gb_nedjima@esi.dz>
|
||||
Nedjima Belgacem <gb_nedjima@esi.dz> nedjima <gb_nedjima@esi.dz>
|
||||
Nedjima Belgacem <gb_nedjima@esi.dz> Belgacem <gb_nedjima@esi.dz>
|
||||
|
||||
Nicolas Godet <nicolas.godet@outlook.fr> nicogodet <39594821+nicogodet@users.noreply.github.com>
|
||||
Nicolas Godet <nicolas.godet@outlook.fr> nicogodet <nicolas.godet@outlook.fr>
|
||||
Nicolas Godet <nicolas.godet@outlook.fr> <39594821+nicogodet@users.noreply.github.com>
|
||||
|
||||
Nyall Dawson <nyall.dawson@gmail.com> nyalldawson <nyall.dawson@gmail.com>
|
||||
Nyall Dawson <nyall.dawson@gmail.com> <nyall@localhost.localdomain>
|
||||
Nyall Dawson <nyall.dawson@gmail.com> Nyall <nyall.dawson@gmail.com>
|
||||
|
||||
Olivier Dalang <olivier.dalang@gmail.com> olivierdalang <olivier.dalang@epfl.ch>
|
||||
Olivier Dalang <olivier.dalang@gmail.com> olivierdalang <olivier.dalang@gmail.com>
|
||||
Olivier Dalang <olivier.dalang@gmail.com> olivier <olivier.dalang@gmail.com>
|
||||
|
||||
Otto Dassau <dassau@gbd-consult.de> dassau <dassau@c8812cc2-4d05-0410-92ff-de0c093fc19c>
|
||||
Otto Dassau <dassau@gbd-consult.de> dassau <dassau@gbd-consult.de>
|
||||
|
||||
Paolo Cavallini <cavallini@faunalia.it>
|
||||
Paolo Cavallini <cavallini@faunalia.it> <pcav@c8812cc2-4d05-0410-92ff-de0c093fc19c>
|
||||
|
||||
Paul Blottiere <blottiere.paul@gmail.com> Blottiere Paul <blottiere.paul@gmail.com>
|
||||
|
||||
Peter Petrik <zilolv@gmail.com> PeterPetrik <zilolv@gmail.com>
|
||||
|
||||
Radim Blazek <radim.blazek@gmail.com> <rblazek@c8812cc2-4d05-0410-92ff-de0c093fc19c>
|
||||
|
||||
Raymond Nijssen <r.nijssen@terglobo.nl> raymondnijssen <r.nijssen@terglobo.nl>
|
||||
|
||||
Régis Haubourg <regis@qgis.org> <regis.haubourg@eau-adour-garonne.fr>
|
||||
Régis Haubourg <regis@qgis.org> <regis.haubourg@oslandia.com>
|
||||
|
||||
Richard Duivenvoorde <richard@duif.net> rduivenvoorde <rduivenvoorde@c8812cc2-4d05-0410-92ff-de0c093fc19c>
|
||||
Richard Duivenvoorde <richard@duif.net> <rdmailings@duif.net>
|
||||
|
||||
Saber <saber.razmjooei@lutraconsulting.co.uk> Lutra <saber.razmjooei@lutraconsulting.co.uk>
|
||||
Saber <saber.razmjooei@lutraconsulting.co.uk> saber <saber.razmjooei@lutraconsulting.co.uk>
|
||||
Saber <saber.razmjooei@lutraconsulting.co.uk> Sab <saber.razmjooei@lutraconsulting.co.uk>
|
||||
|
||||
Salvatore Fiandaca <pigrecoinfinito@gmail.com> Salvatore <pigrecoinfinito@gmail.com>
|
||||
|
||||
Salvatore Larosa <lrssvtml@gmail.com>
|
||||
|
||||
Samweli Mwakisambwe <samweli@kartoza.com> <smwltwesa6@gmail.com>
|
||||
Samweli Mwakisambwe <samweli@kartoza.com> Samweli <samweli@kartoza.com>
|
||||
Samweli Mwakisambwe <samweli@kartoza.com> Samweli <smwltwesa6@gmail.com>
|
||||
|
||||
Sandro Santilli <strk@kbt.io> <strk@keybit.net>
|
||||
|
||||
Stefanos Natsis <uclaros@gmail.com> <uclaros@debian-BULLSEYE-live-builder-AMD64>
|
||||
Stefanos Natsis <uclaros@gmail.com> uclaros <Ucla ros 1>
|
||||
Stefanos Natsis <uclaros@gmail.com> uclaros <uclaros@gmail.com>
|
||||
|
||||
Thomas Gratier <thomas_gratier@yahoo.fr> ThomasG77 <thomas_gratier@yahoo.fr>
|
||||
|
||||
Tim Sutton <tim@linfiniti.com> <tim@kartoza.com>
|
||||
Tim Sutton <tim@linfiniti.com> <timlinux@c8812cc2-4d05-0410-92ff-de0c093fc19c>
|
||||
|
||||
Tom Chadwin <tomchadwin@astuntechnology.com> <tom.chadwin@nnpa.org.uk>
|
||||
Tom Chadwin <tomchadwin@astuntechnology.com> <tomchadwin@users.noreply.github.com>
|
||||
|
||||
Tomas Mizera <tomas.mizera@lutraconsulting.co.uk> tomasMizera <tomas.mizera2@gmail.com>
|
||||
Tomas Mizera <tomas.mizera@lutraconsulting.co.uk> <tomas.mizera2@gmail.com>
|
||||
Tomas Mizera <tomas.mizera@lutraconsulting.co.uk> tomasMizera <tomas.mizera@lutraconsulting.co.uk>
|
||||
|
||||
Tudor Bărăscu <tudor.barascu@qtibia.ro> Tudor Barascu <tudor.barascu@qtibia.ro>
|
||||
|
||||
Víctor Olaya <volayaf@gmail.com>
|
||||
Víctor Olaya <volayaf@gmail.com> <volayaf@881b9c09-3ef8-f3c2-ec3d-21d735c97f4d>
|
||||
Víctor Olaya <volayaf@gmail.com> <volayaf@gmail.com@881b9c09-3ef8-f3c2-ec3d-21d735c97f4d>
|
||||
|
||||
Vincent Cloarec <vcloarec@gmail.com> vcloarec <vcloarec@gmail.com>
|
||||
|
||||
Werner Macho <werner.macho@gmail.com> macho <macho@c8812cc2-4d05-0410-92ff-de0c093fc19c>
|
||||
Werner Macho <werner.macho@gmail.com> <macho@void.(none)>
|
||||
|
||||
William Kyngesburye <kyngchaos@kyngchaos.com> kyngchaos <kyngchaos@c8812cc2-4d05-0410-92ff-de0c093fc19c>
|
||||
William Kyngesburye <kyngchaos@kyngchaos.com> <kyngchaos@sumomo.attlocal.net>
|
||||
William Kyngesburye <kyngchaos@kyngchaos.com> <kyngchaos@Sumomo.attlocal.net>
|
||||
|
||||
Yves Jacolin <yves.jacolin@camptocamp.com> Jacolin <yves.jacolin@camptocamp.com>
|
48
.pre-commit-config.yaml
Normal file
48
.pre-commit-config.yaml
Normal file
@ -0,0 +1,48 @@
|
||||
exclude: |
|
||||
(?x)^(
|
||||
python/.*/auto_\w+/.*.py|
|
||||
external/.*|
|
||||
tests/testdata/script_with_error.py
|
||||
)$
|
||||
fail_fast: false
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||
rev: v19.1.6
|
||||
# if adding directory handled by clang-format
|
||||
# you need to adapt prepare_commit and verify_indentation scripts accordingly
|
||||
hooks:
|
||||
- id: clang-format
|
||||
types_or: [c++, c, c#]
|
||||
exclude: |
|
||||
(?x)^(
|
||||
src/core/.*|
|
||||
tests/code_layout/sipify/sipifyheader.h
|
||||
)$
|
||||
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.19.1
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--py39-plus]
|
||||
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 24.10.0
|
||||
hooks:
|
||||
- id: black
|
||||
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 5.13.2
|
||||
hooks:
|
||||
- id: isort
|
||||
args: ["--profile", "black", "--filter-files"]
|
||||
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: prepare_commit
|
||||
name: prepare_commit
|
||||
entry: ./scripts/prepare_commit.sh
|
||||
language: system
|
||||
always_run: true
|
||||
pass_filenames: false
|
||||
|
52
.tx/config
Normal file
52
.tx/config
Normal file
@ -0,0 +1,52 @@
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
|
||||
[o:qgis:p:QGIS:r:qgis-application]
|
||||
file_filter = i18n/qgis_<lang>.ts
|
||||
source_file = i18n/qgis_en.ts
|
||||
source_lang = en
|
||||
type = QT
|
||||
minimum_perc = 35
|
||||
trans.cs = i18n/qgis_cs.ts
|
||||
trans.de = i18n/qgis_de.ts
|
||||
trans.es = i18n/qgis_es.ts
|
||||
trans.fi = i18n/qgis_fi.ts
|
||||
trans.it = i18n/qgis_it.ts
|
||||
trans.ru = i18n/qgis_ru.ts
|
||||
trans.sk = i18n/qgis_sk.ts
|
||||
trans.ar = i18n/qgis_ar.ts
|
||||
trans.hu = i18n/qgis_hu.ts
|
||||
trans.lv = i18n/qgis_lv.ts
|
||||
trans.ca = i18n/qgis_ca.ts
|
||||
trans.ja = i18n/qgis_ja.ts
|
||||
trans.nb = i18n/qgis_nb.ts
|
||||
trans.pl = i18n/qgis_pl.ts
|
||||
trans.pt_PT = i18n/qgis_pt_PT.ts
|
||||
trans.tr = i18n/qgis_tr.ts
|
||||
trans.uk = i18n/qgis_uk.ts
|
||||
trans.hr = i18n/qgis_hr.ts
|
||||
trans.en_US = i18n/qgis_en_US.ts
|
||||
trans.fr = i18n/qgis_fr.ts
|
||||
trans.ko = i18n/qgis_ko.ts
|
||||
trans.lt = i18n/qgis_lt.ts
|
||||
trans.pt_BR = i18n/qgis_pt_BR.ts
|
||||
trans.sr@latin = i18n/qgis_sr@latin.ts
|
||||
trans.vi = i18n/qgis_vi.ts
|
||||
trans.el = i18n/qgis_el.ts
|
||||
trans.eo = i18n/qgis_eo.ts
|
||||
trans.hi = i18n/qgis_hi.ts
|
||||
trans.nl = i18n/qgis_nl.ts
|
||||
trans.ro = i18n/qgis_ro.ts
|
||||
trans.bs = i18n/qgis_bs.ts
|
||||
trans.et = i18n/qgis_et.ts
|
||||
trans.km = i18n/qgis_km.ts
|
||||
trans.sl = i18n/qgis_sl.ts
|
||||
trans.sr = i18n/qgis_sr.ts
|
||||
trans.zh-Hant = i18n/qgis_zh-Hant.ts
|
||||
trans.eu = i18n/qgis_eu.ts
|
||||
trans.gl = i18n/qgis_gl.ts
|
||||
trans.id = i18n/qgis_id.ts
|
||||
trans.sv = i18n/qgis_sv.ts
|
||||
trans.zh-Hans = i18n/qgis_zh-Hans.ts
|
||||
trans.da = i18n/qgis_da.ts
|
||||
|
27
AUTHORS
27
AUTHORS
@ -1,27 +0,0 @@
|
||||
# The following have contributed to QGis:
|
||||
# --------------------------------------------------------
|
||||
# Please note that this file is parsed by the about box
|
||||
# for the contributors list, so names should be strictly
|
||||
# in the format:
|
||||
# name [tab] <email>
|
||||
#
|
||||
# The name will be used to infer the image name, with spaces
|
||||
# replaced by underscores. If no matching image is found
|
||||
# a blank image will be displayed.
|
||||
# Images are read out of $PREFIX/share/images/contributors/
|
||||
# ---------------------------------------------------------
|
||||
Gary E.Sherman <sherman at mrcc dot com>
|
||||
Steve Halasz <stevehalasz at users.sourceforge.net>
|
||||
Marco Hugentobler <mhugent at users.sourceforge.net>
|
||||
Tim Sutton <tim at linfiniti.com>
|
||||
Denis Antipov <rawbytes at users.sourceforge.net>
|
||||
Mark Coletti <mcoletti at users.sourceforge.net>
|
||||
Lars Luthman <larsl at users.sourceforge.net>
|
||||
Jens Oberender <j.obi at troja.net>
|
||||
Christoph Spoerri <spoerri at users.sourceforge.net>
|
||||
Carl Anderson <>
|
||||
Gavin Macaulay <g_j_m at users.sourceforge.net>
|
||||
Masaru Hoshi <hoshi at users.sourceforge.net>
|
||||
Peter Brewer <p.w.brewer at rdg dot ac dot uk>
|
||||
Radim Blazek <blazek at itc.it>
|
||||
Tom Elwertowski <telwertowski at users.sourceforge.net>
|
40
BUGS
40
BUGS
@ -1,20 +1,26 @@
|
||||
BUGS,v 1.4 2004/02/25 05:42:07 gsherman Exp
|
||||
-----------------------------------------------------------------------------
|
||||
Known issues and bugs in this release (QGIS 0.1 'Moroz')
|
||||
RASTER:
|
||||
1. Very large rasters cause crash [Bug 898642]
|
||||
Help I think I found a bug!
|
||||
---------------------------
|
||||
|
||||
VECTOR:
|
||||
1. OGR layers (for example shapefiles) do not reliably select or identify
|
||||
features. Any feature that intersects the MBR (minimum bounding rectangle)
|
||||
of the selection rectangle will be returned. This results in more features
|
||||
being returned than desired.[Bug 896254]
|
||||
2. Zooming in very close can result in a scrambled display. [Bug 895506]
|
||||
3. Drawing polygons with patterns other than solid may leave "holes" where the
|
||||
polygons are not properly rendered.[Bug 889454]
|
||||
If you find a bug in QGIS, first check if it has already been reported:
|
||||
|
||||
PLUGINS:
|
||||
1. SPIT crashes on empty/invalid data in a shapefile [Bug 903940]
|
||||
https://github.com/qgis/QGIS/issues
|
||||
|
||||
For additional information, see the QGIS Bugs page at:
|
||||
http://sourceforge.net/tracker/?group_id=55820&atid=478378
|
||||
If you can't find an existing ticket, report a new one, using the bug report template provided.
|
||||
|
||||
Some hints about when you should file a bug:
|
||||
|
||||
|
||||
- Just because a bug is filed doesn't always mean we can or will fix it.
|
||||
Sometimes people ask for things that will require many man hours to do and
|
||||
offer little reward to work ratio benefit when compared to the other issues
|
||||
in the queue. Also some things are simply not fixable due to whatever
|
||||
technical reason.
|
||||
- Sometimes we don't fix a bug because the user's vision of how QGIS should
|
||||
behave doesn't match ours. Hey we are all humans it can happen...
|
||||
- Always check that your bug has not already been filed by someone else since
|
||||
dealing with duplicate tickets causes a lot of time wasting.
|
||||
- Be prepared to provided further feedback after the initial triage.
|
||||
- Don't be offended if we don't see tickets as having the same priority as you
|
||||
do. While we appreciate it's inconvenient if some issue prevents you doing
|
||||
your work, we need to take the big picture view of things and focus on
|
||||
things that affect the largest proportion of our user base.
|
||||
|
1237
CMakeLists.txt
Normal file
1237
CMakeLists.txt
Normal file
File diff suppressed because it is too large
Load Diff
37
CONTRIBUTING.md
Normal file
37
CONTRIBUTING.md
Normal file
@ -0,0 +1,37 @@
|
||||
# Contributing
|
||||
|
||||
## Developer guide
|
||||
|
||||
A [complete developer guide](https://docs.qgis.org/latest/en/docs/developers_guide/index.html) is also available to explain the development process, the unit testing system and more!
|
||||
|
||||
You may also want to consult the build process for QGIS which is fully detailed in the [install guide](INSTALL.md).
|
||||
|
||||
## Bug reporting and bug fixing
|
||||
|
||||
You can help us **by submitting bug reports or fixing bugs** in the [QGIS bug tracker](https://github.com/qgis/QGIS/issues/).
|
||||
|
||||
## New features and enhancements
|
||||
|
||||
If you wish to contribute patches you can:
|
||||
|
||||
1. [Fork the project](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo)
|
||||
2. Install the [pre-commit](https://pre-commit.com/) hook: `pre-commit install --install-hooks` (version 4.1+ required)
|
||||
3. Make your changes
|
||||
4. Commit to your repository
|
||||
5. [Create a pull request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/)
|
||||
|
||||
The development team can then review your contribution and commit it upstream as appropriate.
|
||||
|
||||
If you commit a new feature, add `[FEATURE]` to your commit message AND give a clear description of the new feature. The label `Needs documentation` will be added by maintainers and will automatically create an issue on the QGIS-Documentation repo, where you or others should write documentation about it.
|
||||
|
||||
For large-scale changes, you can open a [QEP (QGIS Enhancement Proposal)](https://github.com/qgis/QGIS-Enhancement-Proposals). QEPs are used in the process of creating and discussing new enhancements or policy for QGIS.
|
||||
|
||||
## Translations
|
||||
|
||||
Please help translate QGIS to your language. At this moment about forty languages are already available in the Desktop user interface and about eighty languages are available in transifex ready to be translated.
|
||||
|
||||
The [translation](https://docs.qgis.org/latest/en/docs/documentation_guidelines/do_translations.html) process is managed by the [Translation Team](https://qgis.org/community/organisation/#translation) and all the activities are done under the [Transifex](https://www.transifex.com/qgis/) platform.
|
||||
|
||||
## Other ways to contribute
|
||||
|
||||
If you are not a developer, there are many other possibilities that do not require programming skills to help QGIS to evolve. Check our [project homepage for more information](https://qgis.org/community/involve/).
|
43
COPYING
43
COPYING
@ -1,12 +1,12 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
@ -225,7 +225,7 @@ impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
@ -277,12 +277,12 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
In addition, as a special exception, the QGIS Development Team gives
|
||||
permission to link the code of this program with the Qt library,
|
||||
including but not limited to the following versions (both free and
|
||||
commercial): Qt/Non-commerical Windows, Qt/Windows, Qt/X11, Qt/Mac, and
|
||||
commercial): Qt/Non-commercial Windows, Qt/Windows, Qt/X11, Qt/Mac, and
|
||||
Qt/Embedded (or with modified versions of Qt that use the same license
|
||||
as Qt), and distribute linked combinations including the two. You must
|
||||
obey the GNU General Public License in all respects for all of the code
|
||||
@ -292,7 +292,7 @@ so. If you do not wish to do so, delete this exception statement from
|
||||
your version.
|
||||
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
@ -316,17 +316,16 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
@ -349,5 +348,5 @@ necessary. Here is a sample; alter the names:
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
229
INSTALL
229
INSTALL
@ -1,229 +0,0 @@
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. (Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.)
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You only need
|
||||
`configure.ac' if you want to change it or regenerate `configure' using
|
||||
a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. Run `./configure --help'
|
||||
for details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not support the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a
|
||||
time in the source code directory. After you have installed the
|
||||
package for one architecture, use `make distclean' before reconfiguring
|
||||
for another architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PATH'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||
PATH as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=PATH' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out
|
||||
automatically, but needs to determine by the type of machine the package
|
||||
will run on. Usually, assuming the package is built to be run on the
|
||||
_same_ architectures, `configure' can figure that out, but if it prints
|
||||
a message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the `--target=TYPE' option to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
will cause the specified gcc to be used as the C compiler (unless it is
|
||||
overridden in the site shell script).
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
1394
INSTALL.md
Normal file
1394
INSTALL.md
Normal file
File diff suppressed because it is too large
Load Diff
13
INSTALL.svn
13
INSTALL.svn
@ -1,13 +0,0 @@
|
||||
To build and install the source checked out from Subversion:
|
||||
./autogen.sh <configure options>
|
||||
make
|
||||
make install
|
||||
|
||||
|
||||
Configure options to autogen.sh can include any of the options available to
|
||||
configure. Run ./configure --help to get a list of options.
|
||||
|
||||
Example to configure for installing in /usr/local/qgis:
|
||||
./autogen.sh --prefix=/usr/local/qgis
|
||||
make
|
||||
make install
|
59
Makefile.am
59
Makefile.am
@ -1,59 +0,0 @@
|
||||
# Copyright (C) 2003 Gary Sherman <sherman at mrcc.com>
|
||||
#
|
||||
# This file is free software; as a special exception the author gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
EXTRA_DIST = \
|
||||
AUTHORS \
|
||||
BUGS \
|
||||
ChangeLog \
|
||||
COPYING \
|
||||
create_qm_files.sh \
|
||||
doc \
|
||||
INSTALL \
|
||||
$(man1_MANS) \
|
||||
NEWS \
|
||||
qgis.spec \
|
||||
qgsconfig.h.in \
|
||||
README \
|
||||
TODO \
|
||||
update_ts_files.sh
|
||||
|
||||
man1_MANS = qgis.man
|
||||
|
||||
docdatadir = $(datadir)/$(PACKAGE)/doc
|
||||
|
||||
docdata_DATA = AUTHORS
|
||||
|
||||
if HAVE_QT3
|
||||
SUBDIRS = src widgets providers plugins doc tools i18n designer_plugins helpviewer
|
||||
endif
|
||||
|
||||
if HAVE_QT4
|
||||
SUBDIRS = src widgets providers plugins doc tools i18n
|
||||
endif
|
||||
|
||||
pkginclude_HEADERS = qgsconfig.h
|
||||
|
||||
UIcheck:
|
||||
@UIS=`find . -name *.ui` && \
|
||||
if [ `grep "UI version" $$UIS | sed -e '/3.1/d' -e '/3.3/d' | wc -l` -ne 0 ]; then \
|
||||
echo -e "\nWrong UI version:"; \
|
||||
grep "UI version" $$UIS | sed -e '/3.1/d' -e '/3.3/d' -e 's/:.*version="\([0-9\.]*\)".*/ is version \1/g'; \
|
||||
echo; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
release: UIcheck distdir
|
||||
-chmod -R a+r $(distdir)
|
||||
GZIP=$(GZIP_ENV) $(AMTAR)$(TAR) chozf $(distdir).tar.gz $(distdir)
|
||||
rm -f $(distdir)/qgis.spec
|
||||
sed '/^Source:/s/\.tar\.gz$$/\.tar\.bz2/' qgis.spec \
|
||||
> $(distdir)/qgis.spec
|
||||
BZIP2=$(BZIP2_ENV) $(AMTAR)$(TAR) --bzip2 -chof $(distdir).tar.bz2 $(distdir)
|
||||
-rm -rf $(distdir)
|
71
PROVENANCE
Normal file
71
PROVENANCE
Normal file
@ -0,0 +1,71 @@
|
||||
<!--
|
||||
This file documents the code provenance review for QGIS as part of the
|
||||
OSGEO incubation process and should remain in the QGIS source tree. It
|
||||
should not be included in release packages.
|
||||
|
||||
This file is in MediaWiki format for inclusion on the OSGEO wiki.
|
||||
-->
|
||||
Note the authoritative copy of this document is stored in the QGIS repository.
|
||||
= Committers Past and Present =
|
||||
dassau - Otto Dassau
|
||||
ersts - Peter Ersts
|
||||
g_j_m - Gavin Macaulay
|
||||
godofredo - Godofredo Contreras
|
||||
gsherman - Gary Sherman
|
||||
homann - Magnus Homann
|
||||
hoshi - Masaru Hoshi
|
||||
jef - Jürgen Fischer
|
||||
jobi - Jens Oberender
|
||||
larsl - Lars Luthman
|
||||
leo.lami - Leonardo Lami
|
||||
mcoletti - Mark Coletti
|
||||
mhugent - Marco Hugentobler
|
||||
morb_au - Brendan Morley
|
||||
perrygeo - Matthew Perry
|
||||
rabla/rblazek - Radim Blazek
|
||||
rawbytes - Denis Antipov
|
||||
sbr00pwb - Peter Brewer
|
||||
shalasz/stevehalasz - Steve Halasz
|
||||
spoerri - Christoph Spoerri
|
||||
StevenB - Steven Bell
|
||||
telwertowski - Tom Elwertowski
|
||||
timlinux - Tim Sutton
|
||||
warmerdam - Frank Warmerdam
|
||||
what_nick - Tisham Dhar
|
||||
wonder - Martin Dobias
|
||||
= Outstanding Issues =
|
||||
No issues were discovered in the code review. All external code was
|
||||
examined to make sure there were no license problems (see below).
|
||||
= Included Libraries =
|
||||
The following libraries are used in QGIS:
|
||||
* GDAL/OGR
|
||||
* GSL (optional)
|
||||
* Qt
|
||||
* PostgreSQL (optional)
|
||||
* Python (optional)
|
||||
* GRASS (optional)
|
||||
* PyQt (optional)
|
||||
* Sip (optional)
|
||||
* Sqlite3
|
||||
= Source Code Review =
|
||||
All non-generated source files were manually reviewed for copyright and
|
||||
license statements, as well as potential issues. This constituted a
|
||||
review of 364 implementation files (.cpp and .cc), 378 header files
|
||||
(.h), and 21 Python scripts in the src directory and its subdirectories:
|
||||
app
|
||||
designer
|
||||
core
|
||||
gui
|
||||
helpviewer
|
||||
mac
|
||||
plugins
|
||||
providers
|
||||
ui
|
||||
Where copyright and/or GPL license statement were missing, it was added
|
||||
after ensuring it was appropriate. All code within the project is
|
||||
licensed under the GPL or LGPL, version 2.
|
||||
|
||||
== External Source Files ==
|
||||
The following files are included in the QGIS source tree from external
|
||||
sources. The source, license, and copyright are noted for each.
|
||||
|
70
README
70
README
@ -1,70 +0,0 @@
|
||||
README for QGIS version 0.7 'Seamus'
|
||||
|
||||
Quantum GIS (QGIS) is an Open Source Geographic Information System. The
|
||||
project was born in May of 2002 and was established as a project on
|
||||
SourceForge in June of the same year. We've worked hard to make GIS
|
||||
software (which is traditionaly expensive commerical software) a viable
|
||||
prospect for anyone with basic access to a Personal Computer. QGIS
|
||||
currently runs on most Unix platforms, Window, and OS X. QGIS is
|
||||
developed using the Qt toolkit (http://www.trolltech.com) and C++. This
|
||||
means that QGIS feels snappy to use and has a pleasing, easy to use
|
||||
graphical user interface.
|
||||
|
||||
QGIS aims to be an easy to use GIS, providing common functions and
|
||||
features. The initial goal was to provide a GIS data viewer. QGIS has
|
||||
reached that point in its evolution and is being used by many for their
|
||||
daily GIS data viewing needs. QGIS supports a number of raster and
|
||||
vector data formats, with new support easily added using the plugin
|
||||
architecture.
|
||||
|
||||
QGIS is released under the GNU Public License (GPL). Devloping QGIS
|
||||
under this license means that you can (if you want to) inspect and
|
||||
modify the source code and guarantees that you, our happy user will
|
||||
always have access to a GIS program that is free of cost and can be
|
||||
freely modified.
|
||||
|
||||
This release adds:
|
||||
* Projection support
|
||||
|
||||
Supported raster formats include:
|
||||
Grass
|
||||
USGS DEM
|
||||
ArcInfo binary grid
|
||||
ArcInfo ASCII grid
|
||||
ERDAS Imagine
|
||||
SDTS
|
||||
GeoTiff
|
||||
Tiff with world file
|
||||
|
||||
Supported vector formats include:
|
||||
ESRI Shapefiles
|
||||
PostgreSQL/PostGIS
|
||||
GRASS
|
||||
|
||||
|
||||
NOTE -- Please follow the installation instructions carefully.
|
||||
After untarring the distribution, you can find the HTML version of the
|
||||
installation document in qgis/doc/index.html. The installation document is
|
||||
also available as PDF in the same directory or on the website at
|
||||
http://qgis.org/docs/install.html.
|
||||
|
||||
HELP US -- Please submit bug reports using the QGIS bug tracker at:
|
||||
http://sourceforge.net/tracker/?group_id=55820&atid=478378
|
||||
When reporting a bug, either login to SourceForge or, if you don't
|
||||
have a SourceForge id, provide an email address where we can
|
||||
request additional information.
|
||||
|
||||
Please do not use the Bugs forum to report bugs.
|
||||
|
||||
SUPPORT - You can get support in the following ways:
|
||||
1. Using the QGIS community site at http://community.qgis.org
|
||||
2. Joining the qgis-users mailing list at:
|
||||
http://lists.sourceforge.net/lists/listinfo/qgis-user
|
||||
3. Using IRC by joining the #qgis channel on irc.freenode.net.
|
||||
Please wait around for a response to your question as many
|
||||
folks on the channel are doing other things and it may take a
|
||||
while for them to notice your question.
|
||||
|
||||
|
||||
|
||||
|
190
README.md
Normal file
190
README.md
Normal file
@ -0,0 +1,190 @@
|
||||
<img src="images/README-md/main_logo.png" width="300">
|
||||
|
||||
[](https://github.com/qgis/QGIS/actions/workflows/run-tests.yml?query=branch%3Amaster+event%3Apush)
|
||||
[](https://hub.docker.com/r/qgis/qgis/tags)
|
||||
[](https://dev.azure.com/qgis/QGIS/_build/latest?definitionId=1&branchName=master)
|
||||
[](https://securityscorecards.dev/viewer/?uri=github.com/qgis/QGIS)
|
||||
[](https://www.bestpractices.dev/projects/1581)
|
||||
[](https://github.com/qgis/QGIS/actions/workflows/mingw64.yml?query=branch%3Amaster+event%3Apush)
|
||||
[](https://doi.org/10.5281/zenodo.5869837)
|
||||
|
||||
QGIS is a full-featured, user-friendly, free-and-open-source (FOSS) geographical information system (GIS) that runs on Unix platforms, Windows, and MacOS.
|
||||
|
||||
<!-- TOC generated with https://freelance-tech-writer.github.io/table-of-contents-generator/index.html -->
|
||||
|
||||
- [Features](#features)
|
||||
- [1. Flexible and powerful spatial data management](#1-flexible-and-powerful-spatial-data-management)
|
||||
- [2. Beautiful cartography](#2-beautiful-cartography)
|
||||
- [3. Advanced and robust geospatial analysis](#3-advanced-and-robust-geospatial-analysis)
|
||||
- [4. Powerful customization and extensibility](#4-powerful-customization-and-extensibility)
|
||||
- [5. QGIS Server](#5-qgis-server)
|
||||
- [Under the hood](#under-the-hood)
|
||||
- [Versions and release cycle](#versions-and-release-cycle)
|
||||
- [Free and Open Source](#free-and-open-source)
|
||||
- [Installing and using QGIS](#installing-and-using-qgis)
|
||||
- [Documentation](#documentation)
|
||||
- [Help and support channels](#help-and-support-channels)
|
||||
- [Get involved with the community](#get-involved-with-the-community)
|
||||
|
||||
## Features
|
||||
|
||||
### 1. Flexible and powerful spatial data management
|
||||
|
||||
- Support for raster, vector, mesh, and point cloud data in a range of industry-standard formats
|
||||
- *Raster formats include*: GeoPackage, GeoTIFF, GRASS, ArcInfo binary and ASCII grids, ERDAS Imagine SDTS, WMS, WCS, PostgreSQL/PostGIS, and [other GDAL supported formats](https://gdal.org/drivers/raster/index.html).
|
||||
- *Vector formats include*: GeoPackage, ESRI shapefiles, GRASS, SpatiaLite, PostgreSQL/PostGIS, MSSQL, Oracle, WFS, Vector Tiles and [other OGR supported formats](https://www.gdal.org/ogr_formats.html).
|
||||
- *Mesh formats include*: NetCDF, GRIB, 2DM, and [other MDAL supported formats](https://github.com/lutraconsulting/MDAL#supported-formats).
|
||||
- *Point-cloud format*: LAS/LAZ and EPT datasets.
|
||||
- Data abstraction framework, with local files, spatial databases (PostGIS, SpatiaLite, SQL Server, Oracle, SAP HANA), and web services (WMS, WCS, WFS, ArcGIS REST) all accessed through a unified data model and browser interface, and as flexible layers in user-created projects
|
||||
- Spatial data creation via visual and numerical digitizing and editing, as well as georeferencing of raster and vector data
|
||||
- On-the-fly reprojection between coordinate reference systems (CRS)
|
||||
- Nominatim (OpenStreetMap) geocoder access
|
||||
- Temporal support
|
||||
|
||||
*Example: Temporal animation*
|
||||
|
||||

|
||||
|
||||
*Example: 3D map view*
|
||||
|
||||

|
||||
|
||||
### 2. Beautiful cartography
|
||||
- Large variety of rendering options in 2D and 3D
|
||||
- Fine control over symbology, labeling, legends and additional graphical elements for beautifully rendered maps
|
||||
- Respect for embedded styling in many spatial data sources (e.g. KML and TAB files, Mapbox-GL styled vector tiles)
|
||||
- In particular, near-complete replication (and significant extension) of symbology options that are available in proprietary software by ESRI
|
||||
- Advanced styling using data-defined overrides, blending modes, and draw effects
|
||||
- 500+ built-in color ramps (cpt-city, ColorBrewer, etc.)
|
||||
- Create and update maps with specified scale, extent, style, and decorations via saved layouts
|
||||
- Generate multiple maps (and reports) automatically using QGIS Atlas and QGIS Reports
|
||||
- Display and export elevation profile plots with flexible symbology
|
||||
- Flexible output direct to printer, or as image (raster), PDF, or SVG for further customization
|
||||
- On-the-fly rendering enhancements using geometry generators (e.g. create and style new geometries from existing features)
|
||||
- Preview modes for inclusive map making (e.g. monochrome, color blindness)
|
||||
|
||||
*[Example: Map of Bogota, Colombia in the style of Starry Starry Night, by Andrés Felipe Lancheros Sánchez](https://flic.kr/p/2jFfGJP)*
|
||||
|
||||

|
||||
|
||||
For more maps created with QGIS, visit the [QGIS Map Showcase Flickr Group](https://www.flickr.com/groups/2244553@N22/pool/with/50355460063/).
|
||||
|
||||

|
||||
|
||||
### 3. Advanced and robust geospatial analysis
|
||||
- Powerful processing framework with 200+ native processing algorithms
|
||||
- Access to 1000+ processing algorithms via providers such as GDAL, SAGA, GRASS, OrfeoToolbox, as well as custom models and processing scripts
|
||||
- Geospatial database engine (filters, joins, relations, forms, etc.), as close to datasource- and format-independent as possible
|
||||
- Immediate visualization of geospatial query and geoprocessing results
|
||||
- Model designer and batch processing
|
||||
|
||||
*Example: Travel isochrones*
|
||||
|
||||

|
||||
|
||||
*Example: Model designer*
|
||||
|
||||

|
||||
|
||||
### 4. Powerful customization and extensibility
|
||||
|
||||
- Fully customizable user experience, including user interface and application settings that cater to power-users and beginners alike
|
||||
- Rich [expression engine](https://docs.qgis.org/testing/en/docs/user_manual/working_with_vector/expression.html) for maximum flexibility in visualization and processing
|
||||
- Broad and varied [plugin ecosystem](https://plugins.qgis.org/) that includes data connectors, digitizing aids, advanced analysis and charting tools,
|
||||
in-the-field data capture, conversion of ESRI style files, etc.
|
||||
- Style manager for creating, storing, and managing styles
|
||||
- [QGIS style hub](https://plugins.qgis.org/styles/) for easy sharing of styles
|
||||
- Python and C++ API for standalone (headless) applications as well as in-application comprehensive scripting (PyQGIS)
|
||||
|
||||
*Example: Style manager*
|
||||
|
||||

|
||||
|
||||
*Example: Plugins*
|
||||
|
||||

|
||||
|
||||
<!-- Kill this one for now, since the example provided is Python2 not 3
|
||||
Example: Python console
|
||||
|
||||

|
||||
-->
|
||||
|
||||
### 5. QGIS Server
|
||||
|
||||
Headless map server -- running on Linux, macOS, Windows, or in a docker container -- that shares the same code base as QGIS.
|
||||
|
||||
- Industry-standard protocols (WMS, WFS, WFS3/OGC API for Features and WCS) allow plug-n-play with any software stack
|
||||
- Works with any web server (Apache, nginx, etc) or standalone
|
||||
- All beautiful QGIS cartography is supported with best-in-class support for printing
|
||||
- Fully customizable with Python scripting support
|
||||
|
||||
*Example: QGIS server WMS response*
|
||||
|
||||

|
||||
|
||||
*Example: QGIS server WFS response*
|
||||
|
||||

|
||||
|
||||
## Under the hood
|
||||
|
||||
QGIS is developed using the [Qt toolkit](https://qt.io) and C++, since 2002, and has a pleasing, easy to use graphical
|
||||
user interface with multilingual support. It is maintained by an active developer team and supported by vibrant
|
||||
community of GIS professionals and enthusiasts as well as geospatial data publishers and end-users.
|
||||
|
||||
### Versions and release cycle
|
||||
|
||||
QGIS development and releases follow a [time based schedule/roadmap](https://www.qgis.org/en/site/getinvolved/development/roadmap.html). There are three main branches of QGIS that users can install. These are the **Long Term Release (LTR)** branch, the **Latest Release (LR)** branch, and the **Development (Nightly)** branch.
|
||||
|
||||
Every month, there is a **Point Release** that provides bug-fixes to the LTR and LR.
|
||||
|
||||
### Free and Open Source
|
||||
|
||||
QGIS is released under the GNU Public License (GPL) Version 2 or any later version.
|
||||
Developing QGIS under this license means that you can (if you want to) inspect
|
||||
and modify the source code and guarantees that you, our happy user will always
|
||||
have access to a GIS program that is free of cost and can be freely
|
||||
modified.
|
||||
|
||||
QGIS is part of the Open-Source Geospatial Foundation ([OSGeo](https://www.osgeo.org/)), offering a range of complementary open-source GIS software projects.
|
||||
|
||||
## Installing and using QGIS
|
||||
|
||||
Precompiled binaries for QGIS are available at [the QGIS.org download page](https://www.qgis.org/en/site/forusers/download.html).
|
||||
Please follow the installation instructions carefully.
|
||||
|
||||
The [building guide](INSTALL.md) can be used to get started with building QGIS from source.
|
||||
|
||||
For installation of QGIS Server, see its [getting started documentation](https://docs.qgis.org/testing/en/docs/server_manual/getting_started.html).
|
||||
|
||||
### Documentation
|
||||
|
||||
A range of [documentation](https://qgis.org/resources/hub/#documentation) is available. This includes:
|
||||
|
||||
- [Training Manual](https://docs.qgis.org/latest/en/docs/training_manual/index.html)
|
||||
- [QGIS User Guide](https://docs.qgis.org/latest/en/docs/user_manual/index.html)
|
||||
- [QGIS Server Guide](https://docs.qgis.org/latest/en/docs/server_manual/index.html)
|
||||
- [Visual Changelog](https://qgis.org/project/visual-changelogs/)
|
||||
- [Documentation Guidelines](https://docs.qgis.org/latest/en/docs/documentation_guidelines/index.html)
|
||||
- [QGIS Python (PyQGIS) Cookbook](https://docs.qgis.org/latest/en/docs/pyqgis_developer_cookbook/index.html)
|
||||
- [QGIS Python (PyQGIS) API](https://qgis.org/pyqgis/)
|
||||
- [QGIS C++ API](https://qgis.org/api/)
|
||||
- [Developers Guide](https://docs.qgis.org/latest/en/docs/developers_guide/index.html)
|
||||
|
||||
### Help and support channels
|
||||
|
||||
There are several channels where you can find help and support for QGIS:
|
||||
|
||||
- Using the [QGIS community site](https://qgis.org)
|
||||
- Joining the [qgis-users mailing list](https://lists.osgeo.org/mailman/listinfo/qgis-user)
|
||||
- Chatting with other users real-time. *Please wait around for a response to your question as many folks on the channel are doing other things and it may take a while for them to notice your question. The following paths all take you to the same chat room:*
|
||||
- Using an IRC client and joining the
|
||||
[#qgis](https://web.libera.chat/?channels=#qgis) channel on irc.libera.chat.
|
||||
- Using a Matrix client and joining the [#qgis:osgeo.org](https://matrix.to/#/#qgis:osgeo.org) room.
|
||||
- At the [GIS stackexchange](https://gis.stackexchange.com/) or [r/QGIS reddit](https://www.reddit.com/r/QGIS/), which are not maintained by the QGIS team, but where the QGIS and broader GIS community provides lots of advice
|
||||
- [Other support channels](https://qgis.org/resources/support/)
|
||||
|
||||
## Get involved with the community
|
||||
|
||||
[Contribution guidelines for this project](CONTRIBUTING.md)
|
10
TODO
10
TODO
@ -1,10 +0,0 @@
|
||||
TODO,v 1.21 2004/06/03 18:36:46 gsherman Exp
|
||||
#############################################################################
|
||||
TODO List for 0.8 (in no order of importance)
|
||||
#############################################################################
|
||||
1. Complete WMS support
|
||||
2. Implement new legend
|
||||
3. New GRASS tools in toolbox
|
||||
4. Editing fixups
|
||||
5. Implement Phase I of take over the world
|
||||
6. Rethink Phase I
|
684
acinclude.m4
684
acinclude.m4
@ -1,684 +0,0 @@
|
||||
dnl ------------------------------------------------------------------------
|
||||
dnl Detect if this is a 64bit environment
|
||||
dnl
|
||||
dnl it sets:
|
||||
dnl _lib
|
||||
dnl ------------------------------------------------------------------------
|
||||
AC_DEFUN([AQ_CHECK_LIB64],
|
||||
[
|
||||
if test `echo ${libdir} | sed -e 's#.*lib64.*#64#'` = "64"; then
|
||||
_lib="lib64"
|
||||
else
|
||||
_lib="lib"
|
||||
fi
|
||||
])
|
||||
|
||||
dnl ------------------------------------------------------------------------
|
||||
dnl Detect GDAL/OGR
|
||||
dnl
|
||||
dnl use AQ_CHECK_GDAL to detect GDAL and OGR
|
||||
dnl it sets:
|
||||
dnl GDAL_CFLAGS
|
||||
dnl GDAL_LDADD
|
||||
dnl ------------------------------------------------------------------------
|
||||
|
||||
# Check for GDAL and OGR compiler and linker flags
|
||||
|
||||
AC_DEFUN([AQ_CHECK_GDAL],
|
||||
[
|
||||
AC_ARG_WITH([gdal],
|
||||
AC_HELP_STRING([--with-gdal=path],
|
||||
[Full path to 'gdal-config' script, e.g. '--with-gdal=/usr/local/bin/gdal-config']),
|
||||
[ac_gdal_config_path=$withval])
|
||||
|
||||
if test x"$ac_gdal_config_path" = x ; then
|
||||
ac_gdal_config_path=`which gdal-config`
|
||||
fi
|
||||
|
||||
ac_gdal_config_path=`dirname $ac_gdal_config_path 2> /dev/null`
|
||||
AC_PATH_PROG(GDAL_CONFIG, gdal-config, no, $ac_gdal_config_path)
|
||||
|
||||
if test x${GDAL_CONFIG} = xno ; then
|
||||
AC_MSG_ERROR([gdal-config not found! Supply it with --with-gdal=PATH])
|
||||
else
|
||||
AC_MSG_CHECKING([for OGR in GDAL])
|
||||
if test x`$GDAL_CONFIG --ogr-enabled` = "xno" ; then
|
||||
AC_MSG_ERROR([GDAL must be compiled with OGR support and currently is not.])
|
||||
fi
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_MSG_CHECKING([GDAL_CFLAGS])
|
||||
GDAL_CFLAGS=`$GDAL_CONFIG --cflags`
|
||||
AC_MSG_RESULT($GDAL_CFLAGS)
|
||||
|
||||
AC_MSG_CHECKING([GDAL_LDADD])
|
||||
GDAL_LDADD=`$GDAL_CONFIG --libs`
|
||||
AC_MSG_RESULT($GDAL_LDADD)
|
||||
|
||||
ac_gdalogr_version=`$GDAL_CONFIG --version`
|
||||
ac_gdalogr="yes"
|
||||
fi
|
||||
|
||||
AC_SUBST(GDAL_CFLAGS)
|
||||
AC_SUBST(GDAL_LDADD)
|
||||
])
|
||||
|
||||
dnl ------------------------------------------------------------------------
|
||||
dnl Detect GEOS
|
||||
dnl
|
||||
dnl use AQ_CHECK_GEOS to detect GEOS
|
||||
dnl it sets:
|
||||
dnl GEOS_CFLAGS
|
||||
dnl GEOS_LDADD
|
||||
dnl ------------------------------------------------------------------------
|
||||
|
||||
# Check for GEOS
|
||||
|
||||
AC_DEFUN([AQ_CHECK_GEOS],
|
||||
[
|
||||
AC_ARG_WITH([geos],
|
||||
AC_HELP_STRING([--with-geos=path],
|
||||
[Full path to 'geos-config' script, e.g. '--with-geos=/usr/local/bin/geos-config']),
|
||||
[ac_geos_config_path=$withval])
|
||||
|
||||
if test x"$ac_geos_config_path" = x ; then
|
||||
ac_geos_config_path=`which geos-config`
|
||||
fi
|
||||
|
||||
ac_geos_config_path=`dirname $ac_geos_config_path 2> /dev/null`
|
||||
AC_PATH_PROG(GEOS_CONFIG, geos-config, no, $ac_geos_config_path)
|
||||
|
||||
if test x${GEOS_CONFIG} = xno ; then
|
||||
AC_MSG_ERROR([geos-config not found! Supply it with --with-geos=PATH])
|
||||
else
|
||||
ac_geos_version=`${GEOS_CONFIG} --version`
|
||||
if test `echo ${ac_geos_version} | sed -e 's#2\.[0-9].*#OK#'` != OK ; then
|
||||
AC_MSG_ERROR([Geos Version 2.x.x is needed, but you have $ac_geos_version!])
|
||||
else
|
||||
AC_MSG_CHECKING([GEOS_CFLAGS])
|
||||
GEOS_CFLAGS=`$GEOS_CONFIG --cflags`
|
||||
AC_MSG_RESULT($GEOS_CFLAGS)
|
||||
|
||||
AC_MSG_CHECKING([GEOS_LDADD])
|
||||
GEOS_LDADD=`$GEOS_CONFIG --libs`
|
||||
AC_MSG_RESULT($GEOS_LDADD)
|
||||
|
||||
ac_geos="yes"
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(GEOS_CFLAGS)
|
||||
AC_SUBST(GEOS_LDADD)
|
||||
])
|
||||
|
||||
dnl ------------------------------------------------------------------------
|
||||
dnl Detect QT3
|
||||
dnl
|
||||
dnl use AQ_CHECK_QT to detect QT3
|
||||
dnl it sets:
|
||||
dnl QT_CXXFLAGS
|
||||
dnl QT_LDADD
|
||||
dnl QT_GUILINK
|
||||
dnl QASSISTANTCLIENT_LDADD
|
||||
dnl ------------------------------------------------------------------------
|
||||
|
||||
# Check for Qt compiler flags, linker flags, and binary packages
|
||||
|
||||
AC_DEFUN([AQ_CHECK_QT],
|
||||
[
|
||||
AC_REQUIRE([AC_PROG_CXX])
|
||||
AC_REQUIRE([AC_PATH_X])
|
||||
|
||||
AC_MSG_CHECKING([QTDIR])
|
||||
AC_ARG_WITH([qtdir], [ --with-qtdir=DIR Qt installation directory [default=/usr/local]], QTDIR=$withval)
|
||||
# Check that QTDIR is defined or that --with-qtdir given
|
||||
if test x$QTDIR = x ; then
|
||||
QT_SEARCH=" /usr/lib/qt31 /usr/lib64/qt31 /usr/local/qt31 /usr/lib/qt3 /usr/lib64/qt3 /usr/local/qt3 /usr/lib/qt2 /usr/lib64/qt2 /usr/local/qt2 /usr/lib/qt /usr/lib64/qt /usr/local/qt /usr /usr/local"
|
||||
for i in $QT_SEARCH; do
|
||||
if test x$QTDIR = x; then
|
||||
if test -f $i/include/qt/qglobal.h -o -f $i/include/qglobal.h -o -f $i/include/qt3/qglobal.h; then
|
||||
QTDIR=$i
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if test x$QTDIR = x ; then
|
||||
AC_MSG_ERROR([*** QTDIR must be defined, or --with-qtdir option given])
|
||||
fi
|
||||
AC_MSG_RESULT([$QTDIR])
|
||||
|
||||
# Change backslashes in QTDIR to forward slashes to prevent escaping
|
||||
# problems later on in the build process, mainly for Cygwin build
|
||||
# environment using MSVC as the compiler
|
||||
# (include/Qt is used on Qt4)
|
||||
# TODO: Use sed instead of perl
|
||||
QTDIR=`echo $QTDIR | perl -p -e 's/\\\\/\\//g'`
|
||||
|
||||
# Check for QT includedir
|
||||
if test -f $QTDIR/include/qt/qglobal.h; then
|
||||
QTINC=$QTDIR/include/qt
|
||||
QTVERTEST=$QTDIR/include/qt
|
||||
elif test -f $QTDIR/include/qt3/qglobal.h; then
|
||||
QTINC=$QTDIR/include/qt3
|
||||
QTVERTEST=$QTDIR/include/qt3
|
||||
elif test -f $QTDIR/include/Qt/qglobal.h; then
|
||||
QTINC=$QTDIR/include
|
||||
QTVERTEST=$QTDIR/include/Qt
|
||||
else
|
||||
QTINC=$QTDIR/include
|
||||
QTVERTEST=$QTDIR/include
|
||||
fi
|
||||
|
||||
# Figure out which version of Qt we are using
|
||||
AC_MSG_CHECKING([Qt version])
|
||||
QT_VER=`grep 'define.*QT_VERSION_STR\W' $QTVERTEST/qglobal.h | perl -p -e 's/\D//g'`
|
||||
case "${QT_VER}" in
|
||||
41*|40*)
|
||||
QT_MAJOR="4"
|
||||
QT4_3SUPPORTINC=$QTDIR/include/Qt3Support
|
||||
QT4_COREINC=$QTDIR/include/QtCore
|
||||
QT4_DESIGNERINC=$QTDIR/include/QtDesigner
|
||||
QT4_GUIINC=$QTDIR/include/QtGui
|
||||
QT4_NETWORKINC=$QTDIR/include/QtNetwork
|
||||
QT4_OPENGLINC=$QTDIR/include/QtOpenGL
|
||||
QT4_SQLINC=$QTDIR/include/QtSql
|
||||
QT4_XMLINC=$QTDIR/include/QtXml
|
||||
QT4_DEFAULTINC=$QTDIR/mkspecs/default
|
||||
;;
|
||||
33*)
|
||||
QT_MAJOR="3"
|
||||
;;
|
||||
# 32*)
|
||||
# QT_MAJOR="3"
|
||||
# ;;
|
||||
# 31*)
|
||||
# QT_MAJOR="3"
|
||||
# ;;
|
||||
*)
|
||||
AC_MSG_ERROR([*** Qt version 3.3.x or higher is required])
|
||||
;;
|
||||
esac
|
||||
AC_MSG_RESULT([$QT_VER ($QT_MAJOR)])
|
||||
|
||||
if test $QT_MAJOR = "3" ; then
|
||||
# Check that moc is in path
|
||||
AC_CHECK_PROG(MOC, moc, moc)
|
||||
if test x$MOC = x ; then
|
||||
AC_MSG_ERROR([*** moc must be in path])
|
||||
fi
|
||||
# uic is the Qt user interface compiler
|
||||
AC_CHECK_PROG(UIC, uic, uic)
|
||||
if test x$UIC = x ; then
|
||||
AC_MSG_ERROR([*** uic must be in path])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $QT_MAJOR = "4" ; then
|
||||
# Hard code things for the moment
|
||||
|
||||
# Check that moc is in path
|
||||
AC_CHECK_PROG(MOC, moc, $QTDIR/bin/moc, , $QTDIR/bin)
|
||||
if test x$MOC = x ; then
|
||||
AC_MSG_ERROR([*** moc must be in path])
|
||||
fi
|
||||
# uic3 is the Qt user interface compiler in Qt3 legacy mode
|
||||
AC_CHECK_PROG(UIC, uic3, $QTDIR/bin/uic3, , $QTDIR/bin)
|
||||
if test x$UIC = x ; then
|
||||
AC_MSG_ERROR([*** uic3 must be in path])
|
||||
fi
|
||||
fi
|
||||
|
||||
# qembed is the Qt data embedding utility.
|
||||
# It is located in $QTDIR/tools/qembed, and must be compiled and installed
|
||||
# manually, we'll let it slide if it isn't present
|
||||
### AC_CHECK_PROG(QEMBED, qembed, qembed)
|
||||
# Calculate Qt include path
|
||||
if test $QT_MAJOR = "3" ; then
|
||||
QT_CXXFLAGS="-I$QTINC"
|
||||
fi
|
||||
if test $QT_MAJOR = "4" ; then
|
||||
QT_CXXFLAGS="-DQT3_SUPPORT -I$QT4_DEFAULTINC -I$QT4_3SUPPORTINC -I$QT4_COREINC -I$QT4_DESIGNERINC -I$QT4_GUIINC -I$QT4_NETWORKINC -I$QT4_OPENGLINC -I$QT4_SQLINC -I$QT4_XMLINC -I$QTINC"
|
||||
fi
|
||||
QT_IS_EMBEDDED="no"
|
||||
# On unix, figure out if we're doing a static or dynamic link
|
||||
|
||||
case "${host}" in
|
||||
*-cygwin)
|
||||
AC_DEFINE_UNQUOTED(WIN32, "", Defined if on Win32 platform)
|
||||
echo "$QTDIR/lib/qt-mt$QT_VER.lib"
|
||||
if test -f "$QTDIR/lib/qt-mt$QT_VER.lib" ; then
|
||||
QT_LIB="qt-mt$QT_VER.lib"
|
||||
QT_IS_STATIC="no"
|
||||
QT_IS_MT="yes"
|
||||
|
||||
elif test -f "$QTDIR/lib/qt$QT_VER.lib" ; then
|
||||
QT_LIB="qt$QT_VER.lib"
|
||||
QT_IS_STATIC="no"
|
||||
QT_IS_MT="no"
|
||||
elif test -f "$QTDIR/lib/qt.lib" ; then
|
||||
QT_LIB="qt.lib"
|
||||
QT_IS_STATIC="yes"
|
||||
QT_IS_MT="no"
|
||||
elif test -f "$QTDIR/lib/qt-mt.lib" ; then
|
||||
QT_LIB="qt-mt.lib"
|
||||
QT_IS_STATIC="yes"
|
||||
QT_IS_MT="yes"
|
||||
fi
|
||||
;;
|
||||
*-darwin*)
|
||||
# determin static or dynamic -- prefer dynamic
|
||||
QT_IS_DYNAMIC=`ls $QTDIR/lib/libqt*.dylib 2> /dev/null`
|
||||
if test "x$QT_IS_DYNAMIC" = x; then
|
||||
QT_IS_STATIC=`ls $QTDIR/lib/libqt*.a 2> /dev/null`
|
||||
if test "x$QT_IS_STATIC" = x; then
|
||||
QT_IS_STATIC="no"
|
||||
AC_MSG_ERROR([*** Couldn't find any Qt libraries in $QTDIR/${_lib}])
|
||||
else
|
||||
QT_IS_STATIC="yes"
|
||||
fi
|
||||
else
|
||||
QT_IS_STATIC="no"
|
||||
fi
|
||||
# set link parameters based on shared/mt libs or static lib
|
||||
if test "x`ls $QTDIR/lib/libqt.a* 2> /dev/null`" != x ; then
|
||||
QT_LIB="-lqt"
|
||||
QT_IS_MT="no"
|
||||
elif test "x`ls $QTDIR/lib/libqt-mt.*.dylib 2> /dev/null`" != x ; then
|
||||
QT_LIB="-lqt-mt"
|
||||
QT_IS_MT="yes"
|
||||
elif test "x`ls $QTDIR/lib/libqt.*.dylib 2> /dev/null`" != x ; then
|
||||
QT_LIB="-lqt"
|
||||
QT_IS_MT="no"
|
||||
elif test "x`ls $QTDIR/lib/libqte.* 2> /dev/null`" != x ; then
|
||||
QT_LIB="-lqte"
|
||||
QT_IS_MT="no"
|
||||
QT_IS_EMBEDDED="yes"
|
||||
elif test "x`ls $QTDIR/lib/libqte-mt.* 2> /dev/null`" != x ; then
|
||||
QT_LIB="-lqte-mt"
|
||||
QT_IS_MT="yes"
|
||||
QT_IS_EMBEDDED="yes"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
# determin static or dynamic -- prefer dynamic
|
||||
QT_IS_DYNAMIC=`ls $QTDIR/${_lib}/libqt*.so $QTDIR/${_lib}/libQtCore.so 2> /dev/null`
|
||||
if test "x$QT_IS_DYNAMIC" = x; then
|
||||
QT_IS_STATIC=`ls $QTDIR/${_lib}/libqt*.a $QTDIR/${_lib}/libQtCore.a 2> /dev/null`
|
||||
if test "x$QT_IS_STATIC" = x; then
|
||||
QT_IS_STATIC="no"
|
||||
AC_MSG_ERROR([*** Couldn't find any Qt libraries in $QTDIR/${_lib}])
|
||||
else
|
||||
QT_IS_STATIC="yes"
|
||||
fi
|
||||
else
|
||||
QT_IS_STATIC="no"
|
||||
fi
|
||||
# set link parameters based on shared/mt libs or static lib
|
||||
if test "x`ls $QTDIR/${_lib}/libqt.a* 2> /dev/null`" != x ; then
|
||||
QT_LIB="-lqt"
|
||||
QT_IS_MT="no"
|
||||
elif test "x`ls $QTDIR/${_lib}/libqt-mt.so* 2> /dev/null`" != x ; then
|
||||
QT_LIB="-lqt-mt"
|
||||
QT_IS_MT="yes"
|
||||
elif test "x`ls $QTDIR/${_lib}/libqt.so* 2> /dev/null`" != x ; then
|
||||
QT_LIB="-lqt"
|
||||
QT_IS_MT="no"
|
||||
elif test "x`ls $QTDIR/${_lib}/libqte.* 2> /dev/null`" != x ; then
|
||||
QT_LIB="-lqte"
|
||||
QT_IS_MT="no"
|
||||
QT_IS_EMBEDDED="yes"
|
||||
elif test "x`ls $QTDIR/${_lib}/libqte-mt.* 2> /dev/null`" != x ; then
|
||||
QT_LIB="-lqte-mt"
|
||||
QT_IS_MT="yes"
|
||||
QT_IS_EMBEDDED="yes"
|
||||
elif test "x`ls $QTDIR/${_lib}/libQtCore.* 2> /dev/null`" != x ; then
|
||||
QT_LIB="-lQtCore -lQt3Support -lQtGui -lQtNetwork"
|
||||
QT_CXXFLAGS="-DQT3_SUPPORT -I$QT4_DEFAULTINC -I$QT4_3SUPPORTINC -I$QT4_COREINC -I$QT4_DESIGNERINC -I$QT4_GUIINC -I$QT4_NETWORKINC -I$QT4_OPENGLINC -I$QT4_SQLINC -I$QT4_XMLINC -I$QTINC"
|
||||
QT_IS_MT="yes"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_MSG_CHECKING([if Qt is static])
|
||||
AC_MSG_RESULT([$QT_IS_STATIC])
|
||||
AC_MSG_CHECKING([if Qt is multithreaded])
|
||||
AC_MSG_RESULT([$QT_IS_MT])
|
||||
AC_MSG_CHECKING([if Qt is embedded])
|
||||
AC_MSG_RESULT([$QT_IS_EMBEDDED])
|
||||
|
||||
QT_GUILINK=""
|
||||
QASSISTANTCLIENT_LDADD="-lqassistantclient"
|
||||
case "${host}" in
|
||||
*irix*)
|
||||
QT_LIBS="$QT_LIB"
|
||||
if test $QT_IS_STATIC = yes ; then
|
||||
QT_LIBS="$QT_LIBS -L$x_libraries -lXext -lX11 -lm -lSM -lICE"
|
||||
fi
|
||||
;;
|
||||
|
||||
*linux*)
|
||||
QT_LIBS="$QT_LIB"
|
||||
if test $QT_IS_STATIC = yes && test $QT_IS_EMBEDDED = no; then
|
||||
QT_LIBS="$QT_LIBS -L$x_libraries -lXext -lX11 -lm -lSM -lICE -ldl -ljpeg"
|
||||
fi
|
||||
;;
|
||||
|
||||
*freebsd*)
|
||||
QT_LIBS="$QT_LIB"
|
||||
if test $QT_IS_STATIC = yes && test $QT_IS_EMBEDDED = no; then
|
||||
QT_LIBS="$QT_LIBS -L$x_libraries -lXext -lX11 -lm -lSM -lICE -ldl -ljpeg -lpthread"
|
||||
else
|
||||
QT_LIBS="$QT_LIBS -lpthread"
|
||||
fi
|
||||
;;
|
||||
|
||||
*darwin*)
|
||||
QT_LIBS="$QT_LIB"
|
||||
if test $QT_IS_STATIC = yes && test $QT_IS_EMBEDDED = no; then
|
||||
QT_LIBS="$QT_LIBS -L$x_libraries -lXext -lX11 -lm -lSM -lICE -ldl -ljpeg"
|
||||
fi
|
||||
;;
|
||||
|
||||
*osf*)
|
||||
# Digital Unix (aka DGUX aka Tru64)
|
||||
QT_LIBS="$QT_LIB"
|
||||
if test $QT_IS_STATIC = yes ; then
|
||||
QT_LIBS="$QT_LIBS -L$x_libraries -lXext -lX11 -lm -lSM -lICE"
|
||||
fi
|
||||
;;
|
||||
|
||||
*solaris*)
|
||||
QT_LIBS="$QT_LIB"
|
||||
if test $QT_IS_STATIC = yes ; then
|
||||
QT_LIBS="$QT_LIBS -L$x_libraries -lXext -lX11 -lm -lSM -lICE -lresolv -lsocket -lnsl"
|
||||
fi
|
||||
;;
|
||||
|
||||
*win*)
|
||||
# linker flag to suppress console when linking a GUI app on Win32
|
||||
QT_GUILINK="/subsystem:windows"
|
||||
if test $QT_MAJOR = "3" ; then
|
||||
if test $QT_IS_MT = yes ; then
|
||||
QT_LIBS="/nodefaultlib:libcmt"
|
||||
else
|
||||
QT_LIBS="/nodefaultlib:libc"
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $QT_IS_STATIC = yes ; then
|
||||
QT_LIBS="$QT_LIBS $QT_LIB kernel32.lib user32.lib gdi32.lib comdlg32.lib ole32.lib shell32.lib imm32.lib advapi32.lib wsock32.lib winspool.lib winmm.lib netapi32.lib"
|
||||
if test $QT_MAJOR = "3" ; then
|
||||
QT_LIBS="$QT_LIBS qtmain.lib"
|
||||
fi
|
||||
else
|
||||
QT_LIBS="$QT_LIBS $QT_LIB"
|
||||
if test $QT_MAJOR = "3" ; then
|
||||
QT_CXXFLAGS="$QT_CXXFLAGS -DQT_DLL"
|
||||
QT_LIBS="$QT_LIBS qtmain.lib qui.lib user32.lib netapi32.lib"
|
||||
fi
|
||||
fi
|
||||
QASSISTANTCLIENT_LDADD="qassistantclient.lib"
|
||||
;;
|
||||
esac
|
||||
|
||||
if test x"$QT_IS_EMBEDDED" = "xyes" ; then
|
||||
QT_CXXFLAGS="-DQWS $QT_CXXFLAGS"
|
||||
fi
|
||||
|
||||
if test x"$QT_IS_MT" = "xyes" ; then
|
||||
QT_CXXFLAGS="$QT_CXXFLAGS -D_REENTRANT -DQT_THREAD_SUPPORT"
|
||||
fi
|
||||
|
||||
QT_LDADD="-L$QTDIR/${_lib} $QT_LIBS"
|
||||
|
||||
if test x$QT_IS_STATIC = xyes ; then
|
||||
OLDLIBS="$LIBS"
|
||||
LIBS="$QT_LDADD"
|
||||
AC_CHECK_LIB(Xft, XftFontOpen, QT_LDADD="$QT_LDADD -lXft")
|
||||
LIBS="$LIBS"
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([QT_CXXFLAGS])
|
||||
AC_MSG_RESULT([$QT_CXXFLAGS])
|
||||
AC_MSG_CHECKING([QT_LDADD])
|
||||
AC_MSG_RESULT([$QT_LDADD])
|
||||
|
||||
AC_SUBST(QT_CXXFLAGS)
|
||||
AC_SUBST(QT_LDADD)
|
||||
AC_SUBST(QT_GUILINK)
|
||||
AC_SUBST(QASSISTANTCLIENT_LDADD)
|
||||
AC_SUBST(QTDIR)
|
||||
])
|
||||
|
||||
|
||||
|
||||
# Configure path for the GNU Scientific Library
|
||||
# Christopher R. Gabriel <cgabriel@linux.it>, April 2000
|
||||
|
||||
|
||||
AC_DEFUN([AM_PATH_GSL],
|
||||
[
|
||||
AC_ARG_WITH(gsl-prefix,[ --with-gsl-prefix=PFX Prefix where GSL is installed (optional)],
|
||||
gsl_prefix="$withval", gsl_prefix="")
|
||||
AC_ARG_WITH(gsl-exec-prefix,[ --with-gsl-exec-prefix=PFX Exec prefix where GSL is installed (optional)],
|
||||
gsl_exec_prefix="$withval", gsl_exec_prefix="")
|
||||
AC_ARG_ENABLE(gsltest, [ --disable-gsltest Do not try to compile and run a test GSL program],
|
||||
, enable_gsltest=yes)
|
||||
|
||||
if test "x${GSL_CONFIG+set}" != xset ; then
|
||||
if test "x$gsl_prefix" != x ; then
|
||||
GSL_CONFIG="$gsl_prefix/bin/gsl-config"
|
||||
fi
|
||||
if test "x$gsl_exec_prefix" != x ; then
|
||||
GSL_CONFIG="$gsl_exec_prefix/bin/gsl-config"
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_PATH_PROG(GSL_CONFIG, gsl-config, no)
|
||||
min_gsl_version=ifelse([$1], ,0.2.5,$1)
|
||||
AC_MSG_CHECKING(for GSL - version >= $min_gsl_version)
|
||||
no_gsl=""
|
||||
if test "$GSL_CONFIG" = "no" ; then
|
||||
no_gsl=yes
|
||||
else
|
||||
GSL_CFLAGS=`$GSL_CONFIG --cflags`
|
||||
GSL_LIBS=`$GSL_CONFIG --libs`
|
||||
|
||||
gsl_major_version=`$GSL_CONFIG --version | \
|
||||
sed 's/^\([[0-9]]*\).*/\1/'`
|
||||
if test "x${gsl_major_version}" = "x" ; then
|
||||
gsl_major_version=0
|
||||
fi
|
||||
|
||||
gsl_minor_version=`$GSL_CONFIG --version | \
|
||||
sed 's/^\([[0-9]]*\)\.\{0,1\}\([[0-9]]*\).*/\2/'`
|
||||
if test "x${gsl_minor_version}" = "x" ; then
|
||||
gsl_minor_version=0
|
||||
fi
|
||||
|
||||
gsl_micro_version=`$GSL_CONFIG --version | \
|
||||
sed 's/^\([[0-9]]*\)\.\{0,1\}\([[0-9]]*\)\.\{0,1\}\([[0-9]]*\).*/\3/'`
|
||||
if test "x${gsl_micro_version}" = "x" ; then
|
||||
gsl_micro_version=0
|
||||
fi
|
||||
|
||||
if test "x$enable_gsltest" = "xyes" ; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $GSL_CFLAGS"
|
||||
LIBS="$LIBS $GSL_LIBS"
|
||||
|
||||
rm -f conf.gsltest
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
char* my_strdup (const char *str);
|
||||
|
||||
char*
|
||||
my_strdup (const char *str)
|
||||
{
|
||||
char *new_str;
|
||||
|
||||
if (str)
|
||||
{
|
||||
new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char));
|
||||
strcpy (new_str, str);
|
||||
}
|
||||
else
|
||||
new_str = NULL;
|
||||
|
||||
return new_str;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
int major = 0, minor = 0, micro = 0;
|
||||
int n;
|
||||
char *tmp_version;
|
||||
|
||||
system ("touch conf.gsltest");
|
||||
|
||||
/* HP/UX 9 (%@#!) writes to sscanf strings */
|
||||
tmp_version = my_strdup("$min_gsl_version");
|
||||
|
||||
n = sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) ;
|
||||
|
||||
if (n != 2 && n != 3) {
|
||||
printf("%s, bad version string\n", "$min_gsl_version");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (($gsl_major_version > major) ||
|
||||
(($gsl_major_version == major) && ($gsl_minor_version > minor)) ||
|
||||
(($gsl_major_version == major) && ($gsl_minor_version == minor) && ($gsl_micro_version >= micro)))
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\n*** 'gsl-config --version' returned %d.%d.%d, but the minimum version\n", $gsl_major_version, $gsl_minor_version, $gsl_micro_version);
|
||||
printf("*** of GSL required is %d.%d.%d. If gsl-config is correct, then it is\n", major, minor, micro);
|
||||
printf("*** best to upgrade to the required version.\n");
|
||||
printf("*** If gsl-config was wrong, set the environment variable GSL_CONFIG\n");
|
||||
printf("*** to point to the correct copy of gsl-config, and remove the file\n");
|
||||
printf("*** config.cache before re-running configure\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
],, no_gsl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
fi
|
||||
if test "x$no_gsl" = x ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$2], , :, [$2])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test "$GSL_CONFIG" = "no" ; then
|
||||
echo "*** The gsl-config script installed by GSL could not be found"
|
||||
echo "*** If GSL was installed in PREFIX, make sure PREFIX/bin is in"
|
||||
echo "*** your path, or set the GSL_CONFIG environment variable to the"
|
||||
echo "*** full path to gsl-config."
|
||||
else
|
||||
if test -f conf.gsltest ; then
|
||||
:
|
||||
else
|
||||
echo "*** Could not run GSL test program, checking why..."
|
||||
CFLAGS="$CFLAGS $GSL_CFLAGS"
|
||||
LIBS="$LIBS $GSL_LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <stdio.h>
|
||||
], [ return 0; ],
|
||||
[ echo "*** The test program compiled, but did not run. This usually means"
|
||||
echo "*** that the run-time linker is not finding GSL or finding the wrong"
|
||||
echo "*** version of GSL. If it is not finding GSL, you'll need to set your"
|
||||
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
|
||||
echo "*** to the installed location Also, make sure you have run ldconfig if that"
|
||||
echo "*** is required on your system"
|
||||
echo "***"
|
||||
echo "*** If you have an old version installed, it is best to remove it, although"
|
||||
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
|
||||
[ echo "*** The test program failed to compile or link. See the file config.log for the"
|
||||
echo "*** exact error that occured. This usually means GSL was incorrectly installed"
|
||||
echo "*** or that you have moved GSL since it was installed. In the latter case, you"
|
||||
echo "*** may want to edit the gsl-config script: $GSL_CONFIG" ])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
fi
|
||||
# GSL_CFLAGS=""
|
||||
# GSL_LIBS=""
|
||||
ifelse([$3], , :, [$3])
|
||||
fi
|
||||
AC_SUBST(GSL_CFLAGS)
|
||||
AC_SUBST(GSL_LIBS)
|
||||
rm -f conf.gsltest
|
||||
])
|
||||
|
||||
dnl Python
|
||||
dnl Available from the GNU Autoconf Macro Archive at:
|
||||
dnl http://www.gnu.org/software/ac-archive/htmldoc/ax_python.html
|
||||
dnl
|
||||
AC_DEFUN([AX_PYTHON],
|
||||
[
|
||||
AC_ARG_WITH([python],
|
||||
AC_HELP_STRING([--with-python],
|
||||
[Include Python scripting support ]))
|
||||
|
||||
if test x"$with_python" = "x"; then
|
||||
AC_MSG_RESULT( Not using python )
|
||||
ac_use_python=no
|
||||
else
|
||||
AC_MSG_CHECKING(for python build information)
|
||||
for python in python2.4 python2.3 python2.2 python2.1 python; do
|
||||
AC_CHECK_PROGS(PYTHON_BIN, [$python])
|
||||
ax_python_bin=$PYTHON_BIN
|
||||
if test x$ax_python_bin != x; then
|
||||
AC_CHECK_LIB($ax_python_bin, main, ax_python_lib=$ax_python_bin, ax_python_lib=no)
|
||||
AC_CHECK_HEADER([$ax_python_bin/Python.h],
|
||||
[[ax_python_header=`locate $ax_python_bin/Python.h | sed -e s,/Python.h,,`]],
|
||||
ax_python_header=no)
|
||||
if test $ax_python_lib != no; then
|
||||
if test $ax_python_header != no; then
|
||||
break;
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
if test x$ax_python_bin = x; then
|
||||
ax_python_bin=no
|
||||
fi
|
||||
if test x$ax_python_header = x; then
|
||||
ax_python_header=no
|
||||
fi
|
||||
if test x$ax_python_lib = x; then
|
||||
ax_python_lib=no
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([ results of the Python check:])
|
||||
AC_MSG_RESULT([ Binary: $ax_python_bin])
|
||||
AC_MSG_RESULT([ Library: $ax_python_lib])
|
||||
AC_MSG_RESULT([ Include Dir: $ax_python_header])
|
||||
AC_MSG_RESULT([ Have python: $ac_use_python])
|
||||
|
||||
if test x$ax_python_header != xno; then
|
||||
PYTHON_INCLUDE_DIR=-I$ax_python_header
|
||||
AC_SUBST(PYTHON_INCLUDE_DIR)
|
||||
fi
|
||||
if test x$ax_python_lib != xno; then
|
||||
PYTHON_LIB=-l$ax_python_lib
|
||||
AC_SUBST(PYTHON_LIB)
|
||||
fi
|
||||
if test x$ax_python_header != xno; then
|
||||
dnl & x$ax_python_lib != xno; then
|
||||
ac_use_python=yes
|
||||
HAVE_PYTHON=-DHAVE_PYTHON
|
||||
fi
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL([USE_PYTHON], [test "$ac_use_python" = "yes"])
|
||||
])
|
||||
dnl
|
110
autogen.sh
110
autogen.sh
@ -1,110 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Automakeversion
|
||||
AM_1=1
|
||||
AM_2=7
|
||||
AM_3=2
|
||||
|
||||
# Autoconfversion
|
||||
AC_1=2
|
||||
AC_2=57
|
||||
|
||||
# Libtoolversion
|
||||
LT_1=1
|
||||
LT_2=4
|
||||
|
||||
# Libtoolname
|
||||
LIBTOOL=libtool
|
||||
LIBTOOLIZE=libtoolize
|
||||
if [ "`uname`" = "Darwin" ]; then
|
||||
LIBTOOL=glibtool
|
||||
LIBTOOLIZE=glibtoolize
|
||||
fi
|
||||
|
||||
# Check automake version
|
||||
AM_VERSION=`automake --version | sed -n -e 's#[^0-9]* \([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*$#\1 \2 \3#p'`
|
||||
AM_V1=`echo $AM_VERSION | awk '{print $1}'`
|
||||
AM_V2=`echo $AM_VERSION | awk '{print $2}'`
|
||||
AM_V3=`echo $AM_VERSION | awk '{print $3}'`
|
||||
|
||||
if [ $AM_1 -gt $AM_V1 ]; then
|
||||
AM_ERROR=1
|
||||
else
|
||||
if [ $AM_1 -eq $AM_V1 ]; then
|
||||
if [ $AM_2 -gt $AM_V2 ]; then
|
||||
AM_ERROR=1
|
||||
else
|
||||
if [ $AM_2 -eq $AM_V2 ]; then
|
||||
if [ $AM_3 -gt $AM_V3 ]; then
|
||||
AM_ERROR=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$AM_ERROR" = "1" ]; then
|
||||
echo -e '\E[31;m'
|
||||
echo -n "Your automake version `automake --version | sed -n -e 's#[^0-9]* \([0-9]*\.[0-9]*\.[0-9]*\).*#\1#p'`"
|
||||
echo " is older than the suggested one, $AM_1.$AM_2.$AM_3"
|
||||
echo "Go on at your own risk. :-)"
|
||||
echo
|
||||
tput sgr0
|
||||
fi
|
||||
|
||||
# Check autoconf version
|
||||
AC_VERSION=`autoconf --version | sed -n -e 's#[^0-9]* \([0-9]*\)\.\([0-9]*\).*$#\1 \2#p'`
|
||||
AC_V1=`echo $AC_VERSION | awk '{print $1}'`
|
||||
AC_V2=`echo $AC_VERSION | awk '{print $2}'`
|
||||
|
||||
if [ $AC_1 -gt $AC_V1 ]; then
|
||||
AC_ERROR=1
|
||||
else
|
||||
if [ $AC_1 -eq $AC_V1 ]; then
|
||||
if [ $AC_2 -gt $AC_V2 ]; then
|
||||
AC_ERROR=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$AC_ERROR" = "1" ]; then
|
||||
echo -e '\E[31;m'
|
||||
echo -n "Your autoconf version `autoconf --version | sed -n -e 's#[^0-9]* \([0-9]*\.[0-9]*\).*#\1#p'`"
|
||||
echo " is older than the suggested one, $AC_1.$AC_2"
|
||||
echo "Go on at your own risk. :-)"
|
||||
echo
|
||||
tput sgr0
|
||||
fi
|
||||
|
||||
# Check libtool version
|
||||
LT_VERSION=`$LIBTOOL --version | sed -n -e 's#[^0-9]* \([0-9]*\)\.\([0-9]*\).*$#\1 \2#p'`
|
||||
LT_V1=`echo $LT_VERSION | awk '{print $1}'`
|
||||
LT_V2=`echo $LT_VERSION | awk '{print $2}'`
|
||||
|
||||
if [ $LT_1 -gt $LT_V1 ]; then
|
||||
LT_ERROR=1
|
||||
else
|
||||
if [ $LT_1 -eq $LT_V1 ]; then
|
||||
if [ $LT_2 -gt $LT_V2 ]; then
|
||||
LT_ERROR=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$LT_ERROR" = "1" ]; then
|
||||
echo -e '\E[31;m'
|
||||
echo -n "Your libtool version `$LIBTOOL --version | sed -n -e 's#[^0-9]* \([0-9]*\.[0-9]*\).*#\1#p'`"
|
||||
echo " is older than the suggested one, $LT_1.$LT_2"
|
||||
echo "Go on at your own risk. :-)"
|
||||
echo
|
||||
tput sgr0
|
||||
fi
|
||||
|
||||
echo Configuring build environment for QGIS
|
||||
aclocal \
|
||||
&& $LIBTOOLIZE --force --copy \
|
||||
&& autoheader --force -W all \
|
||||
&& automake --add-missing --foreign --copy \
|
||||
&& autoconf --force \
|
||||
&& echo Now running configure to configure QGIS \
|
||||
&& ./configure $@
|
@ -1,3 +0,0 @@
|
||||
output.*
|
||||
requests
|
||||
traces.*
|
64
cmake/Bundle.cmake
Normal file
64
cmake/Bundle.cmake
Normal file
@ -0,0 +1,64 @@
|
||||
set(CPACK_GENERATOR)
|
||||
set(CPACK_OUTPUT_CONFIG_FILE "${CMAKE_BINARY_DIR}/BundleConfig.cmake")
|
||||
|
||||
add_custom_target(bundle
|
||||
COMMAND ${CMAKE_CPACK_COMMAND} "--config" "${CMAKE_BINARY_DIR}/BundleConfig.cmake" "--verbose"
|
||||
COMMENT "Running CPACK. Please wait..."
|
||||
DEPENDS qgis)
|
||||
|
||||
if(WIN32 AND NOT UNIX)
|
||||
set (CREATE_NSIS FALSE CACHE BOOL "Create an installer using NSIS")
|
||||
endif()
|
||||
set (CREATE_ZIP FALSE CACHE BOOL "Create a ZIP package")
|
||||
|
||||
# Do not warn about runtime libs when building using VS Express
|
||||
if(NOT DEFINED CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
|
||||
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS ON)
|
||||
endif()
|
||||
|
||||
if(QGIS_INSTALL_SYS_LIBS)
|
||||
include(InstallRequiredSystemLibraries)
|
||||
endif()
|
||||
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "QGIS")
|
||||
set(CPACK_PACKAGE_VENDOR "Open Source Geospatial Foundation")
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING")
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "QGIS ${COMPLETE_VERSION}")
|
||||
set(CPACK_PACKAGE_EXECUTABLES "qgis" "QGIS")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md")
|
||||
|
||||
if(CREATE_NSIS)
|
||||
# There is a bug in NSI that does not handle full unix paths properly. Make
|
||||
# sure there is at least one set of four (4) backslashes.
|
||||
set(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/win_build\\\\sidebar.bmp")
|
||||
set(CPACK_NSIS_INSTALLED_ICON_NAME "\\\\qgis.exe")
|
||||
set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} QGIS")
|
||||
set(CPACK_NSIS_HELP_LINK "http:\\\\\\\\qgis.org")
|
||||
set(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\qgis.org")
|
||||
set(CPACK_NSIS_CONTACT "info@qgis.org")
|
||||
set(CPACK_NSIS_MODIFY_PATH ON)
|
||||
endif()
|
||||
|
||||
if(CREATE_ZIP)
|
||||
list(APPEND CPACK_GENERATOR "ZIP")
|
||||
endif()
|
||||
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND QGIS_MAC_BUNDLE)
|
||||
set(CREATE_DMG FALSE CACHE BOOL "Create a dmg bundle")
|
||||
set(PYMACDEPLOYQT_EXECUTABLE "${CMAKE_SOURCE_DIR}/platform/macos/pymacdeployqt.py")
|
||||
|
||||
configure_file("${CMAKE_SOURCE_DIR}/platform/macos/Info.plist.in" "${CMAKE_BINARY_DIR}/platform//macos/Info.plist" @ONLY)
|
||||
install(FILES "${CMAKE_BINARY_DIR}/platform/macos/Info.plist" DESTINATION "${APP_CONTENTS_DIR}")
|
||||
|
||||
set(CPACK_DMG_VOLUME_NAME "${PROJECT_NAME}")
|
||||
set(CPACK_DMG_FORMAT "UDBZ")
|
||||
list(APPEND CPACK_GENERATOR "External")
|
||||
message(STATUS " + macdeployqt/DMG YES ")
|
||||
configure_file(${CMAKE_SOURCE_DIR}/platform/macos/CPackMacDeployQt.cmake.in "${CMAKE_BINARY_DIR}/CPackExternal.cmake" @ONLY)
|
||||
set(CPACK_EXTERNAL_PACKAGE_SCRIPT "${CMAKE_BINARY_DIR}/CPackExternal.cmake")
|
||||
set(CPACK_EXTERNAL_ENABLE_STAGING ON)
|
||||
set(CPACK_PACKAGING_INSTALL_PREFIX "/${QGIS_APP_NAME}.app")
|
||||
endif()
|
||||
|
||||
include(CPack)
|
42
cmake/CMakeDebugMacros.cmake
Normal file
42
cmake/CMakeDebugMacros.cmake
Normal file
@ -0,0 +1,42 @@
|
||||
# Macros/functions for debugging CMake
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
#
|
||||
# Copyright (c) 2016, Larry Shaffer, <lshaffer (at) boundlessgeo (dot) com>>
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
|
||||
# Dump current CMake variables to file
|
||||
#
|
||||
# Usage:
|
||||
# INCLUDE(CMakeDebugMacros)
|
||||
# DUMP_CMAKE_VARS() or DUMP_CMAKE_VARS("regex")
|
||||
#
|
||||
# regex: optional ARGV0 regular expression for filtering output variable names
|
||||
#
|
||||
# Outputs the result relative to the current CMake file being processed and
|
||||
# writes to a file with name "<file-basename>_cmake-vars.txt" to the current
|
||||
# build (binary) directory
|
||||
#
|
||||
function(DUMP_CMAKE_VARS)
|
||||
|
||||
get_filename_component(_basename ${CMAKE_CURRENT_LIST_FILE} NAME_WE)
|
||||
set(_out "${CMAKE_CURRENT_BINARY_DIR}/${_basename}_cmake-vars.txt")
|
||||
|
||||
set(_cmake_vars "")
|
||||
get_cmake_property(_varNames VARIABLES)
|
||||
foreach(_varName ${_varNames})
|
||||
if(ARGV0)
|
||||
string(REGEX MATCH "${ARGV0}" _match "${_varName}")
|
||||
if(_match)
|
||||
set(_cmake_vars "${_cmake_vars}\n\n${_varName}=${${_varName}}")
|
||||
endif()
|
||||
else()
|
||||
set(_cmake_vars "${_cmake_vars}\n\n${_varName}=${${_varName}}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
message(STATUS "Dumping current CMake variables to ...\n ${_out}")
|
||||
file(WRITE "${_out}" "${_cmake_vars}")
|
||||
|
||||
endfunction(DUMP_CMAKE_VARS)
|
22
cmake/COPYING-CMAKE-SCRIPTS
Normal file
22
cmake/COPYING-CMAKE-SCRIPTS
Normal file
@ -0,0 +1,22 @@
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
4
cmake/CopyIfChanged.cmake
Normal file
4
cmake/CopyIfChanged.cmake
Normal file
@ -0,0 +1,4 @@
|
||||
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E compare_files ${SRC} ${DST} RESULT_VARIABLE result)
|
||||
IF(result)
|
||||
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E copy ${SRC} ${DST})
|
||||
ENDIF(result)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user