From 5c65b39d70b939528b8be14fb45cadc9a36e71b6 Mon Sep 17 00:00:00 2001
From: Nicolas Raidelet <nicolas.raidelet@irstea.fr>
Date: Fri, 24 Nov 2017 16:05:29 +0100
Subject: [PATCH] git subrepo clone
 git@gitlab-ssh.irstea.fr:pole-is/devtools-config.git devtools

subrepo:
  subdir:   "devtools"
  merged:   "0c931beb"
upstream:
  origin:   "git@gitlab-ssh.irstea.fr:pole-is/devtools-config.git"
  branch:   "master"
  commit:   "0c931beb"
git-subrepo:
  version:  "0.3.1"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "a7ee886"
---
 devtools/.editorconfig               |   1 +
 devtools/.gitrepo                    |  11 +++
 devtools/README.md                   |  48 ++++++++++
 devtools/editorconfig                |  22 +++++
 devtools/gitlab/gitlab-ci.bundle.yml |  40 ++++++++
 devtools/php/.php_cs.dist            |   1 +
 devtools/php/php_cs.dist             | 136 +++++++++++++++++++++++++++
 devtools/php/phpcs.xml.dist          |  21 +++++
 devtools/php/phpmd-ruleset.xml       |  31 ++++++
 9 files changed, 311 insertions(+)
 create mode 120000 devtools/.editorconfig
 create mode 100644 devtools/.gitrepo
 create mode 100644 devtools/README.md
 create mode 100644 devtools/editorconfig
 create mode 100644 devtools/gitlab/gitlab-ci.bundle.yml
 create mode 120000 devtools/php/.php_cs.dist
 create mode 100644 devtools/php/php_cs.dist
 create mode 100644 devtools/php/phpcs.xml.dist
 create mode 100644 devtools/php/phpmd-ruleset.xml

diff --git a/devtools/.editorconfig b/devtools/.editorconfig
new file mode 120000
index 00000000..6f27d609
--- /dev/null
+++ b/devtools/.editorconfig
@@ -0,0 +1 @@
+editorconfig
\ No newline at end of file
diff --git a/devtools/.gitrepo b/devtools/.gitrepo
new file mode 100644
index 00000000..280a3d4e
--- /dev/null
+++ b/devtools/.gitrepo
@@ -0,0 +1,11 @@
+; DO NOT EDIT (unless you know what you are doing)
+;
+; This subdirectory is a git "subrepo", and this file is maintained by the
+; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
+;
+[subrepo]
+	remote = git@gitlab-ssh.irstea.fr:pole-is/devtools-config.git
+	branch = master
+	commit = 0c931beb09149c83b9defadd3f96284e7c91ba44
+	parent = 06988e9db1b139f8a6baf91aa1007c717451455a
+	cmdver = 0.3.1
diff --git a/devtools/README.md b/devtools/README.md
new file mode 100644
index 00000000..431d33a4
--- /dev/null
+++ b/devtools/README.md
@@ -0,0 +1,48 @@
+Ce dépôt contient la configuration par défaut de quelques outils utiles pendant le développement.
+
+Installation
+============
+
+Cloner le dossier dans $HOME/.config/devtools.
+
+```bash
+git clone git@gitlab-ssh.irstea.fr:pole-is/devtools-config.git $HOME/.config/devtools
+```
+
+Utilisation
+
+Globale
+-------
+
+Créer des liens symboliques dans $HOME pour .editorconf et phpcs.xml.dist:
+
+```bash
+ln -snf $HOME/.config/devtools/php/phpcs.xml.dist $HOME/phpcs.xml.dist
+ln -snf $HOME/.config/devtools/.editorconfig $HOME/.editorconfig
+```
+
+Enfin, configurer PHPStorm pour utiliser les fichiers $HOME/.config/devtools/php/phpcs.xml.dist et $HOME/.config/devtools/php/phpmd-ruleset.xml pour phpcs et phpmd respectivement.
+
+Par projet
+----------
+
+php-cs-fixer nécessite de copier le fichier directement dans le projet :
+
+```bash
+cp $HOME/.config/devtools/php/.php_cs.dist chemin/vers/mon/projet
+```
+
+Pour phpcs et phpmd, c'est également nécessaire pour l'intégration continue.
+
+Outils
+======
+
+* [editorconfig](): permet de configurer globalement l'encodage, l'indentation et la gestion des espaces.
+
+* [phpcs](https://github.com/squizlabs/PHP_CodeSniffer): vérification du style de codage.
+
+* [php-cs-fixer](https://github.com/FriendsOfPhp/PHP-CS-Fixer): cousin de phpcs, mais qui permet de corriger les fichiers et inclut également des aide pour migrer d'une version de PHP à une autre. 
+
+* [phpmd](https://phpmd.org/): détection de bugs potentielles, de fonctions/classes trop complexes, ...
+
+
diff --git a/devtools/editorconfig b/devtools/editorconfig
new file mode 100644
index 00000000..e12e5a76
--- /dev/null
+++ b/devtools/editorconfig
@@ -0,0 +1,22 @@
+# editorconfig.org
+root=true
+
+[*]
+charset=utf-8
+end_of_line=lf
+indent_size=4
+indent_style=space
+insert_final_newline=true
+tab_width=4
+trim_trailing_whitespace=true
+
+[*.{js,yml,json,ts}]
+indent_size=2
+tab_width=2
+
+[Makefile]
+indent_style=tab
+
+[*.md]
+max_line_length = off
+trim_trailing_whitespace = false
diff --git a/devtools/gitlab/gitlab-ci.bundle.yml b/devtools/gitlab/gitlab-ci.bundle.yml
new file mode 100644
index 00000000..0c9a6684
--- /dev/null
+++ b/devtools/gitlab/gitlab-ci.bundle.yml
@@ -0,0 +1,40 @@
+
+.defaults: &defaults
+  tags: [ docker ]
+  image: isdevtools.irstea.fr/poleis/php-analysis:7.1
+
+phploc:
+  <<: *defaults
+  script: phploc src
+
+lint:
+  <<: *defaults
+  script:
+    - parallel-lint -j $(nproc) src
+    - twig-lint lint src
+    - yaml-lint src
+
+php-cs-fixer:
+  <<: *defaults
+  script: php-cs-fixer fix --dry-run --verbose
+
+phpcpd:
+  <<: *defaults
+  script: phpcpd --fuzzy src
+
+.with-vendors: &with-vendors
+  <<: *defaults
+  before_script:
+    - composer install --prefer-dist --no-progress --no-suggest
+  cache:
+    key: "$CI_COMMIT_REF_NAME"
+    paths:
+      - /composer/cache
+
+composer-require-checker:
+  <<: *with-vendors
+  script: composer-require-checker
+
+phpmd:
+  <<: *with-vendors
+  script: phpmd src text ./phpmd-ruleset.xml --suffixes=php
diff --git a/devtools/php/.php_cs.dist b/devtools/php/.php_cs.dist
new file mode 120000
index 00000000..13ed5428
--- /dev/null
+++ b/devtools/php/.php_cs.dist
@@ -0,0 +1 @@
+php_cs.dist
\ No newline at end of file
diff --git a/devtools/php/php_cs.dist b/devtools/php/php_cs.dist
new file mode 100644
index 00000000..745a58bf
--- /dev/null
+++ b/devtools/php/php_cs.dist
@@ -0,0 +1,136 @@
+<?php
+define('COMMIT_CACHE', '.php_cs.commit-cache');
+
+$finder = PhpCsFixer\Finder::create()
+    ->exclude('vendor')
+    ->exclude('node_modules')
+    ->exclude('cache')
+    ->files()
+    ->name('*.php')
+    ->in('.');
+
+$yearRange = getGitCommitYears();
+
+$ruleSets = ['@PSR2' => true, '@Symfony' => true];
+
+$rules = [
+    // Configuration && overrides
+    'binary_operator_spaces'                    => ['align_double_arrow' => true],
+    'blank_line_after_opening_tag'              => false,
+    'concat_space'                              => ['spacing' => 'one'],
+    'method_argument_space'                     => ['ensure_fully_multiline' => true],
+
+    // Risky
+    'is_null'                                   => ['use_yoda_style' => false],
+    'non_printable_character'                   => ['use_escape_sequences_in_strings' => true],
+
+    // Safe
+    'align_multiline_comment'                   => true,
+    'array_syntax'                              => ['syntax' => 'short'],
+    'general_phpdoc_annotation_remove'          => ['annotations' => ['author', 'package']],
+    'no_multiline_whitespace_before_semicolons' => true,
+    'no_useless_else'                           => true,
+    'no_useless_return'                         => true,
+    'ordered_imports'                           => true,
+    'phpdoc_add_missing_param_annotation'       => true,
+    'phpdoc_annotation_without_dot'             => true,
+    'phpdoc_order'                              => true,
+    'semicolon_after_instruction'               => true,
+    'yoda_style'                                => false,
+
+    'header_comment' => [
+        'commentType' => 'comment',
+        'location'    => 'after_declare_strict',
+        'separate'    => 'bottom',
+        'header'      => <<<HEADER
+Copyright (C) $yearRange IRSTEA
+All rights reserved.
+HEADER
+        ,
+    ],
+];
+
+$phpVersion = findComposerPhpReq();
+
+if ($phpVersion >= 5.6) {
+    $ruleSets['@PHP56Migration'] = true;
+}
+if ($phpVersion >= 7.0) {
+    $ruleSets['@PHP70Migration'] = true;
+    $rules['declare_strict_types'] = true;
+}
+if ($phpVersion >= 7.1) {
+    $ruleSets['@PHP71Migration'] = true;
+}
+
+echo "Rulesets: " . implode(', ', array_keys($ruleSets)) . ".\n";
+
+return PhpCsFixer\Config::create()
+  ->setRiskyAllowed(true)
+  ->setUsingCache(false)
+  ->setIndent('    ')
+  ->setLineEnding("\n")
+  ->setRules(array_merge($ruleSets, $rules))
+  ->setFinder($finder);
+
+/**
+ * @return string
+ */
+function getGitCommitYears(): string
+{
+    return getCachedValue('years', function () {
+        echo "Examining git history...\n";
+        $last = date('Y');
+        $first = exec('git log --format=%cd --date=format:%Y --date-order | tail -n1') ?? $last;
+        return (null !== $last && $last !== $first) ? "$first-$last" : $first;
+    });
+}
+
+/**
+ * @return float
+ */
+function findComposerPhpReq()
+{
+    return getCachedValue('php-req', function () {
+        if (file_exists('composer.json')) {
+            $data = json_decode(file_get_contents('composer.json'), true);
+            if (is_array($data) && isset($data['require']['php'])) {
+                if (preg_match('/(?:>=?|\^|~)\s*([57]\.[0-9])/', $data['require']['php'], $groups)) {
+                    return (float) $groups[1];
+                }
+            }
+        }
+
+        return 5.6;
+    });
+}
+
+/**
+ * @param string   $key
+ * @param callable $produce
+ *
+ * @return string|int|bool|array
+ */
+function getCachedValue($key, $produce)
+{
+    static $commit = null;
+    if (null === $commit) {
+        $commit = trim(`git rev-parse HEAD`);
+    }
+    if (file_exists(COMMIT_CACHE) && filemtime(COMMIT_CACHE) >= filemtime(__FILE__)) {
+        $cache = json_decode(file_get_contents(COMMIT_CACHE), true);
+    } else {
+        $cache = [];
+    }
+    if (!isset($cache[$commit][$key])) {
+        if (!isset($cache[$commit])) {
+            $cache[$commit] = [];
+        }
+        $cache[$commit][$key] = $produce();
+        file_put_contents(COMMIT_CACHE, json_encode($cache));
+    }
+
+    return $cache[$commit][$key];
+}
+
+// vim:filetype=php
diff --git a/devtools/php/phpcs.xml.dist b/devtools/php/phpcs.xml.dist
new file mode 100644
index 00000000..f6de6b66
--- /dev/null
+++ b/devtools/php/phpcs.xml.dist
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<ruleset name="Irstea" namespace="Irstea\Standard">
+
+    <description>Coding standard of Irstea, pôle informatique scientifique</description>
+
+    <file>src</file>
+
+    <arg name="encoding" value="utf-8"/>
+    <arg name="extensions" value="php"/>
+    <arg name="ignore" value="vendor/*,*/cache/*"/>
+    <arg value="sp"/>
+
+    <rule ref="PSR2"/>
+
+    <rule ref="Generic.Files.LineLength">
+        <properties>
+            <property name="lineLimit" value="140"/>
+        </properties>
+    </rule>
+
+</ruleset>
diff --git a/devtools/php/phpmd-ruleset.xml b/devtools/php/phpmd-ruleset.xml
new file mode 100644
index 00000000..7e284556
--- /dev/null
+++ b/devtools/php/phpmd-ruleset.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<ruleset name="Irstea PHPMD ruleset"
+         xmlns="http://pmd.sf.net/ruleset/1.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd">
+
+    <description>Irstea ruleset</description>
+
+    <rule ref="rulesets/controversial.xml/Superglobals" />
+    <rule ref="rulesets/controversial.xml/CamelCaseClassName"/>
+    <rule ref="rulesets/controversial.xml/CamelCasePropertyName"/>
+
+    <rule ref="rulesets/design.xml/ExitExpression" />
+    <rule ref="rulesets/design.xml/EvalExpression" />
+    <rule ref="rulesets/design.xml/GotoStatement" />
+    <rule ref="rulesets/design.xml/DevelopmentCodeFragment">
+        <property name="unwanted-functions" value="var_dump,print_r,debug_zval_dump,debug_print_backtrace,dump" />
+    </rule>
+
+    <rule ref="rulesets/naming.xml/ShortMethodName" />
+    <rule ref="rulesets/naming.xml/ConstructorWithNameAsEnclosingClass" />
+    <rule ref="rulesets/naming.xml/ConstantNamingConventions" />
+
+    <rule ref="rulesets/unusedcode.xml/UnusedPrivateMethod" />
+    <rule ref="rulesets/unusedcode.xml/UnusedPrivateField" />
+
+    <exclude-pattern>vendor/</exclude-pattern>
+    <exclude-pattern>node_modules/</exclude-pattern>
+    <exclude-pattern>.*/cache/</exclude-pattern>
+
+</ruleset>
-- 
GitLab