Add infrastructure

Add several tools to help with the extension development:

- Add .editorconfig file to set formatting options for the code editors.
- Add generateManifest.bash to generate the manifest.json file
  dynamically, from a template at templates/manifest.gjson. The
  manifest.gjson file can have lines defining what parts of the manifest
  are added for each target browser.
- Add release.bash to generate the extension ZIP files.
- Add Makefile to serve as a wrapper for the release.bash script.
- Add tagRelease.bash to help tag versions in Git accordingly.
- Add docs to explain all this new infrastructure (will need to be
  updated in the future with more details).

Change-Id: I698ffc59d0d2ec02b483935f7860e95760951a42
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..e5dd176
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,15 @@
+root = true
+
+[*]
+end_of_line = lf
+insert_final_line = true
+charset = utf-8
+
+[*.{sh,bash}]
+indent_style = space
+indent_size = 2
+switch_case_indent = true
+
+[*.{html,css,js,json}]
+indent_style = space
+indent_size = 2
diff --git a/.gitignore b/.gitignore
index 2d37dc9..125c39b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,3 @@
+out/
+src/manifest.json
 crowdin.yaml
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..3f174f1
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,12 @@
+.PHONY: all chromium-stable chromium-beta
+
+all: chromium-stable chromium-beta
+
+chromium-stable:
+	bash release.bash -c stable -b chromium
+
+chromium-beta:
+	bash release.bash -c beta -b chromium
+
+clean:
+	rm -rf out
diff --git a/README.md b/README.md
index d5e6fe3..a7bd3f9 100644
--- a/README.md
+++ b/README.md
@@ -13,3 +13,6 @@
 * All the users who use the extension every day and who trust the model of developing simple extensions which do not request any privacy-breaking permissions.
 * Alexander Simkin for the Russian translation.
 * BrowserStack for allowing me to use their awesome services in order to test the extension in multiple versions of Chrome and in different operating systems.
+
+## More documents
+* [For developers working on the extension](docs/development.md)
diff --git a/docs/development.md b/docs/development.md
new file mode 100644
index 0000000..1306a92
--- /dev/null
+++ b/docs/development.md
@@ -0,0 +1,8 @@
+# Development
+In order to work with the extension, take a look at
+[the docs](https://gerrit.avm99963.com/plugins/gitiles/infinitegforums/+/0991c69b3300b7c1e4b833bbb226f37bac7094c2/README.md)
+for this other extension that I developed. The infrastructure involved with this
+extension is very similar to the one for that extension.
+
+In the near future I will change the documentation for the other extension,
+which will allow me to update this article with more information.
diff --git a/generateManifest.bash b/generateManifest.bash
new file mode 100644
index 0000000..eaea8aa
--- /dev/null
+++ b/generateManifest.bash
@@ -0,0 +1,2 @@
+#!/bin/bash
+genmanifest -template templates/manifest.gjson -dest src/manifest.json "$@"
diff --git a/release.bash b/release.bash
new file mode 100644
index 0000000..94ab75a
--- /dev/null
+++ b/release.bash
@@ -0,0 +1,103 @@
+#!/bin/bash
+#
+# Generate release files (ZIP archives of the extension source code).
+
+# Prints help text
+function usage() {
+  cat <<END
+
+  Usage: $progname [--channel CHANNEL --browser BROWSER]
+
+  optional arguments:
+    -h, --help     show this help message and exit
+    -c, --channel  indicates the channel of the release. Can be "beta"
+                   or "stable". Defaults to "stable".
+    -b, --browser  indicates the target browser for the release. As of
+                   now it can only be "chromium", which is also the
+                   default value.
+
+END
+}
+
+# Updates manifest.json field
+function set_manifest_field() {
+  sed -i -E "s/\"$1\": \"[^\"]*\"/\"$1\": \"$2\"/" src/manifest.json
+}
+
+# Get options
+opts=$(getopt -l "help,channel:,browser:" -o "hc:b:" -n "$progname" -- "$@")
+eval set -- "$opts"
+
+channel=stable
+browser=chromium
+
+while true; do
+  case "$1" in
+    -h | --help)
+      usage
+      exit
+      ;;
+    -c | --channel)
+      channel="$2"
+      shift 2
+      ;;
+    -b | --browser)
+      browser="$2"
+      shift 2
+      ;;
+    *) break ;;
+  esac
+done
+
+if [[ $channel != "stable" && $channel != "beta" ]]; then
+  echo "channel parameter value is incorrect." >&2
+  usage
+  exit
+fi
+
+if [[ $browser != "chromium" ]]; then
+  echo "browser parameter value is incorrect." >&2
+  usage
+  exit
+fi
+
+echo "Started building release..."
+
+# First of all, generate the appropriate manifest.json file for the
+# target browser
+dependencies=(${browser})
+
+bash generateManifest.bash "${dependencies[@]}"
+
+# This is the version name which git gives us
+version=$(git describe --always --tags --dirty)
+
+# If the version name contains a hyphen then it isn't a release
+# version. This is also the case if it doesn't start with a "v".
+if [[ $version == *"-"* || $version != "v"* ]]; then
+  # As it isn't a release version, setting version number to 0 so it
+  # cannot be uploaded to the Chrome Web Store
+  set_manifest_field "version" "0"
+  set_manifest_field "version_name" "$version-$channel"
+else
+  # It is a release version, set the version fields accordingly.
+  set_manifest_field "version" "${version:1}"
+  set_manifest_field "version_name" "${version:1}-$channel"
+fi
+
+if [[ $channel == "beta" ]]; then
+  # Change manifest.json to label the release as beta
+  set_manifest_field "name" "__MSG_appBetaName__"
+fi
+
+# Create ZIP file for upload to the Chrome Web Store
+mkdir -p out
+rm -rf out/translateselectedtext-$version-$browser-$channel.zip
+(cd src &&
+  zip -rq ../out/translateselectedtext-$version-$browser-$channel.zip * \
+  -x "*/.git*" -x "*/\.DS_Store" -x "*/OWNERS")
+
+# Clean generated manifest.json file
+rm -f src/manifest.json
+
+echo "Done!"
diff --git a/tagRelease.bash b/tagRelease.bash
new file mode 100644
index 0000000..d639f70
--- /dev/null
+++ b/tagRelease.bash
@@ -0,0 +1,53 @@
+#!/bin/bash
+#
+# Tags the current git HEAD as a new version, passed via a flag.
+
+GITILES_REPO_URL="https://gerrit.avm99963.com/plugins/gitiles/translateselectedtext"
+
+# Prints help text
+function usage() {
+  cat <<END
+
+  Usage: $progname --version VERSION
+
+  required arguments:
+    -v, --version  the version of the new release (in the form vx)
+                   which wants to be tagged.
+
+  optional arguments:
+    -h, --help     show this help message and exit
+
+END
+}
+
+opts=$(getopt -l "help,version:" -o "hv:" -n "$progname" -- "$@")
+eval set -- "$opts"
+
+prevVersion=$(git describe --abbrev=0)
+nextVersion="null"
+
+while true; do
+  case "$1" in
+    -h | --help)
+      usage
+      exit
+      ;;
+    -v | --version)
+      nextVersion="$2"
+      shift 2
+      ;;
+    *) break ;;
+  esac
+done
+
+if [[ $nextVersion == "null" ]]; then
+  echo "version parameter value is incorrect." >&2
+  usage
+  exit
+fi
+
+commitMessage1="$nextVersion"
+commitMessage2="Changelog: $GITILES_REPO_URL/+log/refs/tags/$prevVersion..refs/tags/$nextVersion"
+git tag -a $nextVersion -m "$commitMessage1" -m "$commitMessage2"
+
+echo "Tag created. Now run \`git push --tags\` to push the tags to the server."
diff --git a/src/manifest.json b/templates/manifest.gjson
similarity index 87%
rename from src/manifest.json
rename to templates/manifest.gjson
index 9b8b494..5889bf3 100644
--- a/src/manifest.json
+++ b/templates/manifest.gjson
@@ -1,8 +1,9 @@
 {
   "manifest_version": 2,
-  "name": "__MSG_appBetaName__",
+  "name": "__MSG_appName__",
   "description": "__MSG_appDescription__",
-  "version": "0.8.1",
+  "version": "0",
+  "version_name": "dirty",
   "permissions": [
     "contextMenus",
     "storage",