{"thread":{"id":"30658","subject":"[PATCH/RFC]Test environment for Git-MediaWiki","startedAt":"2012-05-30T16:30:04Z","lastAt":"2012-06-04T14:13:00Z","messageCount":21,"participants":["Simon.Cathebras","Simon Cathebras","Matthieu Moy","Guillaume Sasdy"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"192493","messageId":"4FC64B0C.6070507@ensimag.imag.fr","threadId":"30658","inReplyTo":null,"subject":"[PATCH/RFC]Test environment for Git-MediaWiki","fromName":"Simon.Cathebras","fromEmail":"simon.cathebras@ensimag.imag.fr","sentAt":"2012-05-30T16:30:04Z","receivedAt":"2012-05-30T16:30:04Z","isPatch":true,"sender":{"key":"simon.cathebras@ensimag.imag.fr","avatar":"https://avatars.githubusercontent.com/u/1764010?v=4"},"body":"Hello all,\n\nWe are developing the test environment for the Git-MediaWiki project.\nFor now, we have focused mainly on the environment with some simple test \ncases.\n\nIn this version, we have developed a script to install and delete a \nMediaWiki wiki easily.\nThe environment provides shell functions to manage a wiki (fetch, \ndelete, edit a page, compare the content of a page) and a git-mediawiki \n() repository.\nThere are two simple test cases for git clone.\n\nYou can find all the code in our Github: \nhttps://github.com/Fafinou/git/wiki and how to install and run the tests.\n\nWe would like you to give us a lot of comments about our code :)\n\nNote\n* In this version we have a binary file \"wikidb.sqlite\" which contains \nan empty SQLite3 database. We know this is not a good thing to put a \nbinary file in a repository so we will change this bad behavior later \n(we will generate the \"wikidb.sqlite\" file with a http request to the \nconfig page of MediaWiki)\n* We will add simple test cases for pull and push the soonest\n\nThanks you in advance for your time ;)\n\n-- \nCATHEBRAS Simon\n\n2A-ENSIMAG\n\nFilière Ingéniérie des Systèmes d'Information\nMembre Bug-Buster\n"},{"id":"192496","messageId":"1338397492-13360-1-git-send-email-simon.cathebras@ensimag.imag.fr","threadId":"30658","inReplyTo":"4FC64B0C.6070507@ensimag.imag.fr","subject":"[PATCH 1/3] Script to install, delete and clear a MediaWiki","fromName":"Simon Cathebras","fromEmail":"simon.cathebras@ensimag.imag.fr","sentAt":"2012-05-30T17:04:50Z","receivedAt":"2012-05-30T17:04:50Z","isPatch":true,"sender":{"key":"simon.cathebras@ensimag.imag.fr","avatar":"https://avatars.githubusercontent.com/u/1764010?v=4"},"body":"From: Charles Roussel <charles.roussel@ensimag.fr>\n\ninstall_wiki.sh expects the first argument to be 'install' or 'delete'\n'install' installs a MediaWiki on the web's server with SQLite3\n'delete' deletes the previously created wiki. Note those\nfunctionnalities are made to be used from the user command line in the\ndirectory /t\n\ninstall_wiki also defines a function cmd_reset which clear all content\nof the previously created wiki. Note this functionnality is made to be\nused only by our test function in a subdirectory of t/\n\nSigned-off-by: Simon Cathebras <simon.cathebras@ensimag.imag.fr>\nSigned-off-by: Charles Roussel <charles.roussel@ensimag.imag.fr>\nSigned-off-by: Julien Khayat <julien.khayat@ensimag.imag.fr>\nSigned-off-by: Simon Perrat <simon.perrat@ensimag.imag.fr>\nSigned-off-by: Guillaume Sasdy <guillaume.sasdy@gmail.com>\n---\n t/install-wiki.sh                |  38 ++++++++++\n t/install-wiki/LocalSettings.php | 129 ++++++++++++++++++++++++++++++++++\n t/install-wiki/wikidb.sqlite     | Bin 0 -> 210944 bytes\n t/test-gitmw-lib.sh              | 147 +++++++++++++++++++++++++++++++++++++++\n 4 files changed, 314 insertions(+)\n create mode 100755 t/install-wiki.sh\n create mode 100644 t/install-wiki/LocalSettings.php\n create mode 100644 t/install-wiki/wikidb.sqlite\n create mode 100755 t/test-gitmw-lib.sh\n mode change 100644 => 100755 t/test-lib-functions.sh\n mode change 100644 => 100755 t/test-lib.sh\n\ndiff --git a/t/install-wiki.sh b/t/install-wiki.sh\nnew file mode 100755\nindex 0000000..725346e\n--- /dev/null\n+++ b/t/install-wiki.sh\n@@ -0,0 +1,38 @@\n+#!/bin/sh\n+\n+# This script installs or deletes a MediaWiki on your computer.\n+# It requires a web server with PHP and SQLite running. In addition, if you \n+# do not have MediaWiki sources on your computer, the option 'install' \n+# downloads them for you.\n+# Please set the CONFIGURATION VARIABLES in ./test-gitmw-lib.sh\n+\n+. ./test-gitmw-lib.sh\n+\n+usage () {\n+        echo \"Usage: \"\n+        echo \"  ./install-wiki.sh <install|delete|--help|-h>\"\n+        echo \"          install: Install a wiki on your computer.\"\n+        echo \"          delete: Delete the wiki and all its pages and      content\"\n+}\n+\n+\n+# Argument: install, delete, --help | -h\n+case \"$1\" in\n+\t\"install\")\n+\t\tcmd_install\n+\t\texit 0\n+\t\t;;\n+\t\"delete\")\n+\t\tcmd_delete\n+\t\texit 0\n+\t\t;;\n+\t\"--help\" | \"-h\")\n+\t\tusage\n+\t\texit 0\n+\t\t;;\n+\t*)\n+\t\tusage\n+\t\texit 0\n+\t\t;;\n+esac\n+\ndiff --git a/t/install-wiki/LocalSettings.php b/t/install-wiki/LocalSettings.php\nnew file mode 100644\nindex 0000000..c2fe3d5\n--- /dev/null\n+++ b/t/install-wiki/LocalSettings.php\n@@ -0,0 +1,129 @@\n+<?php\n+# This file was automatically generated by the MediaWiki 1.19.0\n+# installer. If you make manual changes, please keep track in case you\n+# need to recreate them later.\n+#\n+# See includes/DefaultSettings.php for all configurable settings\n+# and their default values, but don't forget to make changes in _this_\n+# file, not there.\n+#\n+# Further documentation for configuration settings may be found at:\n+# http://www.mediawiki.org/wiki/Manual:Configuration_settings\n+\n+# Protect against web entry\n+if ( !defined( 'MEDIAWIKI' ) ) {\n+\texit;\n+}\n+\n+## Uncomment this to disable output compression\n+# $wgDisableOutputCompression = true;\n+\n+$wgSitename      = \"Git-MediaWiki-Test\";\n+$wgMetaNamespace = \"Git-MediaWiki-Test\";\n+\n+## The URL base path to the directory containing the wiki;\n+## defaults for all runtime URL paths are based off of this.\n+## For more information on customizing the URLs please see:\n+## http://www.mediawiki.org/wiki/Manual:Short_URL\n+$wgScriptPath       = \"@WG_SCRIPT_PATH@\";\n+$wgScriptExtension  = \".php\";\n+\n+## The protocol and server name to use in fully-qualified URLs\n+$wgServer           = \"@WG_SERVER@\";\n+\n+## The relative URL path to the skins directory\n+$wgStylePath        = \"$wgScriptPath/skins\";\n+\n+## The relative URL path to the logo.  Make sure you change this from the default,\n+## or else you'll overwrite your logo when you upgrade!\n+$wgLogo             = \"$wgStylePath/common/images/wiki.png\";\n+\n+## UPO means: this is also a user preference option\n+\n+$wgEnableEmail      = true;\n+$wgEnableUserEmail  = true; # UPO\n+\n+$wgEmergencyContact = \"apache@localhost\";\n+$wgPasswordSender   = \"apache@localhost\";\n+\n+$wgEnotifUserTalk      = false; # UPO\n+$wgEnotifWatchlist     = false; # UPO\n+$wgEmailAuthentication = true;\n+\n+## Database settings\n+$wgDBtype           = \"sqlite\";\n+$wgDBserver         = \"\";\n+$wgDBname           = \"wikidb\";\n+$wgDBuser           = \"\";\n+$wgDBpassword       = \"\";\n+\n+# SQLite-specific settings\n+$wgSQLiteDataDir    = \"@WG_SQLITE_DATADIR@\";\n+\n+\n+## Shared memory settings\n+$wgMainCacheType    = CACHE_NONE;\n+$wgMemCachedServers = array();\n+\n+## To enable image uploads, make sure the 'images' directory\n+## is writable, then set this to true:\n+$wgEnableUploads  = false;\n+$wgUseImageMagick = true;\n+$wgImageMagickConvertCommand =\"@CONVERT@\";\n+\n+# InstantCommons allows wiki to use images from http://commons.wikimedia.org\n+$wgUseInstantCommons  = false;\n+\n+## If you use ImageMagick (or any other shell command) on a\n+## Linux server, this will need to be set to the name of an\n+## available UTF-8 locale\n+$wgShellLocale = \"en_US.utf8\";\n+\n+## If you want to use image uploads under safe mode,\n+## create the directories images/archive, images/thumb and\n+## images/temp, and make them all writable. Then uncomment\n+## this, if it's not already uncommented:\n+#$wgHashedUploadDirectory = false;\n+\n+## Set $wgCacheDirectory to a writable directory on the web server\n+## to make your wiki go slightly faster. The directory should not\n+## be publically accessible from the web.\n+#$wgCacheDirectory = \"$IP/cache\";\n+\n+# Site language code, should be one of the list in ./languages/Names.php\n+$wgLanguageCode = \"en\";\n+\n+$wgSecretKey = \"1c912bfe3519fb70f5dc523ecc698111cd43d81a11c585b3eefb28f29c2699b7\";\n+#$wgSecretKey = \"@SECRETKEY@\";\n+\n+\n+# Site upgrade key. Must be set to a string (default provided) to turn on the\n+# web installer while LocalSettings.php is in place\n+$wgUpgradeKey = \"ddae7dc87cd0a645\";\n+\n+## Default skin: you can change the default skin. Use the internal symbolic\n+## names, ie 'standard', 'nostalgia', 'cologneblue', 'monobook', 'vector':\n+$wgDefaultSkin = \"vector\";\n+\n+## For attaching licensing metadata to pages, and displaying an\n+## appropriate copyright notice / icon. GNU Free Documentation\n+## License and Creative Commons licenses are supported so far.\n+$wgRightsPage = \"\"; # Set to the title of a wiki page that describes your license/copyright\n+$wgRightsUrl  = \"\";\n+$wgRightsText = \"\";\n+$wgRightsIcon = \"\";\n+\n+# Path to the GNU diff3 utility. Used for conflict resolution.\n+$wgDiff3 = \"/usr/bin/diff3\";\n+\n+# Query string length limit for ResourceLoader. You should only set this if\n+# your web server has a query string length limit (then set it to that limit),\n+# or if you have suhosin.get.max_value_length set in php.ini (then set it to\n+# that value)\n+$wgResourceLoaderMaxQueryLength = -1;\n+\n+\n+\n+# End of automatically generated settings.\n+# Add more configuration options below.\n+\ndiff --git a/t/install-wiki/wikidb.sqlite b/t/install-wiki/wikidb.sqlite\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..809047334bf15891de943b480171beb2558f7cb8\nGIT binary patch\nliteral 210944\n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\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/test-gitmw-lib.sh b/t/test-gitmw-lib.sh\nnew file mode 100755\nindex 0000000..2deead7\n--- /dev/null\n+++ b/t/test-gitmw-lib.sh\n@@ -0,0 +1,147 @@\n+#\n+# CONFIGURATION VARIABLES\n+# You might want to change those ones ...\n+#\n+WIKI_DIR_NAME=\"wiki\"            # Name of the wiki's directory\n+WIKI_DIR_INST=\"/var/www\"        # Directory of the web server\n+TMP=\"/tmp\"                      # Temporary directory for downloads\n+                                # Absolute address needed!\n+SERVER_ADDR=\"localhost\"         # Web server's address\n+\n+#\n+# CONFIGURATION\n+# You should not change those ones unless you know what you to\n+#\n+# Do not change the variables below\n+MW_VERSION=\"mediawiki-1.19.0\"\n+DB_FILE=\"wikidb.sqlite\"\n+FILES_FOLDER=\"install-wiki\"\n+WIKI_ADMIN=\"WikiAdmin\"\n+WIKI_PASSW=\"AdminPass\"\n+\n+fail () {\n+\techo \"$1\"\n+\texit 1\n+}\n+\n+\n+\n+# Install a wiki in your web server directory.\n+cmd_install () {\n+\n+\t# Copy the generic LocalSettings.php in the web server's directory\n+\t# And modify parameters according to the ones set at the top\n+\t# of this script.\n+\t# Note that LocalSettings.php is never modified.\n+\tif [ ! -f \"$FILES_FOLDER/LocalSettings.php\" ] ; then\n+\t\tfail \"Can't find $FILES_FOLDER/LocalSettings.php \" \\\n+\t\t\t\"in the current folder.\n+\t\tPlease run the script inside its folder.\"\n+\tfi\n+\tcp \"$FILES_FOLDER/LocalSettings.php\" \\\n+\t\t\"$FILES_FOLDER/LocalSettings-tmp.php\" ||\n+\t\tfail \"Unable to copy $FILES_FOLDER/LocalSettings.php \" \\\n+\t\t\"to $FILES_FOLDER/LocalSettings-tmp.php\"\n+\n+\t# Parse and set the LocalSettings file of the user according to the\n+\t# CONFIGURATION VARIABLES section at the beginning of this script\n+\tfile_swap=\"$FILES_FOLDER/LocalSettings-swap.php\"\n+\tsed \"s,@WG_SCRIPT_PATH@,/$WIKI_DIR_NAME,\" \\\n+\t\t\"$FILES_FOLDER/LocalSettings-tmp.php\" > \"$file_swap\"\n+\tmv \"$file_swap\" \"$FILES_FOLDER/LocalSettings-tmp.php\"\n+\tsed \"s,@WG_SERVER@,http://$SERVER_ADDR,\" \\\n+\t\t\"$FILES_FOLDER/LocalSettings-tmp.php\" > \"$file_swap\"\n+\tmv \"$file_swap\" \"$FILES_FOLDER/LocalSettings-tmp.php\"\n+\tsed \"s,@WG_SQLITE_DATADIR@,$TMP,\" \\\n+\t\t\"$FILES_FOLDER/LocalSettings-tmp.php\" > \"$file_swap\"\n+\tmv \"$file_swap\" \"$FILES_FOLDER/LocalSettings-tmp.php\"\n+\n+\tmkdir -p \"$WIKI_DIR_INST/$WIKI_DIR_NAME\"\n+\tif [ ! -d \"$WIKI_DIR_INST/$WIKI_DIR_NAME\" ] ; then\n+\t\tfail \"Folder $WIKI_DIR_INST/$WIKI_DIR_NAME doesn't exist. Please create it\n+\t\tand launch the script again.\"\n+\tfi\n+\n+\tmv \"$FILES_FOLDER/LocalSettings-tmp.php\" \\\n+\t\t\"$WIKI_DIR_INST/$WIKI_DIR_NAME/LocalSettings.php\" ||\n+\t\tfail \"Unable to move $FILES_FOLDER/LocalSettings-tmp.php\" \\\n+\t\t\"in $WIKI_DIR_INST/$WIKI_DIR_NAME\"\n+\techo \"File $FILES_FOLDER/LocalSettings.php is set in $WIKI_DIR_INST/$WIKI_DIR_NAME\"\n+\n+\tchmod ugo+w \"$FILES_FOLDER/$DB_FILE\"\n+\treset_db_wiki \".\"\n+\n+\t# Fetch MediaWiki's archive if not already present in the TMP directory\n+\tcd \"$TMP\"\n+\tif [ ! -f \"$MW_VERSION.tar.gz\" ] ; then\n+\t\techo \"Downloading $MW_VERSION sources ...\"\n+\t\twget http://download.wikimedia.org/mediawiki/1.19/mediawiki-1.19.0.tar.gz ||\n+\t\t\tfail \"Unable to download\" \\\n+\t\t\t\"http://download.wikimedia.org/mediawiki/1.19/mediawiki-1.19.0.tar.gz.\n+\t\tPlease fix your connection and launch the script again.\"\n+\tfi\n+\ttar xfz \"$MW_VERSION.tar.gz\"\n+\techo \"$MW_VERSION.tar.gz downloaded in `pwd`. You can delete it later if you want.\"\n+\n+\t# Copy the files of MediaWiki wiki in the web server's directory.\n+\tcd \"$MW_VERSION\"\n+\tcp -Rf * \"$WIKI_DIR_INST/$WIKI_DIR_NAME/\" ||\n+\t\tfail \"Unable to copy WikiMedia's files from `pwd` to $WIKI_DIR_INST/$WIKI_DIR_NAME\"\n+\n+\tset_admin_wiki\n+\n+\techo \"Your wiki has been installed. You can check it at http://$SERVER_ADDR/$WIKI_DIR_NAME\"\n+}\n+\n+# Copy the initial database of the wiki over the actual one.\n+# Argument $1 is the relative path to the folder $FILES_FOLDER\n+#\n+# Warning: This function should be not called by user. This is a private\n+# function used by cmd_install and cmd_delete\n+reset_db_wiki () {\n+\n+\t# Copy initial database of the wiki\n+\tif [ ! -f \"$1/$FILES_FOLDER/$DB_FILE\" ] ; then\n+\t\tfail \"Can't find $1/$FILES_FOLDER/$DB_FILE in the current folder.\"\n+\tfi\n+\tcp --preserve=mode,ownership \"$1/$FILES_FOLDER/$DB_FILE\" \"$TMP\" ||\n+\t\tfail \"Can't copy $1/$FILES_FOLDER/$DB_FILE in $TMP\"\n+\techo \"File $FILES_FOLDER/$DB_FILE is set in $TMP\"\n+}\n+\n+# Set the admin WikiAdmin with password AdminPass in the database.\n+#\n+# Warning: This function should be not called by user. This is a private\n+# function used by cmd_install and cmd_delete\n+set_admin_wiki () {\n+\n+\t#Add the admin\n+\tmy_pwd=\"`pwd`\"\n+\tcd \"$WIKI_DIR_INST/$WIKI_DIR_NAME/maintenance/\"\n+\tphp changePassword.php --user=\"$WIKI_ADMIN\" --password=\"$WIKI_PASSW\" ||\n+\t\tfail \"Unable to add an admin with the script $WIKI_DIR_INST/$WIKI_DIR_NAME/maintenance/\n+\tchangePassword.php. Check you have the perms to do it.\"\n+\techo \"Admin \\\"$WIKI_ADMIN\\\" has password \\\"$WIKI_PASSW\\\"\"\n+\tcd \"$my_pwd\"\n+}\n+\n+# Reset the database of the wiki and the password of the admin\n+#\n+# Warning: This function must be called only in a subdirectory of t/ directory\n+cmd_reset () {\n+\treset_db_wiki \"..\"\n+\tset_admin_wiki\n+}\n+\n+# Delete the wiki created in the web server's directory and all its content\n+# saved in the database.\n+cmd_delete () {\n+\t# Delete the wiki's directory.\n+\trm -rf \"$WIKI_DIR_INST/$WIKI_DIR_NAME\" ||\n+\t\tfail \"Wiki's directory $WIKI_DIR_INST/\" \\\n+\t\t\"$WIKI_DIR_NAME could not be deleted\"\n+\n+\t# Delete the wiki's SQLite database\n+\trm -f \"$TMP/$DB_FILE\" || fail \"Database $TMP/$DB_FILE could not be deleted.\"\n+}\n+\ndiff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh\nold mode 100644\nnew mode 100755\ndiff --git a/t/test-lib.sh b/t/test-lib.sh\nold mode 100644\nnew mode 100755\n-- \n1.7.10.2.552.gaa3bb87\n"},{"id":"192494","messageId":"1338397492-13360-2-git-send-email-simon.cathebras@ensimag.imag.fr","threadId":"30658","inReplyTo":"1338397492-13360-1-git-send-email-simon.cathebras@ensimag.imag.fr","subject":"[PATCH 2/3] Test environment of git-remote-mw","fromName":"Simon Cathebras","fromEmail":"simon.cathebras@ensimag.imag.fr","sentAt":"2012-05-30T17:04:51Z","receivedAt":"2012-05-30T17:04:51Z","isPatch":true,"sender":{"key":"simon.cathebras@ensimag.imag.fr","avatar":"https://avatars.githubusercontent.com/u/1764010?v=4"},"body":"From: Charles Roussel <charles.roussel@ensimag.fr>\n\nIn order to test git-remote-mediawiki, we need a package of functions\nto manage a MediaWiki: edit a page, remove a page, fetch a page,\nfetch all pages on a given wiki.\n\nWe also need functions to compare the content of directories.\n\nSigned-off-by: Simon Cathebras <simon.cathebras@ensimag.imag.fr>\nSigned-off-by: Charles Roussel <charles.roussel@ensimag.imag.fr>\nSigned-off-by: Julien Khayat <julien.khayat@ensimag.imag.fr>\nSigned-off-by: Simon Perrat <simon.perrat@ensimag.imag.fr>\nSigned-off-by: Guillaume Sasdy <guillaume.sasdy@gmail.com>\n---\n t/test-gitmw-lib.sh | 125 ++++++++++++++++++++++++++++++++++++---\n t/test-gitmw.pl     | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 281 insertions(+), 8 deletions(-)\n create mode 100755 t/test-gitmw.pl\n\ndiff --git a/t/test-gitmw-lib.sh b/t/test-gitmw-lib.sh\nindex 2deead7..8698625 100755\n--- a/t/test-gitmw-lib.sh\n+++ b/t/test-gitmw-lib.sh\n@@ -1,27 +1,136 @@\n+# Copyright (C) 2012\n+#     Charles Roussel <charles.roussel@ensimag.imag.fr>\n+#     Simon Cathebras <simon.cathebras@ensimag.imag.fr>\n+#     Julien Khayat <julien.khayat@ensimag.imag.fr>\n+#     Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>\n+#     Simon Perrat <simon.perrat@ensimag.imag.fr>\n+#     Matthieu Moy <matthieu.moy@imag.fr>\n+# License: GPL v2 or later\n+\n #\n # CONFIGURATION VARIABLES\n-# You might want to change those ones ...\n+# You might want to change these ones\n #\n WIKI_DIR_NAME=\"wiki\"            # Name of the wiki's directory\n WIKI_DIR_INST=\"/var/www\"        # Directory of the web server\n TMP=\"/tmp\"                      # Temporary directory for downloads\n-                                # Absolute address needed!\n+                                # Absolute path required!\n SERVER_ADDR=\"localhost\"         # Web server's address\n \n-#\n # CONFIGURATION\n-# You should not change those ones unless you know what you to\n+# You should not change these ones unless you know what you do\n #\n-# Do not change the variables below\n MW_VERSION=\"mediawiki-1.19.0\"\n DB_FILE=\"wikidb.sqlite\"\n FILES_FOLDER=\"install-wiki\"\n WIKI_ADMIN=\"WikiAdmin\"\n WIKI_PASSW=\"AdminPass\"\n \n-fail () {\n-\techo \"$1\"\n-\texit 1\n+# wiki_getpage <page_name> <dest_path>\n+#\n+# Fetch a page <page_name> from the wiki and copy its content\n+# into directory <dest_path>.\n+wiki_getpage () {\n+\t../test-gitmw.pl \"get_page\" -p \"$1\" \"$2\"\n+}\n+\n+# wiki_delete_page <page_name>\n+#\n+# Delete the page <page_name> on the wiki.\n+wiki_delete_page () {\n+\t../test-gitmw.pl \"delete_page\" -p \"$1\"\n+}\n+\n+# wiki_edit_page <page_name> <page_content> <page_append>\n+#\n+# Edit a page <wiki_page> on the wiki with content <wiki_content>\n+# If <wiki_append> == true the content will be appended\n+# If the page doesn't exist, it is created.\n+wiki_editpage () {\n+\t../test-gitmw.pl \"edit_page\" -p \"$1\" \"$2\" \"$3\"\n+}\n+\n+# git_content <dir_1> <dir_2>\n+#\n+# Compare the contents of directories <dir_1> and <dir_2> with diff\n+# and exits with error 1 if they do not match. The program will\n+# not look into .git in the process.\n+git_content () {\n+\tresult=$(diff -r -B -w --exclude=\".git\" \"$1\" \"$2\")\n+\n+\tif echo $result | grep -q \">\" ; then\n+\t\techo \"test failed: files $1 and $2 do not match\"\n+\t\texit 1\n+\tfi\n+}\n+\n+# git_exist <rep_name> <file_name>\n+#\n+# Check the existence of <file_name> into the git repository\n+# <rep_name> and exits with error 1 if it is absent.\n+git_exist () {\n+\tresult=$(find \"$1\" -type f -name \"$2\")\n+\n+\tif ! echo $result | grep -q \"$2\" ; then\n+\t\techo \"test failed: file $2 does not exist in $1\"\n+\t\texit 1\n+\tfi\n+}\n+\n+# wiki_page_content <file_name> <page_name> \n+#\n+# Compares the contents of the file <file_name> and the wiki page\n+# <page_name> and exits with error 1 if they do not match.\n+wiki_page_content () {\n+\twiki_getpage \"$2\" .\n+\n+\tif test -f \"$2\".mw ; then\n+\t        git_content \"$1\" \"$2\".mw\n+\t\trm \"$2\".mw\n+\telse\n+\t\tdie \"ERROR: file $2 not found on wiki\"\n+\tfi\n+}\n+\n+# wiki_page_exist <page_name>\n+#\n+# Check the existence of the page <page_name> on the wiki and exits\n+# with error if it is absent from it.\n+wiki_page_exist () {\n+\twiki_getpage \"$1\" .\n+\n+\tif test -f \"$1\".mw ; then\n+\t\techo \"test failed: file $1 not found on wiki\"\n+\t\texit 1\n+\telse \n+\t\trm \"$1\".mw\n+\tfi\n+}\n+\n+# wiki_getallpagename\n+# \n+# Fetch the name of each page on the wiki.\n+wiki_getallpagename () {\n+\t../test-gitmw.pl \"getallpagename\" -p\n+}\n+\n+# wiki_getallpage <dest_dir>\n+#\n+# Fetch all the pages from the wiki and place them in the directory\n+# <dest_dir>.\n+wiki_getallpage () {\n+\twiki_getallpagename\n+\tmkdir $1\n+\twhile read -r line; do\n+\t\twiki_getpage \"$line\" $1;\n+\tdone < all.txt\n+\t#rm all.txt\n+}\n+\n+fail()\n+{\n+    echo $1\n+    exit 1\n }\n \n \ndiff --git a/t/test-gitmw.pl b/t/test-gitmw.pl\nnew file mode 100755\nindex 0000000..e9c50f9\n--- /dev/null\n+++ b/t/test-gitmw.pl\n@@ -0,0 +1,164 @@\n+#!/usr/bin/perl -w\n+# Copyright (C) 2012\n+#     Charles Roussel <charles.roussel@ensimag.imag.fr>\n+#     Simon Cathebras <simon.cathebras@ensimag.imag.fr>\n+#     Julien Khayat <julien.khayat@ensimag.imag.fr>\n+#     Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>\n+#     Simon Perrat <simon.perrat@ensimag.imag.fr>\n+#     Matthieu Moy <matthieu.moy@imag.fr>\n+# License: GPL v2 or later\n+\n+# Usage:\n+#       ./test-gitmw.pl <function> [argument]*\n+# Execute in terminal using the name of the function to call as first\n+# parameter, and the function's arguments as following parameters\n+#\n+# Example:\n+#     ./test-gitmw.pl \"get_page\" foo .\n+# will call <wiki_getpage> with arguments <foo> and <.>\n+#\n+# Available functions are:\n+#     \"get_page\"\n+#     \"delete_page\"\n+#     \"edit_page\"\n+#     \"getallpagename\"\n+\n+use MediaWiki::API;\n+use Switch;\n+# URL of the wiki used for the tests\n+my $wiki_url=\"http://localhost/wiki/api.php\";\n+my $wiki_admin='WikiAdmin';\n+my $wiki_admin_pass='AdminPass';\n+my $mw = MediaWiki::API->new;\n+$mw->{config}->{api_url} = $wiki_url;\n+\n+# wiki_login <name> <password>\n+#\n+# Logs the user with <name> and <password> in the global variable\n+# of the mediawiki $mw\n+sub wiki_login {\n+\t$mw->login( { lgname => \"$_[0]\",lgpassword => \"$_[1]\" } )\n+                || die \"getpage: login failed\";\n+}\n+\n+# wiki_getpage <wiki_page> <dest_path>\n+#\n+# fetch a page <wiki_page> from the wiki referenced in the global variable\n+# $mw and copies its content in directory dest_path\n+sub wiki_getpage {\n+\tmy $pagename = $_[0];\n+\tmy $destdir = $_[1];\n+\t\n+\tmy $page = $mw->get_page( { title => $pagename } );\n+\tif (!defined($page)) {\n+\t\tdie \"getpage: wiki does not exist\";\n+\t}\n+\n+\tmy $content = $page->{'*'};\n+\tif (!defined($content)) {\n+\t\tdie \"getpage: page does not exist\";\n+\t}\n+\n+        # Replace spaces by underscore in the page name\n+\t$pagename=~s/\\ /_/;\n+\topen(my $file, \">$destdir/$pagename.mw\");\n+\tprint $file \"$content\";\n+\tclose ($file);\n+}\n+\n+# wiki_delete_page <page_name>\n+#\n+# delete the page with name <page_name> from the wiki referenced\n+# in the global variable $mw\n+sub wiki_delete_page {\n+\tmy $pagename = $_[0];\n+\n+\tmy $exist=$mw->get_page({title => $pagename});\n+\n+\tif (defined($exist->{'*'})){\n+\t\t$mw->edit({ action => 'delete',\n+\t\t\t        title => $pagename})\n+\t\t|| die $mw->{error}->{code} . \": \" . $mw->{error}->{details};\n+\t}\n+        else{\n+\t\tdie \"no page with such name found: $pagename\\n\";\n+\t}\n+}\n+\n+# wiki_editpage <wiki_page> <wiki_content> <wiki_append>\n+#\n+# Edit a page named <wiki_page> with content <wiki_content> on the wiki\n+# referenced with the global variable $mw\n+# If <wiki_append> == true : append <wiki_content> at the end of the actual\n+# content of the page <wiki_page>\n+# If <wik_page> doesn't exist, that page is created with the <wiki_content>\n+sub wiki_editpage {\n+\tmy $wiki_page = $_[0];\n+\tmy $wiki_content = $_[1];\n+\tmy $wiki_append = $_[2];\n+\n+\tmy $append = 0;\n+\tif (defined($wiki_append) && $wiki_append eq 'true') {\n+\t\t$append=1;\n+\t}\n+\n+\tmy $previous_text =\"\";\n+\n+\tif ($append) {\n+\tmy $ref = $mw->get_page( { title => $wiki_page } );\n+\t\t$previous_text = $ref->{'*'};\n+\t}\n+\n+\tmy $text = $wiki_content;\n+\tif (defined($previous_text)) {\n+\t\t$text=\"$previous_text\\n\\n$text\";\n+\t}\n+\t$mw->edit( { action => 'edit', title => $wiki_page, text => \"$text\"} );\n+}\n+\n+# wiki_getallpagename\n+#\n+# Fetch all pages of the wiki referenced by the global variable $mw\n+# and print the names of each one in the file all.txt with a new line\n+# (\"\\n\") between these.\n+sub wiki_getallpagename {\n+        # fetch the pages of the wiki\n+\t$mw->list ( { action => 'query',\n+\t\t\tlist => 'allpages',\n+\t\t\t#cmtitle => \"Category:Surnames\",\n+\t\t\t#cmnamespace => 0,\n+\t\t\tcmlimit=> 500 },\n+\t\t{ max => 4, hook => \\&cat_names } )\n+\t        || die $mw->{error}->{code}.\": \".$mw->{error}->{details};\n+\n+\t# print the name of each page\n+\tsub cat_names {\n+\t\tmy ($ref) = @_;\n+\n+\t\topen(my $file, \">all.txt\");\n+\t\tforeach (@$ref) {\n+\t\t\tprint $file \"$_->{title}\\n\";\n+\t\t}\n+\t\tclose ($file);\n+\t}\n+}\n+\n+# Main part of this script: parse the command line arguments\n+# and select which function to execute\n+my $fct_to_call = shift;\n+my $login = $ARGV[0];\n+\n+if ($login eq \"-p\")\n+{\n+\t&wiki_login($wiki_admin,$wiki_admin_pass);\n+\tshift;\n+}\n+\n+switch ($fct_to_call) {\n+\tcase \"get_page\" { &wiki_getpage($ARGV[0], $ARGV[1])}\n+\tcase \"delete_page\" { &wiki_delete_page($ARGV[0])}\n+\tcase \"edit_page\" { &wiki_editpage($ARGV[0], $ARGV[1], $ARGV[2])}\n+\tcase \"getallpagename\" { &wiki_getallpagename()}\n+\telse{ die(\"test-gitmw.pl ERROR: wrong argument\")}\n+}\n+\n-- \n1.7.10.2.552.gaa3bb87\n"},{"id":"192495","messageId":"1338397492-13360-3-git-send-email-simon.cathebras@ensimag.imag.fr","threadId":"30658","inReplyTo":"1338397492-13360-1-git-send-email-simon.cathebras@ensimag.imag.fr","subject":"[PATCH 3/3] Tests file for git-remote-mediawiki","fromName":"Simon Cathebras","fromEmail":"simon.cathebras@ensimag.imag.fr","sentAt":"2012-05-30T17:04:52Z","receivedAt":"2012-05-30T17:04:52Z","isPatch":true,"sender":{"key":"simon.cathebras@ensimag.imag.fr","avatar":"https://avatars.githubusercontent.com/u/1764010?v=4"},"body":"From: Charles Roussel <charles.roussel@ensimag.fr>\n\nThis file (will) contains all tests for git-remote-mediawiki.\nFor now, we have one test of git-clone on a wiki with one page.\n\nSigned-off-by: Simon Cathebras <simon.cathebras@ensimag.imag.fr>\nSigned-off-by: Charles Roussel <charles.roussel@ensimag.imag.fr>\nSigned-off-by: Julien Khayat <julien.khayat@ensimag.imag.fr>\nSigned-off-by: Simon Perrat <simon.perrat@ensimag.imag.fr>\nSigned-off-by: Guillaume Sasdy <guillaume.sasdy@gmail.com>\n---\n t/t9360-git-mediawiki.sh | 49 ++++++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 49 insertions(+)\n create mode 100755 t/t9360-git-mediawiki.sh\n\ndiff --git a/t/t9360-git-mediawiki.sh b/t/t9360-git-mediawiki.sh\nnew file mode 100755\nindex 0000000..8de56c5\n--- /dev/null\n+++ b/t/t9360-git-mediawiki.sh\n@@ -0,0 +1,49 @@\n+#!/bin/sh\n+#\n+# Copyright (C) 2012\n+#     Charles Roussel <charles.roussel@ensimag.imag.fr>\n+#     Simon Cathebras <simon.cathebras@ensimag.imag.fr>\n+#     Julien Khayat <julien.khayat@ensimag.imag.fr>\n+#     Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>\n+#     Simon Perrat <simon.perrat@ensimag.imag.fr>\n+#     Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n+#\n+# License: GPL v2 or later\n+\n+# tests for git-remote-mediawiki\n+\n+test_description='Test the Git Mediawiki remote helper'\n+\n+. ./test-gitmw-lib.sh\n+. ./test-lib.sh\n+\n+if ! test_have_prereq PERL\n+then\n+\tskip_all='skipping gateway git-mw tests, perl not available'\n+\ttest_done\n+fi\n+\n+if [ ! -f /$GIT_BUILD_DIR/git-remote-mediawiki ];\n+then\n+\tskip_all='skipping gateway git-mw tests, no remote mediawiki for git found'\n+\ttest_done\n+fi\n+\n+if [ ! -d \"$WIKI_DIR_INST/$WIKI_DIR_NAME\" ] ;\n+then\n+\tskip_all='skipping gateway git-mw tests, no mediawiki found'\n+\ttest_done\n+fi\n+\n+test_expect_success 'git clone works with page added' '\n+\tcmd_reset &&\n+\twiki_editpage foo \"hello_world\" false &&\n+\twiki_editpage bar \"hi everybody !\" false &&\n+\tgit clone mediawiki::http://localhost/wiki mw_dir &&\n+\twiki_getallpage ref_page &&\n+\tgit_content mw_dir ref_page &&\n+\twiki_delete_page foo &&\n+\twiki_delete_page bar\n+'\n+\n+test_done\n-- \n1.7.10.2.552.gaa3bb87\n"},{"id":"192543","messageId":"vpqzk8oq0oe.fsf@bauges.imag.fr","threadId":"30658","inReplyTo":"1338397492-13360-2-git-send-email-simon.cathebras@ensimag.imag.fr","subject":"Re: [PATCH 2/3] Test environment of git-remote-mw","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-05-31T07:17:37Z","receivedAt":"2012-05-31T07:17:37Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Simon Cathebras <simon.cathebras@ensimag.imag.fr> writes:\n\n> index 2deead7..8698625 100755\n> --- a/t/test-gitmw-lib.sh\n> +++ b/t/test-gitmw-lib.sh\n> @@ -1,27 +1,136 @@\n> +# Copyright (C) 2012\n> +#     Charles Roussel <charles.roussel@ensimag.imag.fr>\n> +#     Simon Cathebras <simon.cathebras@ensimag.imag.fr>\n> +#     Julien Khayat <julien.khayat@ensimag.imag.fr>\n> +#     Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>\n> +#     Simon Perrat <simon.perrat@ensimag.imag.fr>\n> +#     Matthieu Moy <matthieu.moy@imag.fr>\n> +# License: GPL v2 or later\n> +\n\nWhy is this added by [PATCH 2/3]?\n\n> -# You might want to change those ones ...\n> +# You might want to change these ones\n>  #\n>  WIKI_DIR_NAME=\"wiki\"            # Name of the wiki's directory\n>  WIKI_DIR_INST=\"/var/www\"        # Directory of the web server\n>  TMP=\"/tmp\"                      # Temporary directory for downloads\n> -                                # Absolute address needed!\n> +                                # Absolute path required!\n>  SERVER_ADDR=\"localhost\"         # Web server's address\n>  \n> -#\n>  # CONFIGURATION\n> -# You should not change those ones unless you know what you to\n> +# You should not change these ones unless you know what you do\n\nThese fixups should have been squashed into the previous one. Bad use of\n\"git rebase -i\"?\n\n> +\t../test-gitmw.pl \"get_page\" -p \"$1\" \"$2\"\n\nUseless quotes around \"get_page\".\n\n(but useful ones around $1 and $2 ;-))\n\n> +\tresult=$(diff -r -B -w --exclude=\".git\" \"$1\" \"$2\")\n\nDoesn't seem to be in POSIX:\n\nhttp://pubs.opengroup.org/onlinepubs/009695399/utilities/diff.html\n\nWill this run on all platforms?\n\n> +# wiki_page_content <file_name> <page_name> \n> +#\n> +# Compares the contents of the file <file_name> and the wiki page\n> +# <page_name> and exits with error 1 if they do not match.\n\nIf it does a comparison, why isn't it named \"check_content\", or\n\"diff_content\"?\n\n> +# Usage:\n> +#       ./test-gitmw.pl <function> [argument]*\n\nI'd say s/function/command/\n\n> +my $wiki_url=\"http://localhost/wiki/api.php\";\n> +my $wiki_admin='WikiAdmin';\n> +my $wiki_admin_pass='AdminPass';\n\nIt would be nice to allow overriding these from the command-line. But as\nyou are now writting tests, you may as well apply the YAGNI\nprinciple ;-).\n\n> +        # Replace spaces by underscore in the page name\n\nIndent with space.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192544","messageId":"vpqtxywq0lc.fsf@bauges.imag.fr","threadId":"30658","inReplyTo":"1338397492-13360-1-git-send-email-simon.cathebras@ensimag.imag.fr","subject":"Re: [PATCH 1/3] Script to install, delete and clear a MediaWiki","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-05-31T07:19:27Z","receivedAt":"2012-05-31T07:19:27Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Simon Cathebras <simon.cathebras@ensimag.imag.fr> writes:\n\n> install_wiki also defines a function cmd_reset\n\nWhy the \"cmd_reset\" name?\n\nWouldn't wiki_reset be both more descriptive and more consistent?\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192610","messageId":"1338487992-305-1-git-send-email-guillaume.sasdy@ensimag.imag.fr","threadId":"30658","inReplyTo":"4FC64B0C.6070507@ensimag.imag.fr","subject":"[PATCH 1/2] FIX: t9360. NEW test t9361 for git pull and git push","fromName":"Guillaume Sasdy","fromEmail":"guillaume.sasdy@ensimag.imag.fr","sentAt":"2012-05-31T18:13:11Z","receivedAt":"2012-05-31T18:13:11Z","isPatch":true,"sender":{"key":"guillaume.sasdy@ensimag.imag.fr","avatar":null},"body":"t9360: change the description of the test. Test git clone\nt9361: Test git pull (add page, edit page, delete page) and git push on simple test cases (add file, edit file, delete file).\n---\n t/t9360-git-mediawiki.sh |   4 +-\n t/t9361-git-mediawiki.sh | 156 +++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 158 insertions(+), 2 deletions(-)\n create mode 100755 t/t9361-git-mediawiki.sh\n\ndiff --git a/t/t9360-git-mediawiki.sh b/t/t9360-git-mediawiki.sh\nindex 8de56c5..57e05d8 100755\n--- a/t/t9360-git-mediawiki.sh\n+++ b/t/t9360-git-mediawiki.sh\n@@ -12,7 +12,7 @@\n \n # tests for git-remote-mediawiki\n \n-test_description='Test the Git Mediawiki remote helper'\n+test_description='Test the Git Mediawiki remote helper: git clone'\n \n . ./test-gitmw-lib.sh\n . ./test-lib.sh\n@@ -36,7 +36,7 @@ then\n fi\n \n test_expect_success 'git clone works with page added' '\n-\tcmd_reset &&\n+\twiki_reset &&\n \twiki_editpage foo \"hello_world\" false &&\n \twiki_editpage bar \"hi everybody !\" false &&\n \tgit clone mediawiki::http://localhost/wiki mw_dir &&\ndiff --git a/t/t9361-git-mediawiki.sh b/t/t9361-git-mediawiki.sh\nnew file mode 100755\nindex 0000000..9dd7274\n--- /dev/null\n+++ b/t/t9361-git-mediawiki.sh\n@@ -0,0 +1,156 @@\n+#!/bin/sh\n+#\n+# Copyright (C) 2012\n+#     Charles Roussel <charles.roussel@ensimag.imag.fr>\n+#     Simon Cathebras <simon.cathebras@ensimag.imag.fr>\n+#     Julien Khayat <julien.khayat@ensimag.imag.fr>\n+#     Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>\n+#     Simon Perrat <simon.perrat@ensimag.imag.fr>\n+#     Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n+#\n+# License: GPL v2 or later\n+\n+# tests for git-remote-mediawiki\n+\n+test_description='Test the Git Mediawiki remote helper: git push and git pull simple test cases'\n+\n+. ./test-gitmw-lib.sh\n+. ./test-lib.sh\n+\n+if ! test_have_prereq PERL\n+then\n+\tskip_all='skipping gateway git-mw tests, perl not available'\n+\ttest_done\n+fi\n+\n+if [ ! -f /$GIT_BUILD_DIR/git-remote-mediawiki ];\n+then\n+\tskip_all='skipping gateway git-mw tests, no remote mediawiki for git found'\n+\ttest_done\n+fi\n+\n+if [ ! -d \"$WIKI_DIR_INST/$WIKI_DIR_NAME\" ] ;\n+then\n+\tskip_all='skipping gateway git-mw tests, no mediawiki found'\n+\ttest_done\n+fi\n+\n+# Create a new file foo.mw in a freshly cloned wiki. Commit and push\n+# this file and then check that all files of the repository are similar to\n+# the wiki pages.\n+test_expect_success 'git push works after adding a file .mw' \"\n+        wiki_reset &&\n+        git clone mediawiki::http://$SERVER_ADDR/$WIKI_DIR_NAME mw_dir &&\n+        wiki_getallpage ref_page &&\n+\n+        cd mw_dir &&\n+        test ! -f foo.mw && # foo.mw should not exist after wiki_reset &&\n+        touch foo.mw &&\n+        echo \\\"hello world\\\" >> foo.mw &&\n+        git add foo.mw &&\n+        git commit -m \\\"foo\\\" &&\n+        git push &&\n+        cd .. &&\n+\n+        rm -rf ref_page &&\n+        wiki_getallpage ref_page &&\n+        git_content mw_dir ref_page &&\n+        rm -rf ref_page &&\n+        rm -rf mw_dir\n+\"\n+\n+# Create a new page Foo in an empty wiki. Clone the wiki and edit\n+# the file foo.mw corresponding to the page Foo. Commit and push\n+# then check that all files of the repository are similar to the wiki\n+# pages.\n+test_expect_success 'git push works after editing a file .mw' \"\n+        # clone an empty wiki and add a Foo page\n+        wiki_reset &&\n+        wiki_editpage \\\"foo\\\" \\\"page just created before the git clone\\\" false &&\n+        git clone mediawiki::http://$SERVER_ADDR/$WIKI_DIR_NAME mw_dir &&\n+\n+        cd mw_dir &&\n+        echo \\\"new line added in the file foo.mw\\\" >> Foo.mw &&\n+        git commit -am \\\"edit file foo.mw\\\" &&\n+        git push &&\n+        cd .. &&\n+\n+        rm -rf ref_page &&\n+        wiki_getallpage ref_page &&\n+        git_content mw_dir ref_page &&\n+        rm -rf ref_page &&\n+        rm -rf mw_dir\n+\"\n+\n+# Clone a wiki with a page Foo. Remove the corresponding file from the\n+# repository. Check that the wiki page has been actually removed.\n+test_expect_failure 'git push works after deleting a file' \"\n+        wiki_reset &&\n+        wiki_editpage foo \\\"wiki page added before git clone\\\" false &&\n+        git clone mediawiki::http://$SERVER_ADDR/$WIKI_DIR_NAME mw_dir &&\n+\n+        cd mw_dir &&\n+        git rm Foo.mw &&\n+        git commit -am \\\"git rm delete the wiki page Foo.mw\\\" &&\n+        git push &&\n+        cd .. &&\n+\n+        rm -rf mw_dir &&\n+        test ! wiki_page_exist Foo\n+\"\n+\n+# Clone an empty wiki. Add a page on the wiki and pull. Check \n+# all files of the repository are similar to the wiki pages.\n+test_expect_success 'git pull works after adding a new wiki page' \"\n+        wiki_reset &&\n+        git clone mediawiki::http://$SERVER_ADDR/$WIKI_DIR_NAME mw_dir &&\n+        wiki_editpage foo \\\"page just created after the git clone\\\" false &&\n+\n+        cd mw_dir &&\n+        git pull &&\n+        cd .. &&\n+\n+        rm -rf ref_page &&\n+        wiki_getallpage ref_page &&\n+        git_content mw_dir ref_page &&\n+        rm -rf ref_page &&\n+        rm -rf mw_dir\n+\"\n+\n+# Clone a wiki with a page Foo. Edit the page foo on the wiki and pull.\n+# Check that all files of the repository are similar to the wiki pages.\n+test_expect_success 'git pull works after editing a wiki page' \"\n+        wiki_reset &&\n+        wiki_editpage foo \\\"page just created before the git clone\\\" false &&\n+        git clone mediawiki::http://$SERVER_ADDR/$WIKI_DIR_NAME mw_dir &&\n+        wiki_editpage foo \\\"new line added on the wiki\\\" true &&\n+\n+        cd mw_dir &&\n+        git pull &&\n+        cd .. &&\n+       \n+        rm -rf ref_page &&\n+        wiki_getallpage ref_page &&\n+        git_content mw_dir ref_page &&\n+        rm -rf ref_page\n+        rm -rf mw_dir\n+\"\n+\n+# Clone a wiki with a page Foo. Remove the wiki page and pull.\n+# Check that the corresponding file in the repository has been actually removed.\n+test_expect_failure 'git pull works after deleting a wiki page' \"\n+        wiki_reset &&\n+        wiki_editpage foo \\\"wiki page added before git clone\\\" false &&\n+        git clone mediawiki::http://$SERVER_ADDR/$WIKI_DIR_NAME mw_dir &&\n+\n+        cd mw_dir &&\n+        wiki_delete_page foo\n+        git pull &&\n+        test ! -f Foo.mw &&\n+        cd .. &&\n+\n+        rm -rf mw_dir\n+\"\n+\n+test_done\n+\n-- \n1.7.10.2.568.g4c26a3a\n"},{"id":"192607","messageId":"1338487992-305-2-git-send-email-guillaume.sasdy@ensimag.imag.fr","threadId":"30658","inReplyTo":"1338487992-305-1-git-send-email-guillaume.sasdy@ensimag.imag.fr","subject":"[PATCH 2/2] FIX: Syntax of shell and perl scripts and posix compliant","fromName":"Guillaume Sasdy","fromEmail":"guillaume.sasdy@ensimag.imag.fr","sentAt":"2012-05-31T18:13:12Z","receivedAt":"2012-05-31T18:13:12Z","isPatch":true,"sender":{"key":"guillaume.sasdy@ensimag.imag.fr","avatar":null},"body":"From: Simon Cathebras <simon.cathebras@ensimag.imag.fr>\n\nt/test-gitmw.pl: no more '\\n' in the append of wiki_editpage\nt/test-gitmw-lib.sh: grep is now Posix compliant\nt/test-gitmw-lib.sh: some \"  \" were misplaced\n---\n t/test-gitmw-lib.sh | 17 ++++++++---------\n t/test-gitmw.pl     |  4 ++--\n 2 files changed, 10 insertions(+), 11 deletions(-)\n\ndiff --git a/t/test-gitmw-lib.sh b/t/test-gitmw-lib.sh\nindex b89b45a..d7c7459 100755\n--- a/t/test-gitmw-lib.sh\n+++ b/t/test-gitmw-lib.sh\n@@ -31,14 +31,14 @@ WIKI_PASSW=\"AdminPass\"\n # Fetch a page <page_name> from the wiki and copy its content\n # into directory <dest_path>.\n wiki_getpage () {\n-\t../test-gitmw.pl \"get_page\" -p \"$1\" \"$2\"\n+\t../test-gitmw.pl get_page -p \"$1\" \"$2\"\n }\n \n # wiki_delete_page <page_name>\n #\n # Delete the page <page_name> on the wiki.\n wiki_delete_page () {\n-\t../test-gitmw.pl \"delete_page\" -p \"$1\"\n+\t../test-gitmw.pl delete_page -p \"$1\"\n }\n \n # wiki_edit_page <page_name> <page_content> <page_append>\n@@ -47,7 +47,7 @@ wiki_delete_page () {\n # If <wiki_append> == true the content will be appended\n # If the page doesn't exist, it is created.\n wiki_editpage () {\n-\t../test-gitmw.pl \"edit_page\" -p \"$1\" \"$2\" \"$3\"\n+\t../test-gitmw.pl edit_page -p \"$1\" \"$2\" \"$3\"\n }\n \n # git_content <dir_1> <dir_2>\n@@ -56,7 +56,7 @@ wiki_editpage () {\n # and exits with error 1 if they do not match. The program will\n # not look into .git in the process.\n git_content () {\n-\tresult=$(diff -r -B -w --exclude=\".git\" \"$1\" \"$2\")\n+\tresult=$(diff -r -b --exclude=\".git\" \"$1\" \"$2\")\n \n \tif echo $result | grep -q \">\" ; then\n \t\techo \"test failed: files $1 and $2 do not match\"\n@@ -77,11 +77,11 @@ git_exist () {\n \tfi\n }\n \n-# wiki_page_content <file_name> <page_name> \n+# wiki_check_content <file_name> <page_name> \n #\n # Compares the contents of the file <file_name> and the wiki page\n # <page_name> and exits with error 1 if they do not match.\n-wiki_page_content () {\n+wiki_check_content () {\n \twiki_getpage \"$2\" .\n \n \tif test -f \"$2\".mw ; then\n@@ -120,16 +120,15 @@ wiki_getallpagename () {\n # <dest_dir>.\n wiki_getallpage () {\n \twiki_getallpagename\n-\tmkdir $1\n+\tmkdir -p \"$1\"\n \twhile read -r line; do\n \t\twiki_getpage \"$line\" $1;\n \tdone < all.txt\n-\t#rm all.txt\n }\n \n fail()\n {\n-    echo $1\n+    echo \"$1\"\n     exit 1\n }\n \ndiff --git a/t/test-gitmw.pl b/t/test-gitmw.pl\nindex e9c50f9..bf71485 100755\n--- a/t/test-gitmw.pl\n+++ b/t/test-gitmw.pl\n@@ -9,7 +9,7 @@\n # License: GPL v2 or later\n \n # Usage:\n-#       ./test-gitmw.pl <function> [argument]*\n+#       ./test-gitmw.pl <command> [argument]*\n # Execute in terminal using the name of the function to call as first\n # parameter, and the function's arguments as following parameters\n #\n@@ -111,7 +111,7 @@ sub wiki_editpage {\n \n \tmy $text = $wiki_content;\n \tif (defined($previous_text)) {\n-\t\t$text=\"$previous_text\\n\\n$text\";\n+\t\t$text=\"$previous_text$text\";\n \t}\n \t$mw->edit( { action => 'edit', title => $wiki_page, text => \"$text\"} );\n }\n-- \n1.7.10.2.568.g4c26a3a\n"},{"id":"192608","messageId":"1338488167-1217-1-git-send-email-guillaume.sasdy@ensimag.imag.fr","threadId":"30658","inReplyTo":"4FC64B0C.6070507@ensimag.imag.fr","subject":"[PATCH] FIX: Syntax of shell and perl scripts and posix compliant","fromName":"Guillaume Sasdy","fromEmail":"guillaume.sasdy@ensimag.imag.fr","sentAt":"2012-05-31T18:16:07Z","receivedAt":"2012-05-31T18:16:07Z","isPatch":true,"sender":{"key":"guillaume.sasdy@ensimag.imag.fr","avatar":null},"body":"From: Simon Cathebras <simon.cathebras@ensimag.imag.fr>\n\nt/test-gitmw.pl: no more '\\n' in the append of wiki_editpage\nt/test-gitmw-lib.sh: grep is now Posix compliant\nt/test-gitmw-lib.sh: some \"  \" were misplaced\n---\n t/test-gitmw-lib.sh | 17 ++++++++---------\n t/test-gitmw.pl     |  4 ++--\n 2 files changed, 10 insertions(+), 11 deletions(-)\n\ndiff --git a/t/test-gitmw-lib.sh b/t/test-gitmw-lib.sh\nindex b89b45a..d7c7459 100755\n--- a/t/test-gitmw-lib.sh\n+++ b/t/test-gitmw-lib.sh\n@@ -31,14 +31,14 @@ WIKI_PASSW=\"AdminPass\"\n # Fetch a page <page_name> from the wiki and copy its content\n # into directory <dest_path>.\n wiki_getpage () {\n-\t../test-gitmw.pl \"get_page\" -p \"$1\" \"$2\"\n+\t../test-gitmw.pl get_page -p \"$1\" \"$2\"\n }\n \n # wiki_delete_page <page_name>\n #\n # Delete the page <page_name> on the wiki.\n wiki_delete_page () {\n-\t../test-gitmw.pl \"delete_page\" -p \"$1\"\n+\t../test-gitmw.pl delete_page -p \"$1\"\n }\n \n # wiki_edit_page <page_name> <page_content> <page_append>\n@@ -47,7 +47,7 @@ wiki_delete_page () {\n # If <wiki_append> == true the content will be appended\n # If the page doesn't exist, it is created.\n wiki_editpage () {\n-\t../test-gitmw.pl \"edit_page\" -p \"$1\" \"$2\" \"$3\"\n+\t../test-gitmw.pl edit_page -p \"$1\" \"$2\" \"$3\"\n }\n \n # git_content <dir_1> <dir_2>\n@@ -56,7 +56,7 @@ wiki_editpage () {\n # and exits with error 1 if they do not match. The program will\n # not look into .git in the process.\n git_content () {\n-\tresult=$(diff -r -B -w --exclude=\".git\" \"$1\" \"$2\")\n+\tresult=$(diff -r -b --exclude=\".git\" \"$1\" \"$2\")\n \n \tif echo $result | grep -q \">\" ; then\n \t\techo \"test failed: files $1 and $2 do not match\"\n@@ -77,11 +77,11 @@ git_exist () {\n \tfi\n }\n \n-# wiki_page_content <file_name> <page_name> \n+# wiki_check_content <file_name> <page_name> \n #\n # Compares the contents of the file <file_name> and the wiki page\n # <page_name> and exits with error 1 if they do not match.\n-wiki_page_content () {\n+wiki_check_content () {\n \twiki_getpage \"$2\" .\n \n \tif test -f \"$2\".mw ; then\n@@ -120,16 +120,15 @@ wiki_getallpagename () {\n # <dest_dir>.\n wiki_getallpage () {\n \twiki_getallpagename\n-\tmkdir $1\n+\tmkdir -p \"$1\"\n \twhile read -r line; do\n \t\twiki_getpage \"$line\" $1;\n \tdone < all.txt\n-\t#rm all.txt\n }\n \n fail()\n {\n-    echo $1\n+    echo \"$1\"\n     exit 1\n }\n \ndiff --git a/t/test-gitmw.pl b/t/test-gitmw.pl\nindex e9c50f9..bf71485 100755\n--- a/t/test-gitmw.pl\n+++ b/t/test-gitmw.pl\n@@ -9,7 +9,7 @@\n # License: GPL v2 or later\n \n # Usage:\n-#       ./test-gitmw.pl <function> [argument]*\n+#       ./test-gitmw.pl <command> [argument]*\n # Execute in terminal using the name of the function to call as first\n # parameter, and the function's arguments as following parameters\n #\n@@ -111,7 +111,7 @@ sub wiki_editpage {\n \n \tmy $text = $wiki_content;\n \tif (defined($previous_text)) {\n-\t\t$text=\"$previous_text\\n\\n$text\";\n+\t\t$text=\"$previous_text$text\";\n \t}\n \t$mw->edit( { action => 'edit', title => $wiki_page, text => \"$text\"} );\n }\n-- \n1.7.10.2.568.g4c26a3a\n"},{"id":"192609","messageId":"1338488824-3336-1-git-send-email-guillaume.sasdy@ensimag.imag.fr","threadId":"30658","inReplyTo":"4FC64B0C.6070507@ensimag.imag.fr","subject":"[PATCH] FIX: Syntax of shell and perl scripts and posix compliant","fromName":"Guillaume Sasdy","fromEmail":"guillaume.sasdy@ensimag.imag.fr","sentAt":"2012-05-31T18:27:04Z","receivedAt":"2012-05-31T18:27:04Z","isPatch":true,"sender":{"key":"guillaume.sasdy@ensimag.imag.fr","avatar":null},"body":"From: Simon Cathebras <simon.cathebras@ensimag.imag.fr>\n\nt/test-gitmw.pl: no more '\\n' in the append of wiki_editpage\nt/test-gitmw-lib.sh: grep is now Posix compliant\nt/test-gitmw-lib.sh: some \"  \" were misplaced\n---\n t/test-gitmw-lib.sh | 17 ++++++++---------\n t/test-gitmw.pl     |  4 ++--\n 2 files changed, 10 insertions(+), 11 deletions(-)\n\ndiff --git a/t/test-gitmw-lib.sh b/t/test-gitmw-lib.sh\nindex b89b45a..d7c7459 100755\n--- a/t/test-gitmw-lib.sh\n+++ b/t/test-gitmw-lib.sh\n@@ -31,14 +31,14 @@ WIKI_PASSW=\"AdminPass\"\n # Fetch a page <page_name> from the wiki and copy its content\n # into directory <dest_path>.\n wiki_getpage () {\n-\t../test-gitmw.pl \"get_page\" -p \"$1\" \"$2\"\n+\t../test-gitmw.pl get_page -p \"$1\" \"$2\"\n }\n \n # wiki_delete_page <page_name>\n #\n # Delete the page <page_name> on the wiki.\n wiki_delete_page () {\n-\t../test-gitmw.pl \"delete_page\" -p \"$1\"\n+\t../test-gitmw.pl delete_page -p \"$1\"\n }\n \n # wiki_edit_page <page_name> <page_content> <page_append>\n@@ -47,7 +47,7 @@ wiki_delete_page () {\n # If <wiki_append> == true the content will be appended\n # If the page doesn't exist, it is created.\n wiki_editpage () {\n-\t../test-gitmw.pl \"edit_page\" -p \"$1\" \"$2\" \"$3\"\n+\t../test-gitmw.pl edit_page -p \"$1\" \"$2\" \"$3\"\n }\n \n # git_content <dir_1> <dir_2>\n@@ -56,7 +56,7 @@ wiki_editpage () {\n # and exits with error 1 if they do not match. The program will\n # not look into .git in the process.\n git_content () {\n-\tresult=$(diff -r -B -w --exclude=\".git\" \"$1\" \"$2\")\n+\tresult=$(diff -r -b --exclude=\".git\" \"$1\" \"$2\")\n \n \tif echo $result | grep -q \">\" ; then\n \t\techo \"test failed: files $1 and $2 do not match\"\n@@ -77,11 +77,11 @@ git_exist () {\n \tfi\n }\n \n-# wiki_page_content <file_name> <page_name> \n+# wiki_check_content <file_name> <page_name> \n #\n # Compares the contents of the file <file_name> and the wiki page\n # <page_name> and exits with error 1 if they do not match.\n-wiki_page_content () {\n+wiki_check_content () {\n \twiki_getpage \"$2\" .\n \n \tif test -f \"$2\".mw ; then\n@@ -120,16 +120,15 @@ wiki_getallpagename () {\n # <dest_dir>.\n wiki_getallpage () {\n \twiki_getallpagename\n-\tmkdir $1\n+\tmkdir -p \"$1\"\n \twhile read -r line; do\n \t\twiki_getpage \"$line\" $1;\n \tdone < all.txt\n-\t#rm all.txt\n }\n \n fail()\n {\n-    echo $1\n+    echo \"$1\"\n     exit 1\n }\n \ndiff --git a/t/test-gitmw.pl b/t/test-gitmw.pl\nindex e9c50f9..bf71485 100755\n--- a/t/test-gitmw.pl\n+++ b/t/test-gitmw.pl\n@@ -9,7 +9,7 @@\n # License: GPL v2 or later\n \n # Usage:\n-#       ./test-gitmw.pl <function> [argument]*\n+#       ./test-gitmw.pl <command> [argument]*\n # Execute in terminal using the name of the function to call as first\n # parameter, and the function's arguments as following parameters\n #\n@@ -111,7 +111,7 @@ sub wiki_editpage {\n \n \tmy $text = $wiki_content;\n \tif (defined($previous_text)) {\n-\t\t$text=\"$previous_text\\n\\n$text\";\n+\t\t$text=\"$previous_text$text\";\n \t}\n \t$mw->edit( { action => 'edit', title => $wiki_page, text => \"$text\"} );\n }\n-- \n1.7.10.2.568.g4c26a3a\n"},{"id":"192611","messageId":"1338489110-4843-1-git-send-email-guillaume.sasdy@ensimag.imag.fr","threadId":"30658","inReplyTo":"4FC64B0C.6070507@ensimag.imag.fr","subject":"[PATCH 1/3] FIX: cmd_* moved to wiki_* in test-gitmw-lib.sh and other files","fromName":"Guillaume Sasdy","fromEmail":"guillaume.sasdy@ensimag.imag.fr","sentAt":"2012-05-31T18:31:50Z","receivedAt":"2012-05-31T18:31:50Z","isPatch":true,"sender":{"key":"guillaume.sasdy@ensimag.imag.fr","avatar":null},"body":"From: Simon Cathebras <simon.cathebras@ensimag.imag.fr>\n\nFunction cmd_* has been renamed in wiki_* in t/install-wiki.sh.\nChange the calls in t/test-gitmw-lib.sh\n---\n t/install-wiki.sh   |  4 ++--\n t/test-gitmw-lib.sh | 10 +++++-----\n 2 files changed, 7 insertions(+), 7 deletions(-)\n\ndiff --git a/t/install-wiki.sh b/t/install-wiki.sh\nindex 725346e..322f46d 100755\n--- a/t/install-wiki.sh\n+++ b/t/install-wiki.sh\n@@ -19,11 +19,11 @@ usage () {\n # Argument: install, delete, --help | -h\n case \"$1\" in\n \t\"install\")\n-\t\tcmd_install\n+\t\twiki_install\n \t\texit 0\n \t\t;;\n \t\"delete\")\n-\t\tcmd_delete\n+\t\twiki_delete\n \t\texit 0\n \t\t;;\n \t\"--help\" | \"-h\")\ndiff --git a/t/test-gitmw-lib.sh b/t/test-gitmw-lib.sh\nindex 8698625..b89b45a 100755\n--- a/t/test-gitmw-lib.sh\n+++ b/t/test-gitmw-lib.sh\n@@ -136,7 +136,7 @@ fail()\n \n \n # Install a wiki in your web server directory.\n-cmd_install () {\n+wiki_install () {\n \n \t# Copy the generic LocalSettings.php in the web server's directory\n \t# And modify parameters according to the ones set at the top\n@@ -206,7 +206,7 @@ cmd_install () {\n # Argument $1 is the relative path to the folder $FILES_FOLDER\n #\n # Warning: This function should be not called by user. This is a private\n-# function used by cmd_install and cmd_delete\n+# function used by wiki_install and wiki_delete\n reset_db_wiki () {\n \n \t# Copy initial database of the wiki\n@@ -221,7 +221,7 @@ reset_db_wiki () {\n # Set the admin WikiAdmin with password AdminPass in the database.\n #\n # Warning: This function should be not called by user. This is a private\n-# function used by cmd_install and cmd_delete\n+# function used by wiki_install and wiki_delete\n set_admin_wiki () {\n \n \t#Add the admin\n@@ -237,14 +237,14 @@ set_admin_wiki () {\n # Reset the database of the wiki and the password of the admin\n #\n # Warning: This function must be called only in a subdirectory of t/ directory\n-cmd_reset () {\n+wiki_reset () {\n \treset_db_wiki \"..\"\n \tset_admin_wiki\n }\n \n # Delete the wiki created in the web server's directory and all its content\n # saved in the database.\n-cmd_delete () {\n+wiki_delete () {\n \t# Delete the wiki's directory.\n \trm -rf \"$WIKI_DIR_INST/$WIKI_DIR_NAME\" ||\n \t\tfail \"Wiki's directory $WIKI_DIR_INST/\" \\\n-- \n1.7.10.2.568.g4c26a3a\n"},{"id":"192634","messageId":"4FC88310.2020103@ensimag.imag.fr","threadId":"30658","inReplyTo":"vpqzk8oq0oe.fsf@bauges.imag.fr","subject":"Re: [PATCH 2/3] Test environment of git-remote-mw","fromName":"Simon.Cathebras","fromEmail":"simon.cathebras@ensimag.imag.fr","sentAt":"2012-06-01T08:53:36Z","receivedAt":"2012-06-01T08:53:36Z","isPatch":true,"sender":{"key":"simon.cathebras@ensimag.imag.fr","avatar":"https://avatars.githubusercontent.com/u/1764010?v=4"},"body":"On 31/05/2012 09:17, Matthieu Moy wrote:\n>\n>> +\tresult=$(diff -r -B -w --exclude=\".git\" \"$1\" \"$2\")\n> Doesn't seem to be in POSIX:\n>\n> http://pubs.opengroup.org/onlinepubs/009695399/utilities/diff.html\n>\n> Will this run on all platforms?\n>\nIndeed. According to the POSIX manual, the option -B and -w are merged \nin the single option -b.\nIn addition, -r option still exists (to compare recursively two \ndirectories).\nThe previous instruction will be write as follow :\n     diff -r -b \"$first_folder\" \"$second_folder\"\n\nWith this fix, it will works on all platforms. ;)\n>> +my $wiki_url=\"http://localhost/wiki/api.php\";\n>> +my $wiki_admin='WikiAdmin';\n>> +my $wiki_admin_pass='AdminPass';\n> It would be nice to allow overriding these from the command-line. But as\n> you are now writting tests, you may as well apply the YAGNI\n> principle ;-).\nDoes it seems important for you to overriding these from CL ?\nBy default, those settings work fine. You have to edit this only if you \nneed a special configuration. But it is purely optionnal.\n\n   Included in v2 patches:\n\n     * Fixing errors pointed above.\n     * Sqlite file excluded from the patches. Mainly with reviewing the \nwiki_install script.\n\nOn the other hand, considering the git-mediawiki is curently on contrib \nbranch, shall we move our test environement from git/t to git/contrib/t ?\n\nSimonC\n\n-- \nCATHEBRAS Simon\n\n2A-ENSIMAG\n\nFilière Ingéniérie des Systèmes d'Information\nMembre Bug-Buster\n"},{"id":"192636","messageId":"vpqpq9jievq.fsf@bauges.imag.fr","threadId":"30658","inReplyTo":"4FC88310.2020103@ensimag.imag.fr","subject":"Re: [PATCH 2/3] Test environment of git-remote-mw","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-06-01T09:02:33Z","receivedAt":"2012-06-01T09:02:33Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"\"Simon.Cathebras\" <Simon.Cathebras@ensimag.imag.fr> writes:\n\n> On the other hand, considering the git-mediawiki is curently on\n> contrib branch, shall we move our test environement from git/t to\n> git/contrib/t ?\n\nIf so, that would be to $git/contrib/mw-to-git/t/.\n\nI'm not sur what's best, depending on the future of the tool:\n\nIf, once Git-MediaWiki is robust, well-tested, ... and enough people are\ninterested, it may make sense to move Git-MediaWiki out of the contrib/\ndirectory, and integrate it as an official command (like git-svn for\nexample). That would make the installation process seamless (\"make\ninstall\" would install git-remote-mediawiki like other commands, \"make\ndoc\" would generate the doc, and so on), which would be nice for the\nuser.\n\nMy feeling is that we're still quite far from this. Although we're in\nthe process of having a well-tested program, and that new features are\ngoing to come soon, there is still little interest of the community for\nit (at least, uncomparable to the one of git-svn for example).\n\nSo, I'd say that we should stick to something non-intrusive, within\ncontrib/, and if more people show interest in the tool and if it becomes\nmature enough, we can start trying to push it out of contrib/.\n\nWhat do other people think?\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192640","messageId":"vpq7gvridzd.fsf@bauges.imag.fr","threadId":"30658","inReplyTo":"vpqpq9jievq.fsf@bauges.imag.fr","subject":"Re: [PATCH 2/3] Test environment of git-remote-mw","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-06-01T09:21:58Z","receivedAt":"2012-06-01T09:21:58Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:\n\n> \"Simon.Cathebras\" <Simon.Cathebras@ensimag.imag.fr> writes:\n>\n>> On the other hand, considering the git-mediawiki is curently on\n>> contrib branch, shall we move our test environement from git/t to\n>> git/contrib/t ?\n>\n> If so, that would be to $git/contrib/mw-to-git/t/.\n>\n> I'm not sur what's best, depending on the future of the tool:\n>\n> If, once Git-MediaWiki is robust, well-tested, ... and enough people are\n> interested, it may make sense to move Git-MediaWiki out of the contrib/\n> directory, and integrate it as an official command (like git-svn for\n> example). That would make the installation process seamless (\"make\n> install\" would install git-remote-mediawiki like other commands, \"make\n> doc\" would generate the doc, and so on), which would be nice for the\n> user.\n\nHere's another attempt to be nice to the user, without getting out of\nthe contrib/ directory. I suggest that you include it in your patch\nserie, and build your stuff on top of it.\n\n--------------- 8< ----------------- 8< ------------------------\nFrom 25187a652abc0b546be2fb1afb707b32b9f1d4fc Mon Sep 17 00:00:00 2001\nFrom: Matthieu Moy <Matthieu.Moy@imag.fr>\nDate: Fri, 1 Jun 2012 11:18:20 +0200\nSubject: [PATCH] git-remote-mediawiki: simple Makefile for simple\n installation\n\nThis allows the user to run \"make check\" to install the script in Git's\nexec path, following the configuration (manual in config.mak, or through\nautoconf).\n---\n contrib/mw-to-git/Makefile | 29 +++++++++++++++++++++++++++++\n 1 file changed, 29 insertions(+)\n create mode 100644 contrib/mw-to-git/Makefile\n\ndiff --git a/contrib/mw-to-git/Makefile b/contrib/mw-to-git/Makefile\nnew file mode 100644\nindex 0000000..99b7caa\n--- /dev/null\n+++ b/contrib/mw-to-git/Makefile\n@@ -0,0 +1,29 @@\n+-include ../../config.mak\n+-include ../../config.mak.autogen\n+\n+ifndef PERL_PATH\n+\tPERL_PATH = /usr/bin/perl\n+endif\n+\n+PERL_PATH_SQ = $(subst ','\\'',$(PERL_PATH))\n+gitexecdir_SQ = $(subst ','\\'',$(gitexecdir))\n+\n+SCRIPT=git-remote-mediawiki\n+\n+.PHONY: install help doc test\n+help:\n+\t@echo 'This is the help target of the Makefile. Current configuration:'\n+\t@echo '  gitexecdir = $(gitexecdir_SQ)'\n+\t@echo '  PERL_PATH = $(PERL_PATH_SQ)'\n+\t@echo 'Run \"$(MAKE) install\" to install $(SCRIPT) in gitexecdir.'\n+\n+install:\n+\tsed -e '1s|#!.*/perl|#!$(PERL_PATH_SQ)|' $(SCRIPT) \\\n+            > '$(gitexecdir_SQ)/$(SCRIPT)'\n+\tchmod 755 '$(gitexecdir)/$(SCRIPT)'\n+\n+doc:\n+\t@echo 'Sorry, \"make doc\" is not implemented yet for $(SCRIPT)'\n+\n+test:\n+\t@echo 'Sorry, \"make test\" is not implemented yet for $(SCRIPT)'\n-- \n1.7.10.2.817.g37218b0\n\n\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192648","messageId":"1338547317-26088-1-git-send-email-guillaume.sasdy@ensimag.imag.fr","threadId":"30658","inReplyTo":"4FC64B0C.6070507@ensimag.imag.fr","subject":"[PATCH 1/3] Script to install, delete and clear a MediaWiki","fromName":"Guillaume Sasdy","fromEmail":"guillaume.sasdy@ensimag.imag.fr","sentAt":"2012-06-01T10:41:55Z","receivedAt":"2012-06-01T10:41:55Z","isPatch":true,"sender":{"key":"guillaume.sasdy@ensimag.imag.fr","avatar":null},"body":"From: Charles Roussel <charles.roussel@ensimag.fr>\n\ninstall_wiki.sh expects the first argument to be 'install' or 'delete'\n'install' installs a MediaWiki on the web's server with SQLite3\n'delete' deletes the previously created wiki.\nNote those functionnalities are made to be used from the user command line in\nthe directory t/\n\ninstall_wiki also defines a function cmd_reset which clear all content\nof the previously created wiki. Note this functionnality is made to be\nused only by our test function in a subdirectory of t/\n\nSigned-off-by: Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>\nSigned-off-by: Simon Cathebras <Simon.Cathebras@ensimag.imag.fr>\nSigned-off-by: Simon Perrat <Simon.Perrat@ensimag.imag.fr>\nSigned-off-by: Charles Roussel <Charles.Roussel@ensimag.imag.fr>\nSigned-off-by: Julien Khayat <Julien.Khayat@ensimag.imag.fr>\n---\n t/install-wiki.sh                |  38 ++++++++++\n t/install-wiki/LocalSettings.php | 129 ++++++++++++++++++++++++++++++++++\n t/install-wiki/wikidb.sqlite     | Bin 0 -> 210944 bytes\n t/test-gitmw-lib.sh              | 147 +++++++++++++++++++++++++++++++++++++++\n 4 files changed, 314 insertions(+)\n create mode 100755 t/install-wiki.sh\n create mode 100644 t/install-wiki/LocalSettings.php\n create mode 100644 t/install-wiki/wikidb.sqlite\n create mode 100755 t/test-gitmw-lib.sh\n mode change 100644 => 100755 t/test-lib-functions.sh\n mode change 100644 => 100755 t/test-lib.sh\n\ndiff --git a/t/install-wiki.sh b/t/install-wiki.sh\nnew file mode 100755\nindex 0000000..322f46d\n--- /dev/null\n+++ b/t/install-wiki.sh\n@@ -0,0 +1,38 @@\n+#!/bin/sh\n+\n+# This script installs or deletes a MediaWiki on your computer.\n+# It requires a web server with PHP and SQLite running. In addition, if you \n+# do not have MediaWiki sources on your computer, the option 'install' \n+# downloads them for you.\n+# Please set the CONFIGURATION VARIABLES in ./test-gitmw-lib.sh\n+\n+. ./test-gitmw-lib.sh\n+\n+usage () {\n+        echo \"Usage: \"\n+        echo \"  ./install-wiki.sh <install|delete|--help|-h>\"\n+        echo \"          install: Install a wiki on your computer.\"\n+        echo \"          delete: Delete the wiki and all its pages and      content\"\n+}\n+\n+\n+# Argument: install, delete, --help | -h\n+case \"$1\" in\n+\t\"install\")\n+\t\twiki_install\n+\t\texit 0\n+\t\t;;\n+\t\"delete\")\n+\t\twiki_delete\n+\t\texit 0\n+\t\t;;\n+\t\"--help\" | \"-h\")\n+\t\tusage\n+\t\texit 0\n+\t\t;;\n+\t*)\n+\t\tusage\n+\t\texit 0\n+\t\t;;\n+esac\n+\ndiff --git a/t/install-wiki/LocalSettings.php b/t/install-wiki/LocalSettings.php\nnew file mode 100644\nindex 0000000..c2fe3d5\n--- /dev/null\n+++ b/t/install-wiki/LocalSettings.php\n@@ -0,0 +1,129 @@\n+<?php\n+# This file was automatically generated by the MediaWiki 1.19.0\n+# installer. If you make manual changes, please keep track in case you\n+# need to recreate them later.\n+#\n+# See includes/DefaultSettings.php for all configurable settings\n+# and their default values, but don't forget to make changes in _this_\n+# file, not there.\n+#\n+# Further documentation for configuration settings may be found at:\n+# http://www.mediawiki.org/wiki/Manual:Configuration_settings\n+\n+# Protect against web entry\n+if ( !defined( 'MEDIAWIKI' ) ) {\n+\texit;\n+}\n+\n+## Uncomment this to disable output compression\n+# $wgDisableOutputCompression = true;\n+\n+$wgSitename      = \"Git-MediaWiki-Test\";\n+$wgMetaNamespace = \"Git-MediaWiki-Test\";\n+\n+## The URL base path to the directory containing the wiki;\n+## defaults for all runtime URL paths are based off of this.\n+## For more information on customizing the URLs please see:\n+## http://www.mediawiki.org/wiki/Manual:Short_URL\n+$wgScriptPath       = \"@WG_SCRIPT_PATH@\";\n+$wgScriptExtension  = \".php\";\n+\n+## The protocol and server name to use in fully-qualified URLs\n+$wgServer           = \"@WG_SERVER@\";\n+\n+## The relative URL path to the skins directory\n+$wgStylePath        = \"$wgScriptPath/skins\";\n+\n+## The relative URL path to the logo.  Make sure you change this from the default,\n+## or else you'll overwrite your logo when you upgrade!\n+$wgLogo             = \"$wgStylePath/common/images/wiki.png\";\n+\n+## UPO means: this is also a user preference option\n+\n+$wgEnableEmail      = true;\n+$wgEnableUserEmail  = true; # UPO\n+\n+$wgEmergencyContact = \"apache@localhost\";\n+$wgPasswordSender   = \"apache@localhost\";\n+\n+$wgEnotifUserTalk      = false; # UPO\n+$wgEnotifWatchlist     = false; # UPO\n+$wgEmailAuthentication = true;\n+\n+## Database settings\n+$wgDBtype           = \"sqlite\";\n+$wgDBserver         = \"\";\n+$wgDBname           = \"wikidb\";\n+$wgDBuser           = \"\";\n+$wgDBpassword       = \"\";\n+\n+# SQLite-specific settings\n+$wgSQLiteDataDir    = \"@WG_SQLITE_DATADIR@\";\n+\n+\n+## Shared memory settings\n+$wgMainCacheType    = CACHE_NONE;\n+$wgMemCachedServers = array();\n+\n+## To enable image uploads, make sure the 'images' directory\n+## is writable, then set this to true:\n+$wgEnableUploads  = false;\n+$wgUseImageMagick = true;\n+$wgImageMagickConvertCommand =\"@CONVERT@\";\n+\n+# InstantCommons allows wiki to use images from http://commons.wikimedia.org\n+$wgUseInstantCommons  = false;\n+\n+## If you use ImageMagick (or any other shell command) on a\n+## Linux server, this will need to be set to the name of an\n+## available UTF-8 locale\n+$wgShellLocale = \"en_US.utf8\";\n+\n+## If you want to use image uploads under safe mode,\n+## create the directories images/archive, images/thumb and\n+## images/temp, and make them all writable. Then uncomment\n+## this, if it's not already uncommented:\n+#$wgHashedUploadDirectory = false;\n+\n+## Set $wgCacheDirectory to a writable directory on the web server\n+## to make your wiki go slightly faster. The directory should not\n+## be publically accessible from the web.\n+#$wgCacheDirectory = \"$IP/cache\";\n+\n+# Site language code, should be one of the list in ./languages/Names.php\n+$wgLanguageCode = \"en\";\n+\n+$wgSecretKey = \"1c912bfe3519fb70f5dc523ecc698111cd43d81a11c585b3eefb28f29c2699b7\";\n+#$wgSecretKey = \"@SECRETKEY@\";\n+\n+\n+# Site upgrade key. Must be set to a string (default provided) to turn on the\n+# web installer while LocalSettings.php is in place\n+$wgUpgradeKey = \"ddae7dc87cd0a645\";\n+\n+## Default skin: you can change the default skin. Use the internal symbolic\n+## names, ie 'standard', 'nostalgia', 'cologneblue', 'monobook', 'vector':\n+$wgDefaultSkin = \"vector\";\n+\n+## For attaching licensing metadata to pages, and displaying an\n+## appropriate copyright notice / icon. GNU Free Documentation\n+## License and Creative Commons licenses are supported so far.\n+$wgRightsPage = \"\"; # Set to the title of a wiki page that describes your license/copyright\n+$wgRightsUrl  = \"\";\n+$wgRightsText = \"\";\n+$wgRightsIcon = \"\";\n+\n+# Path to the GNU diff3 utility. Used for conflict resolution.\n+$wgDiff3 = \"/usr/bin/diff3\";\n+\n+# Query string length limit for ResourceLoader. You should only set this if\n+# your web server has a query string length limit (then set it to that limit),\n+# or if you have suhosin.get.max_value_length set in php.ini (then set it to\n+# that value)\n+$wgResourceLoaderMaxQueryLength = -1;\n+\n+\n+\n+# End of automatically generated settings.\n+# Add more configuration options below.\n+\ndiff --git a/t/install-wiki/wikidb.sqlite b/t/install-wiki/wikidb.sqlite\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..809047334bf15891de943b480171beb2558f7cb8\nGIT binary patch\nliteral 210944\n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\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/test-gitmw-lib.sh b/t/test-gitmw-lib.sh\nnew file mode 100755\nindex 0000000..b1023d7\n--- /dev/null\n+++ b/t/test-gitmw-lib.sh\n@@ -0,0 +1,147 @@\n+#\n+# CONFIGURATION VARIABLES\n+# You might want to change those ones ...\n+#\n+WIKI_DIR_NAME=\"wiki\"            # Name of the wiki's directory\n+WIKI_DIR_INST=\"/var/www\"        # Directory of the web server\n+TMP=\"/tmp\"                      # Temporary directory for downloads\n+                                # Absolute address needed!\n+SERVER_ADDR=\"localhost\"         # Web server's address\n+\n+#\n+# CONFIGURATION\n+# You should not change those ones unless you know what you to\n+#\n+# Do not change the variables below\n+MW_VERSION=\"mediawiki-1.19.0\"\n+DB_FILE=\"wikidb.sqlite\"\n+FILES_FOLDER=\"install-wiki\"\n+WIKI_ADMIN=\"WikiAdmin\"\n+WIKI_PASSW=\"AdminPass\"\n+\n+fail () {\n+\techo \"$1\"\n+\texit 1\n+}\n+\n+\n+\n+# Install a wiki in your web server directory.\n+wiki_install () {\n+\n+\t# Copy the generic LocalSettings.php in the web server's directory\n+\t# And modify parameters according to the ones set at the top\n+\t# of this script.\n+\t# Note that LocalSettings.php is never modified.\n+\tif [ ! -f \"$FILES_FOLDER/LocalSettings.php\" ] ; then\n+\t\tfail \"Can't find $FILES_FOLDER/LocalSettings.php \" \\\n+\t\t\t\"in the current folder.\n+\t\tPlease run the script inside its folder.\"\n+\tfi\n+\tcp \"$FILES_FOLDER/LocalSettings.php\" \\\n+\t\t\"$FILES_FOLDER/LocalSettings-tmp.php\" ||\n+\t\tfail \"Unable to copy $FILES_FOLDER/LocalSettings.php \" \\\n+\t\t\"to $FILES_FOLDER/LocalSettings-tmp.php\"\n+\n+\t# Parse and set the LocalSettings file of the user according to the\n+\t# CONFIGURATION VARIABLES section at the beginning of this script\n+\tfile_swap=\"$FILES_FOLDER/LocalSettings-swap.php\"\n+\tsed \"s,@WG_SCRIPT_PATH@,/$WIKI_DIR_NAME,\" \\\n+\t\t\"$FILES_FOLDER/LocalSettings-tmp.php\" > \"$file_swap\"\n+\tmv \"$file_swap\" \"$FILES_FOLDER/LocalSettings-tmp.php\"\n+\tsed \"s,@WG_SERVER@,http://$SERVER_ADDR,\" \\\n+\t\t\"$FILES_FOLDER/LocalSettings-tmp.php\" > \"$file_swap\"\n+\tmv \"$file_swap\" \"$FILES_FOLDER/LocalSettings-tmp.php\"\n+\tsed \"s,@WG_SQLITE_DATADIR@,$TMP,\" \\\n+\t\t\"$FILES_FOLDER/LocalSettings-tmp.php\" > \"$file_swap\"\n+\tmv \"$file_swap\" \"$FILES_FOLDER/LocalSettings-tmp.php\"\n+\n+\tmkdir -p \"$WIKI_DIR_INST/$WIKI_DIR_NAME\"\n+\tif [ ! -d \"$WIKI_DIR_INST/$WIKI_DIR_NAME\" ] ; then\n+\t\tfail \"Folder $WIKI_DIR_INST/$WIKI_DIR_NAME doesn't exist. Please create it\n+\t\tand launch the script again.\"\n+\tfi\n+\n+\tmv \"$FILES_FOLDER/LocalSettings-tmp.php\" \\\n+\t\t\"$WIKI_DIR_INST/$WIKI_DIR_NAME/LocalSettings.php\" ||\n+\t\tfail \"Unable to move $FILES_FOLDER/LocalSettings-tmp.php\" \\\n+\t\t\"in $WIKI_DIR_INST/$WIKI_DIR_NAME\"\n+\techo \"File $FILES_FOLDER/LocalSettings.php is set in $WIKI_DIR_INST/$WIKI_DIR_NAME\"\n+\n+\tchmod ugo+w \"$FILES_FOLDER/$DB_FILE\"\n+\treset_db_wiki \".\"\n+\n+\t# Fetch MediaWiki's archive if not already present in the TMP directory\n+\tcd \"$TMP\"\n+\tif [ ! -f \"$MW_VERSION.tar.gz\" ] ; then\n+\t\techo \"Downloading $MW_VERSION sources ...\"\n+\t\twget http://download.wikimedia.org/mediawiki/1.19/mediawiki-1.19.0.tar.gz ||\n+\t\t\tfail \"Unable to download\" \\\n+\t\t\t\"http://download.wikimedia.org/mediawiki/1.19/mediawiki-1.19.0.tar.gz.\n+\t\tPlease fix your connection and launch the script again.\"\n+\tfi\n+\ttar xfz \"$MW_VERSION.tar.gz\"\n+\techo \"$MW_VERSION.tar.gz downloaded in `pwd`. You can delete it later if you want.\"\n+\n+\t# Copy the files of MediaWiki wiki in the web server's directory.\n+\tcd \"$MW_VERSION\"\n+\tcp -Rf * \"$WIKI_DIR_INST/$WIKI_DIR_NAME/\" ||\n+\t\tfail \"Unable to copy WikiMedia's files from `pwd` to $WIKI_DIR_INST/$WIKI_DIR_NAME\"\n+\n+\tset_admin_wiki\n+\n+\techo \"Your wiki has been installed. You can check it at http://$SERVER_ADDR/$WIKI_DIR_NAME\"\n+}\n+\n+# Copy the initial database of the wiki over the actual one.\n+# Argument $1 is the relative path to the folder $FILES_FOLDER\n+#\n+# Warning: This function should be not called by user. This is a private\n+# function used by wiki_install and wiki_delete\n+reset_db_wiki () {\n+\n+\t# Copy initial database of the wiki\n+\tif [ ! -f \"$1/$FILES_FOLDER/$DB_FILE\" ] ; then\n+\t\tfail \"Can't find $1/$FILES_FOLDER/$DB_FILE in the current folder.\"\n+\tfi\n+\tcp --preserve=mode,ownership \"$1/$FILES_FOLDER/$DB_FILE\" \"$TMP\" ||\n+\t\tfail \"Can't copy $1/$FILES_FOLDER/$DB_FILE in $TMP\"\n+\techo \"File $FILES_FOLDER/$DB_FILE is set in $TMP\"\n+}\n+\n+# Set the admin WikiAdmin with password AdminPass in the database.\n+#\n+# Warning: This function should be not called by user. This is a private\n+# function used by wiki_install and wiki_delete\n+set_admin_wiki () {\n+\n+\t#Add the admin\n+\tmy_pwd=\"`pwd`\"\n+\tcd \"$WIKI_DIR_INST/$WIKI_DIR_NAME/maintenance/\"\n+\tphp changePassword.php --user=\"$WIKI_ADMIN\" --password=\"$WIKI_PASSW\" ||\n+\t\tfail \"Unable to add an admin with the script $WIKI_DIR_INST/$WIKI_DIR_NAME/maintenance/\n+\tchangePassword.php. Check you have the perms to do it.\"\n+\techo \"Admin \\\"$WIKI_ADMIN\\\" has password \\\"$WIKI_PASSW\\\"\"\n+\tcd \"$my_pwd\"\n+}\n+\n+# Reset the database of the wiki and the password of the admin\n+#\n+# Warning: This function must be called only in a subdirectory of t/ directory\n+wiki_reset () {\n+\treset_db_wiki \"..\"\n+\tset_admin_wiki\n+}\n+\n+# Delete the wiki created in the web server's directory and all its content\n+# saved in the database.\n+wiki_delete () {\n+\t# Delete the wiki's directory.\n+\trm -rf \"$WIKI_DIR_INST/$WIKI_DIR_NAME\" ||\n+\t\tfail \"Wiki's directory $WIKI_DIR_INST/\" \\\n+\t\t\"$WIKI_DIR_NAME could not be deleted\"\n+\n+\t# Delete the wiki's SQLite database\n+\trm -f \"$TMP/$DB_FILE\" || fail \"Database $TMP/$DB_FILE could not be deleted.\"\n+}\n+\ndiff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh\nold mode 100644\nnew mode 100755\ndiff --git a/t/test-lib.sh b/t/test-lib.sh\nold mode 100644\nnew mode 100755\n-- \n1.7.10.2.568.g4c26a3a\n"},{"id":"192649","messageId":"1338547317-26088-2-git-send-email-guillaume.sasdy@ensimag.imag.fr","threadId":"30658","inReplyTo":"1338547317-26088-1-git-send-email-guillaume.sasdy@ensimag.imag.fr","subject":"[PATCH 2/3] Test environment of git-remote-mw","fromName":"Guillaume Sasdy","fromEmail":"guillaume.sasdy@ensimag.imag.fr","sentAt":"2012-06-01T10:41:56Z","receivedAt":"2012-06-01T10:41:56Z","isPatch":true,"sender":{"key":"guillaume.sasdy@ensimag.imag.fr","avatar":null},"body":"From: Charles Roussel <charles.roussel@ensimag.fr>\n\nIn order to test git-remote-mediawiki, we need a package of functions\nto manage a MediaWiki: edit a page, remove a page, fetch a page,\nfetch all pages on a given wiki.\n\nWe also need functions to compare the content of directories.\n\nSigned-off-by: Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>\nSigned-off-by: Simon Cathebras <Simon.Cathebras@ensimag.imag.fr>\nSigned-off-by: Simon Perrat <Simon.Perrat@ensimag.imag.fr>\nSigned-off-by: Charles Roussel <Charles.Roussel@ensimag.imag.fr>\nSigned-off-by: Julien Khayat <Julien.Khayat@ensimag.imag.fr>\n---\n t/test-gitmw-lib.sh | 124 ++++++++++++++++++++++++++++++++++++---\n t/test-gitmw.pl     | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 280 insertions(+), 8 deletions(-)\n create mode 100755 t/test-gitmw.pl\n\ndiff --git a/t/test-gitmw-lib.sh b/t/test-gitmw-lib.sh\nindex b1023d7..d7c7459 100755\n--- a/t/test-gitmw-lib.sh\n+++ b/t/test-gitmw-lib.sh\n@@ -1,27 +1,135 @@\n+# Copyright (C) 2012\n+#     Charles Roussel <charles.roussel@ensimag.imag.fr>\n+#     Simon Cathebras <simon.cathebras@ensimag.imag.fr>\n+#     Julien Khayat <julien.khayat@ensimag.imag.fr>\n+#     Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>\n+#     Simon Perrat <simon.perrat@ensimag.imag.fr>\n+#     Matthieu Moy <matthieu.moy@imag.fr>\n+# License: GPL v2 or later\n+\n #\n # CONFIGURATION VARIABLES\n-# You might want to change those ones ...\n+# You might want to change these ones\n #\n WIKI_DIR_NAME=\"wiki\"            # Name of the wiki's directory\n WIKI_DIR_INST=\"/var/www\"        # Directory of the web server\n TMP=\"/tmp\"                      # Temporary directory for downloads\n-                                # Absolute address needed!\n+                                # Absolute path required!\n SERVER_ADDR=\"localhost\"         # Web server's address\n \n-#\n # CONFIGURATION\n-# You should not change those ones unless you know what you to\n+# You should not change these ones unless you know what you do\n #\n-# Do not change the variables below\n MW_VERSION=\"mediawiki-1.19.0\"\n DB_FILE=\"wikidb.sqlite\"\n FILES_FOLDER=\"install-wiki\"\n WIKI_ADMIN=\"WikiAdmin\"\n WIKI_PASSW=\"AdminPass\"\n \n-fail () {\n-\techo \"$1\"\n-\texit 1\n+# wiki_getpage <page_name> <dest_path>\n+#\n+# Fetch a page <page_name> from the wiki and copy its content\n+# into directory <dest_path>.\n+wiki_getpage () {\n+\t../test-gitmw.pl get_page -p \"$1\" \"$2\"\n+}\n+\n+# wiki_delete_page <page_name>\n+#\n+# Delete the page <page_name> on the wiki.\n+wiki_delete_page () {\n+\t../test-gitmw.pl delete_page -p \"$1\"\n+}\n+\n+# wiki_edit_page <page_name> <page_content> <page_append>\n+#\n+# Edit a page <wiki_page> on the wiki with content <wiki_content>\n+# If <wiki_append> == true the content will be appended\n+# If the page doesn't exist, it is created.\n+wiki_editpage () {\n+\t../test-gitmw.pl edit_page -p \"$1\" \"$2\" \"$3\"\n+}\n+\n+# git_content <dir_1> <dir_2>\n+#\n+# Compare the contents of directories <dir_1> and <dir_2> with diff\n+# and exits with error 1 if they do not match. The program will\n+# not look into .git in the process.\n+git_content () {\n+\tresult=$(diff -r -b --exclude=\".git\" \"$1\" \"$2\")\n+\n+\tif echo $result | grep -q \">\" ; then\n+\t\techo \"test failed: files $1 and $2 do not match\"\n+\t\texit 1\n+\tfi\n+}\n+\n+# git_exist <rep_name> <file_name>\n+#\n+# Check the existence of <file_name> into the git repository\n+# <rep_name> and exits with error 1 if it is absent.\n+git_exist () {\n+\tresult=$(find \"$1\" -type f -name \"$2\")\n+\n+\tif ! echo $result | grep -q \"$2\" ; then\n+\t\techo \"test failed: file $2 does not exist in $1\"\n+\t\texit 1\n+\tfi\n+}\n+\n+# wiki_check_content <file_name> <page_name> \n+#\n+# Compares the contents of the file <file_name> and the wiki page\n+# <page_name> and exits with error 1 if they do not match.\n+wiki_check_content () {\n+\twiki_getpage \"$2\" .\n+\n+\tif test -f \"$2\".mw ; then\n+\t        git_content \"$1\" \"$2\".mw\n+\t\trm \"$2\".mw\n+\telse\n+\t\tdie \"ERROR: file $2 not found on wiki\"\n+\tfi\n+}\n+\n+# wiki_page_exist <page_name>\n+#\n+# Check the existence of the page <page_name> on the wiki and exits\n+# with error if it is absent from it.\n+wiki_page_exist () {\n+\twiki_getpage \"$1\" .\n+\n+\tif test -f \"$1\".mw ; then\n+\t\techo \"test failed: file $1 not found on wiki\"\n+\t\texit 1\n+\telse \n+\t\trm \"$1\".mw\n+\tfi\n+}\n+\n+# wiki_getallpagename\n+# \n+# Fetch the name of each page on the wiki.\n+wiki_getallpagename () {\n+\t../test-gitmw.pl \"getallpagename\" -p\n+}\n+\n+# wiki_getallpage <dest_dir>\n+#\n+# Fetch all the pages from the wiki and place them in the directory\n+# <dest_dir>.\n+wiki_getallpage () {\n+\twiki_getallpagename\n+\tmkdir -p \"$1\"\n+\twhile read -r line; do\n+\t\twiki_getpage \"$line\" $1;\n+\tdone < all.txt\n+}\n+\n+fail()\n+{\n+    echo \"$1\"\n+    exit 1\n }\n \n \ndiff --git a/t/test-gitmw.pl b/t/test-gitmw.pl\nnew file mode 100755\nindex 0000000..bf71485\n--- /dev/null\n+++ b/t/test-gitmw.pl\n@@ -0,0 +1,164 @@\n+#!/usr/bin/perl -w\n+# Copyright (C) 2012\n+#     Charles Roussel <charles.roussel@ensimag.imag.fr>\n+#     Simon Cathebras <simon.cathebras@ensimag.imag.fr>\n+#     Julien Khayat <julien.khayat@ensimag.imag.fr>\n+#     Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>\n+#     Simon Perrat <simon.perrat@ensimag.imag.fr>\n+#     Matthieu Moy <matthieu.moy@imag.fr>\n+# License: GPL v2 or later\n+\n+# Usage:\n+#       ./test-gitmw.pl <command> [argument]*\n+# Execute in terminal using the name of the function to call as first\n+# parameter, and the function's arguments as following parameters\n+#\n+# Example:\n+#     ./test-gitmw.pl \"get_page\" foo .\n+# will call <wiki_getpage> with arguments <foo> and <.>\n+#\n+# Available functions are:\n+#     \"get_page\"\n+#     \"delete_page\"\n+#     \"edit_page\"\n+#     \"getallpagename\"\n+\n+use MediaWiki::API;\n+use Switch;\n+# URL of the wiki used for the tests\n+my $wiki_url=\"http://localhost/wiki/api.php\";\n+my $wiki_admin='WikiAdmin';\n+my $wiki_admin_pass='AdminPass';\n+my $mw = MediaWiki::API->new;\n+$mw->{config}->{api_url} = $wiki_url;\n+\n+# wiki_login <name> <password>\n+#\n+# Logs the user with <name> and <password> in the global variable\n+# of the mediawiki $mw\n+sub wiki_login {\n+\t$mw->login( { lgname => \"$_[0]\",lgpassword => \"$_[1]\" } )\n+                || die \"getpage: login failed\";\n+}\n+\n+# wiki_getpage <wiki_page> <dest_path>\n+#\n+# fetch a page <wiki_page> from the wiki referenced in the global variable\n+# $mw and copies its content in directory dest_path\n+sub wiki_getpage {\n+\tmy $pagename = $_[0];\n+\tmy $destdir = $_[1];\n+\t\n+\tmy $page = $mw->get_page( { title => $pagename } );\n+\tif (!defined($page)) {\n+\t\tdie \"getpage: wiki does not exist\";\n+\t}\n+\n+\tmy $content = $page->{'*'};\n+\tif (!defined($content)) {\n+\t\tdie \"getpage: page does not exist\";\n+\t}\n+\n+        # Replace spaces by underscore in the page name\n+\t$pagename=~s/\\ /_/;\n+\topen(my $file, \">$destdir/$pagename.mw\");\n+\tprint $file \"$content\";\n+\tclose ($file);\n+}\n+\n+# wiki_delete_page <page_name>\n+#\n+# delete the page with name <page_name> from the wiki referenced\n+# in the global variable $mw\n+sub wiki_delete_page {\n+\tmy $pagename = $_[0];\n+\n+\tmy $exist=$mw->get_page({title => $pagename});\n+\n+\tif (defined($exist->{'*'})){\n+\t\t$mw->edit({ action => 'delete',\n+\t\t\t        title => $pagename})\n+\t\t|| die $mw->{error}->{code} . \": \" . $mw->{error}->{details};\n+\t}\n+        else{\n+\t\tdie \"no page with such name found: $pagename\\n\";\n+\t}\n+}\n+\n+# wiki_editpage <wiki_page> <wiki_content> <wiki_append>\n+#\n+# Edit a page named <wiki_page> with content <wiki_content> on the wiki\n+# referenced with the global variable $mw\n+# If <wiki_append> == true : append <wiki_content> at the end of the actual\n+# content of the page <wiki_page>\n+# If <wik_page> doesn't exist, that page is created with the <wiki_content>\n+sub wiki_editpage {\n+\tmy $wiki_page = $_[0];\n+\tmy $wiki_content = $_[1];\n+\tmy $wiki_append = $_[2];\n+\n+\tmy $append = 0;\n+\tif (defined($wiki_append) && $wiki_append eq 'true') {\n+\t\t$append=1;\n+\t}\n+\n+\tmy $previous_text =\"\";\n+\n+\tif ($append) {\n+\tmy $ref = $mw->get_page( { title => $wiki_page } );\n+\t\t$previous_text = $ref->{'*'};\n+\t}\n+\n+\tmy $text = $wiki_content;\n+\tif (defined($previous_text)) {\n+\t\t$text=\"$previous_text$text\";\n+\t}\n+\t$mw->edit( { action => 'edit', title => $wiki_page, text => \"$text\"} );\n+}\n+\n+# wiki_getallpagename\n+#\n+# Fetch all pages of the wiki referenced by the global variable $mw\n+# and print the names of each one in the file all.txt with a new line\n+# (\"\\n\") between these.\n+sub wiki_getallpagename {\n+        # fetch the pages of the wiki\n+\t$mw->list ( { action => 'query',\n+\t\t\tlist => 'allpages',\n+\t\t\t#cmtitle => \"Category:Surnames\",\n+\t\t\t#cmnamespace => 0,\n+\t\t\tcmlimit=> 500 },\n+\t\t{ max => 4, hook => \\&cat_names } )\n+\t        || die $mw->{error}->{code}.\": \".$mw->{error}->{details};\n+\n+\t# print the name of each page\n+\tsub cat_names {\n+\t\tmy ($ref) = @_;\n+\n+\t\topen(my $file, \">all.txt\");\n+\t\tforeach (@$ref) {\n+\t\t\tprint $file \"$_->{title}\\n\";\n+\t\t}\n+\t\tclose ($file);\n+\t}\n+}\n+\n+# Main part of this script: parse the command line arguments\n+# and select which function to execute\n+my $fct_to_call = shift;\n+my $login = $ARGV[0];\n+\n+if ($login eq \"-p\")\n+{\n+\t&wiki_login($wiki_admin,$wiki_admin_pass);\n+\tshift;\n+}\n+\n+switch ($fct_to_call) {\n+\tcase \"get_page\" { &wiki_getpage($ARGV[0], $ARGV[1])}\n+\tcase \"delete_page\" { &wiki_delete_page($ARGV[0])}\n+\tcase \"edit_page\" { &wiki_editpage($ARGV[0], $ARGV[1], $ARGV[2])}\n+\tcase \"getallpagename\" { &wiki_getallpagename()}\n+\telse{ die(\"test-gitmw.pl ERROR: wrong argument\")}\n+}\n+\n-- \n1.7.10.2.568.g4c26a3a\n"},{"id":"192650","messageId":"1338547317-26088-3-git-send-email-guillaume.sasdy@ensimag.imag.fr","threadId":"30658","inReplyTo":"1338547317-26088-1-git-send-email-guillaume.sasdy@ensimag.imag.fr","subject":"[PATCH 3/3] Tests file for git-remote-mediawiki","fromName":"Guillaume Sasdy","fromEmail":"guillaume.sasdy@ensimag.imag.fr","sentAt":"2012-06-01T10:41:57Z","receivedAt":"2012-06-01T10:41:57Z","isPatch":true,"sender":{"key":"guillaume.sasdy@ensimag.imag.fr","avatar":null},"body":"From: Charles Roussel <charles.roussel@ensimag.fr>\n\nThose scripts test the functions of git-remote-mediawiki.\nt9360: simple test case for git clone.\nt9361: simple test cases for git pull (add page, edit page, delete page) and git push (add file, edit file, delete file).\n\nSigned-off-by: Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>\nSigned-off-by: Simon Cathebras <Simon.Cathebras@ensimag.imag.fr>\nSigned-off-by: Simon Perrat <Simon.Perrat@ensimag.imag.fr>\nSigned-off-by: Charles Roussel <Charles.Roussel@ensimag.imag.fr>\nSigned-off-by: Julien Khayat <Julien.Khayat@ensimag.imag.fr>\n---\n t/t9360-git-mediawiki.sh |  49 +++++++++++++++\n t/t9361-git-mediawiki.sh | 156 +++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 205 insertions(+)\n create mode 100755 t/t9360-git-mediawiki.sh\n create mode 100755 t/t9361-git-mediawiki.sh\n\ndiff --git a/t/t9360-git-mediawiki.sh b/t/t9360-git-mediawiki.sh\nnew file mode 100755\nindex 0000000..57e05d8\n--- /dev/null\n+++ b/t/t9360-git-mediawiki.sh\n@@ -0,0 +1,49 @@\n+#!/bin/sh\n+#\n+# Copyright (C) 2012\n+#     Charles Roussel <charles.roussel@ensimag.imag.fr>\n+#     Simon Cathebras <simon.cathebras@ensimag.imag.fr>\n+#     Julien Khayat <julien.khayat@ensimag.imag.fr>\n+#     Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>\n+#     Simon Perrat <simon.perrat@ensimag.imag.fr>\n+#     Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n+#\n+# License: GPL v2 or later\n+\n+# tests for git-remote-mediawiki\n+\n+test_description='Test the Git Mediawiki remote helper: git clone'\n+\n+. ./test-gitmw-lib.sh\n+. ./test-lib.sh\n+\n+if ! test_have_prereq PERL\n+then\n+\tskip_all='skipping gateway git-mw tests, perl not available'\n+\ttest_done\n+fi\n+\n+if [ ! -f /$GIT_BUILD_DIR/git-remote-mediawiki ];\n+then\n+\tskip_all='skipping gateway git-mw tests, no remote mediawiki for git found'\n+\ttest_done\n+fi\n+\n+if [ ! -d \"$WIKI_DIR_INST/$WIKI_DIR_NAME\" ] ;\n+then\n+\tskip_all='skipping gateway git-mw tests, no mediawiki found'\n+\ttest_done\n+fi\n+\n+test_expect_success 'git clone works with page added' '\n+\twiki_reset &&\n+\twiki_editpage foo \"hello_world\" false &&\n+\twiki_editpage bar \"hi everybody !\" false &&\n+\tgit clone mediawiki::http://localhost/wiki mw_dir &&\n+\twiki_getallpage ref_page &&\n+\tgit_content mw_dir ref_page &&\n+\twiki_delete_page foo &&\n+\twiki_delete_page bar\n+'\n+\n+test_done\ndiff --git a/t/t9361-git-mediawiki.sh b/t/t9361-git-mediawiki.sh\nnew file mode 100755\nindex 0000000..9dd7274\n--- /dev/null\n+++ b/t/t9361-git-mediawiki.sh\n@@ -0,0 +1,156 @@\n+#!/bin/sh\n+#\n+# Copyright (C) 2012\n+#     Charles Roussel <charles.roussel@ensimag.imag.fr>\n+#     Simon Cathebras <simon.cathebras@ensimag.imag.fr>\n+#     Julien Khayat <julien.khayat@ensimag.imag.fr>\n+#     Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>\n+#     Simon Perrat <simon.perrat@ensimag.imag.fr>\n+#     Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n+#\n+# License: GPL v2 or later\n+\n+# tests for git-remote-mediawiki\n+\n+test_description='Test the Git Mediawiki remote helper: git push and git pull simple test cases'\n+\n+. ./test-gitmw-lib.sh\n+. ./test-lib.sh\n+\n+if ! test_have_prereq PERL\n+then\n+\tskip_all='skipping gateway git-mw tests, perl not available'\n+\ttest_done\n+fi\n+\n+if [ ! -f /$GIT_BUILD_DIR/git-remote-mediawiki ];\n+then\n+\tskip_all='skipping gateway git-mw tests, no remote mediawiki for git found'\n+\ttest_done\n+fi\n+\n+if [ ! -d \"$WIKI_DIR_INST/$WIKI_DIR_NAME\" ] ;\n+then\n+\tskip_all='skipping gateway git-mw tests, no mediawiki found'\n+\ttest_done\n+fi\n+\n+# Create a new file foo.mw in a freshly cloned wiki. Commit and push\n+# this file and then check that all files of the repository are similar to\n+# the wiki pages.\n+test_expect_success 'git push works after adding a file .mw' \"\n+        wiki_reset &&\n+        git clone mediawiki::http://$SERVER_ADDR/$WIKI_DIR_NAME mw_dir &&\n+        wiki_getallpage ref_page &&\n+\n+        cd mw_dir &&\n+        test ! -f foo.mw && # foo.mw should not exist after wiki_reset &&\n+        touch foo.mw &&\n+        echo \\\"hello world\\\" >> foo.mw &&\n+        git add foo.mw &&\n+        git commit -m \\\"foo\\\" &&\n+        git push &&\n+        cd .. &&\n+\n+        rm -rf ref_page &&\n+        wiki_getallpage ref_page &&\n+        git_content mw_dir ref_page &&\n+        rm -rf ref_page &&\n+        rm -rf mw_dir\n+\"\n+\n+# Create a new page Foo in an empty wiki. Clone the wiki and edit\n+# the file foo.mw corresponding to the page Foo. Commit and push\n+# then check that all files of the repository are similar to the wiki\n+# pages.\n+test_expect_success 'git push works after editing a file .mw' \"\n+        # clone an empty wiki and add a Foo page\n+        wiki_reset &&\n+        wiki_editpage \\\"foo\\\" \\\"page just created before the git clone\\\" false &&\n+        git clone mediawiki::http://$SERVER_ADDR/$WIKI_DIR_NAME mw_dir &&\n+\n+        cd mw_dir &&\n+        echo \\\"new line added in the file foo.mw\\\" >> Foo.mw &&\n+        git commit -am \\\"edit file foo.mw\\\" &&\n+        git push &&\n+        cd .. &&\n+\n+        rm -rf ref_page &&\n+        wiki_getallpage ref_page &&\n+        git_content mw_dir ref_page &&\n+        rm -rf ref_page &&\n+        rm -rf mw_dir\n+\"\n+\n+# Clone a wiki with a page Foo. Remove the corresponding file from the\n+# repository. Check that the wiki page has been actually removed.\n+test_expect_failure 'git push works after deleting a file' \"\n+        wiki_reset &&\n+        wiki_editpage foo \\\"wiki page added before git clone\\\" false &&\n+        git clone mediawiki::http://$SERVER_ADDR/$WIKI_DIR_NAME mw_dir &&\n+\n+        cd mw_dir &&\n+        git rm Foo.mw &&\n+        git commit -am \\\"git rm delete the wiki page Foo.mw\\\" &&\n+        git push &&\n+        cd .. &&\n+\n+        rm -rf mw_dir &&\n+        test ! wiki_page_exist Foo\n+\"\n+\n+# Clone an empty wiki. Add a page on the wiki and pull. Check \n+# all files of the repository are similar to the wiki pages.\n+test_expect_success 'git pull works after adding a new wiki page' \"\n+        wiki_reset &&\n+        git clone mediawiki::http://$SERVER_ADDR/$WIKI_DIR_NAME mw_dir &&\n+        wiki_editpage foo \\\"page just created after the git clone\\\" false &&\n+\n+        cd mw_dir &&\n+        git pull &&\n+        cd .. &&\n+\n+        rm -rf ref_page &&\n+        wiki_getallpage ref_page &&\n+        git_content mw_dir ref_page &&\n+        rm -rf ref_page &&\n+        rm -rf mw_dir\n+\"\n+\n+# Clone a wiki with a page Foo. Edit the page foo on the wiki and pull.\n+# Check that all files of the repository are similar to the wiki pages.\n+test_expect_success 'git pull works after editing a wiki page' \"\n+        wiki_reset &&\n+        wiki_editpage foo \\\"page just created before the git clone\\\" false &&\n+        git clone mediawiki::http://$SERVER_ADDR/$WIKI_DIR_NAME mw_dir &&\n+        wiki_editpage foo \\\"new line added on the wiki\\\" true &&\n+\n+        cd mw_dir &&\n+        git pull &&\n+        cd .. &&\n+       \n+        rm -rf ref_page &&\n+        wiki_getallpage ref_page &&\n+        git_content mw_dir ref_page &&\n+        rm -rf ref_page\n+        rm -rf mw_dir\n+\"\n+\n+# Clone a wiki with a page Foo. Remove the wiki page and pull.\n+# Check that the corresponding file in the repository has been actually removed.\n+test_expect_failure 'git pull works after deleting a wiki page' \"\n+        wiki_reset &&\n+        wiki_editpage foo \\\"wiki page added before git clone\\\" false &&\n+        git clone mediawiki::http://$SERVER_ADDR/$WIKI_DIR_NAME mw_dir &&\n+\n+        cd mw_dir &&\n+        wiki_delete_page foo\n+        git pull &&\n+        test ! -f Foo.mw &&\n+        cd .. &&\n+\n+        rm -rf mw_dir\n+\"\n+\n+test_done\n+\n-- \n1.7.10.2.568.g4c26a3a\n"},{"id":"192654","messageId":"vpqmx4n9rq6.fsf@bauges.imag.fr","threadId":"30658","inReplyTo":"1338547317-26088-2-git-send-email-guillaume.sasdy@ensimag.imag.fr","subject":"Re: [PATCH 2/3] Test environment of git-remote-mw","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-06-01T11:49:53Z","receivedAt":"2012-06-01T11:49:53Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr> writes:\n\n>  # CONFIGURATION VARIABLES\n> -# You might want to change those ones ...\n> +# You might want to change these ones\n>  #\n>  WIKI_DIR_NAME=\"wiki\"            # Name of the wiki's directory\n>  WIKI_DIR_INST=\"/var/www\"        # Directory of the web server\n>  TMP=\"/tmp\"                      # Temporary directory for downloads\n> -                                # Absolute address needed!\n> +                                # Absolute path required!\n>  SERVER_ADDR=\"localhost\"         # Web server's address\n>  \n> -#\n>  # CONFIGURATION\n> -# You should not change those ones unless you know what you to\n> +# You should not change these ones unless you know what you do\n\nI already mentionned in in your v1, but these fixups do not belong to\nPATCH 2/3. You do not want reviewers to see your mistakes in PATCH 1/2\nand see the fix in PATCH 2/3.\n\n> +wiki_getpage () {\n> +\t../test-gitmw.pl get_page -p \"$1\" \"$2\"\n> +}\n\nAny reason why test-gitmw.pl and wiki_getpage have this slightly\ndifferent API? The perl version has a \"-p\" flag, and the shell command\nhas only positionnal arguments.\n\nI'd rather have a more uniform way to wrap calls to test-gitmw.pl in\nshell, like\n\nwiki_<something> () {\n\t../test-gitmw.pl <something> \"$@\"\n}\n\nThen, you probably want to move the API documentation (i.e. comments you\nput before the shell functions) in, or next to the Perl script, and\navoid repeating it in the shell.\n\n> +# git_content <dir_1> <dir_2>\n> +#\n> +# Compare the contents of directories <dir_1> and <dir_2> with diff\n> +# and exits with error 1 if they do not match. The program will\n> +# not look into .git in the process.\n> +git_content () {\n\nDidn't I already say that the naming was strange? A function that\ncompares something shouldn't be called just \"content\".\n\n> +\tresult=$(diff -r -b --exclude=\".git\" \"$1\" \"$2\")\n> +\n> +\tif echo $result | grep -q \">\" ; then\n\nWhy grep, when the exit status of diff tells you about the differences\nalready?\n\n> +# git_exist <rep_name> <file_name>\n> +#\n> +# Check the existence of <file_name> into the git repository\n> +# <rep_name> and exits with error 1 if it is absent.\n> +git_exist () {\n> +\tresult=$(find \"$1\" -type f -name \"$2\")\n> +\n> +\tif ! echo $result | grep -q \"$2\" ; then\n\nMissing quotes around $result.\n\nWhy do you need grep again? You just want to check whether \"$result\" is\nempty (test -z).\n\n> +\t\techo \"test failed: file $2 does not exist in $1\"\n> +\t\texit 1\n\ndie\n\n?\n\n> +wiki_page_exist () {\n> +\twiki_getpage \"$1\" .\n> +\n> +\tif test -f \"$1\".mw ; then\n> +\t\techo \"test failed: file $1 not found on wiki\"\n> +\t\texit 1\n\nlikewise.\n\n> +fail()\n> +{\n\nStyle: fail () {\n\nPlus, didn't we say \"die\" was already there for this?\n\n> +        # Replace spaces by underscore in the page name\n> +\t$pagename=~s/\\ /_/;\n\nIndent with space (didn't I already mention that?).\n\n> +my $login = $ARGV[0];\n> +\n> +if ($login eq \"-p\")\n\nFeels weird. If you're not sure it's a login, why call the variable\n$login?\n\nAny reason not to use Perl's option parsing?\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192664","messageId":"4FC8D501.20207@ensimag.imag.fr","threadId":"30658","inReplyTo":"vpqmx4n9rq6.fsf@bauges.imag.fr","subject":"Re: [PATCH 2/3] Test environment of git-remote-mw","fromName":"Simon.Cathebras","fromEmail":"simon.cathebras@ensimag.imag.fr","sentAt":"2012-06-01T14:43:13Z","receivedAt":"2012-06-01T14:43:13Z","isPatch":true,"sender":{"key":"simon.cathebras@ensimag.imag.fr","avatar":"https://avatars.githubusercontent.com/u/1764010?v=4"},"body":"On 01/06/2012 13:49, Matthieu Moy wrote:\n> Guillaume Sasdy<guillaume.sasdy@ensimag.imag.fr>  writes:\n>\n>>   # CONFIGURATION VARIABLES\n>> -# You might want to change those ones ...\n>> +# You might want to change these ones\n>>   #\n>>   WIKI_DIR_NAME=\"wiki\"            # Name of the wiki's directory\n>>   WIKI_DIR_INST=\"/var/www\"        # Directory of the web server\n>>   TMP=\"/tmp\"                      # Temporary directory for downloads\n>> -                                # Absolute address needed!\n>> +                                # Absolute path required!\n>>   SERVER_ADDR=\"localhost\"         # Web server's address\n>>\n>> -#\n>>   # CONFIGURATION\n>> -# You should not change those ones unless you know what you to\n>> +# You should not change these ones unless you know what you do\n> I already mentionned in in your v1, but these fixups do not belong to\n> PATCH 2/3. You do not want reviewers to see your mistakes in PATCH 1/2\n> and see the fix in PATCH 2/3.\nGot it. With the problem experienced yesterday, we had still this issue \nthis morning. It is now fixed :).\n>> +wiki_getpage () {\n>> +\t../test-gitmw.pl get_page -p \"$1\" \"$2\"\n>> +}\n> Any reason why test-gitmw.pl and wiki_getpage have this slightly\n> different API? The perl version has a \"-p\" flag, and the shell command\n> has only positionnal arguments.\nThe \"-p\" flag exists to specify if we have to use the admin login on \nwiki to do the command. For instance, here we fetch a page from the wiki \nwith Admin privilege.\nOthers arguments remains the same.\n> I'd rather have a more uniform way to wrap calls to test-gitmw.pl in\n> shell, like\n>\n> wiki_<something>  () {\n> \t../test-gitmw.pl<something>  \"$@\"\n> }\nDo you suggest we include the \"-p\" flag in <something> ?\nI agree for the use of \"$@\".\n>\n> Then, you probably want to move the API documentation (i.e. comments you\n> put before the shell functions) in, or next to the Perl script, and\n> avoid repeating it in the shell.\n>\nOk.\n>> +# git_content<dir_1>  <dir_2>\n>> +#\n>> +# Compare the contents of directories<dir_1>  and<dir_2>  with diff\n>> +# and exits with error 1 if they do not match. The program will\n>> +# not look into .git in the process.\n>> +git_content () {\n> Didn't I already say that the naming was strange? A function that\n> compares something shouldn't be called just \"content\".\nSorry, we misunderstood what you mean... Update is coming. What about \ngit_diff_directories ?\nBecause this shell function execute a special instance of diff, matching \ntwo directories and ignoring blank character.\n>> +\tresult=$(diff -r -b --exclude=\".git\" \"$1\" \"$2\")\n>> +\n>> +\tif echo $result | grep -q \">\" ; then\n> Why grep, when the exit status of diff tells you about the differences\n> already?\n>\nGood idea for the exit status.\n>> +# git_exist<rep_name>  <file_name>\n>> +#\n>> +# Check the existence of<file_name>  into the git repository\n>> +#<rep_name>  and exits with error 1 if it is absent.\n>> +git_exist () {\n>> +\tresult=$(find \"$1\" -type f -name \"$2\")\n>> +\n>> +\tif ! echo $result | grep -q \"$2\" ; then\n> Missing quotes around $result.\n>\n> Why do you need grep again? You just want to check whether \"$result\" is\n> empty (test -z).\nthis function is now erased from our code... Actually, it was really \nuseless...\n>> +\t\techo \"test failed: file $2 does not exist in $1\"\n>> +\t\texit 1\n> die\n>\n> ?\n>\n>> +wiki_page_exist () {\n>> +\twiki_getpage \"$1\" .\n>> +\n>> +\tif test -f \"$1\".mw ; then\n>> +\t\techo \"test failed: file $1 not found on wiki\"\n>> +\t\texit 1\n> likewise.\nWe were supposed to do it with the previous version.\nBut we are facing some difficulties using die function outside the test \nharness. We wanted to include the file \"test-lib.sh\" in our own script \n\"test-gitmw-lib.sh\" to use die. It doesn't work, because the harness \nexpect the file \"test-gitmw-lib.sh\" to be a test script. Wich is not the \ncase.\n\nDo you have any Idea about how to fix this problem ?\n>> +fail()\n>> +{\n> Style: fail () {\n>\n> Plus, didn't we say \"die\" was already there for this?\nAgree, see above.\n>> +        # Replace spaces by underscore in the page name\n>> +\t$pagename=~s/\\ /_/;\n> Indent with space (didn't I already mention that?).\n>\n>> +my $login = $ARGV[0];\n>> +\n>> +if ($login eq \"-p\")\n> Feels weird. If you're not sure it's a login, why call the variable\n> $login?\nChange on the way. renaming this variable \"is_login\". Is this ok for you ?\n> Any reason not to use Perl's option parsing?\nNot at all, we juste didn't thought about it.\n\n-- \nCATHEBRAS Simon\n\n2A-ENSIMAG\n\nFilière Ingéniérie des Systèmes d'Information\nMembre Bug-Buster\n"},{"id":"192708","messageId":"vpqipfa9ehx.fsf@bauges.imag.fr","threadId":"30658","inReplyTo":"4FC8D501.20207@ensimag.imag.fr","subject":"Re: [PATCH 2/3] Test environment of git-remote-mw","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-06-02T10:47:54Z","receivedAt":"2012-06-02T10:47:54Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"\"Simon.Cathebras\" <Simon.Cathebras@ensimag.imag.fr> writes:\n\n>>> +wiki_getpage () {\n>>> +\t../test-gitmw.pl get_page -p \"$1\" \"$2\"\n>>> +}\n>> Any reason why test-gitmw.pl and wiki_getpage have this slightly\n>> different API? The perl version has a \"-p\" flag, and the shell command\n>> has only positionnal arguments.\n> The \"-p\" flag exists to specify if we have to use the admin login on\n> wiki to do the command.\n\n(then, maybe --admin would be a better name?)\n\n> For instance, here we fetch a page from the wiki with Admin privilege.\n> Others arguments remains the same.\n\nWhat I don't understand is why you need the flexibility to choose\nbetween admin and non-admin on the Perl side, and you don't need in on\nthe shell side.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192804","messageId":"4FCCC26C.1050304@ensimag.imag.fr","threadId":"30658","inReplyTo":"vpqipfa9ehx.fsf@bauges.imag.fr","subject":"Re: [PATCH 2/3] Test environment of git-remote-mw","fromName":"Simon.Cathebras","fromEmail":"simon.cathebras@ensimag.imag.fr","sentAt":"2012-06-04T14:13:00Z","receivedAt":"2012-06-04T14:13:00Z","isPatch":true,"sender":{"key":"simon.cathebras@ensimag.imag.fr","avatar":"https://avatars.githubusercontent.com/u/1764010?v=4"},"body":"\n\nOn 02/06/2012 12:47, Matthieu Moy wrote:\n> \"Simon.Cathebras\"<Simon.Cathebras@ensimag.imag.fr>  writes:\n>\n>>>> +wiki_getpage () {\n>>>> +\t../test-gitmw.pl get_page -p \"$1\" \"$2\"\n>>>> +}\n>>> Any reason why test-gitmw.pl and wiki_getpage have this slightly\n>>> different API? The perl version has a \"-p\" flag, and the shell command\n>>> has only positionnal arguments.\n>> The \"-p\" flag exists to specify if we have to use the admin login on\n>> wiki to do the command.\n> (then, maybe --admin would be a better name?)\n>\nI am ok with this... It would be more understandable.\n>> For instance, here we fetch a page from the wiki with Admin privilege.\n>> Others arguments remains the same.\n> What I don't understand is why you need the flexibility to choose\n> between admin and non-admin on the Perl side, and you don't need in on\n> the shell side.\n>\nOn one hand, we need to be authentificated as an admin to do some wiki's\noperations, like deleting a page for instance. It is needed by the Perl.\nOn the other hand, we don't need it on the shell side because we believe\nthat we don't have to bother the user with some authentification\nconsideration.\nI mean, if I intend to delete the page <foo> from wiki, it is easier to\ncall 'wiki_delete_page foo', than  'wiki_delete_page --user=thingumy\n--pass=blahblah foo'.\nDoes it make sense ? If not, what do you think we should do ?\n\nSimon\n\n-- \nCATHEBRAS Simon\n\n2A-ENSIMAG\n\nFilière Ingéniérie des Systèmes d'Information\nMembre Bug-Buster\n"}]}