Switch to external genmanifest tool

Until now, we were using a Go program included in this repo to generate
the manifest. This program is being used in other projects, so it got
moved to the gomodules/webext repo.

This change removes the local Go files and switches to the external
genmanifest tool.

Change-Id: Id6168282122ae53ecb9e20a296d2f223e66b9f25
diff --git a/docs/developers/set_up.md b/docs/developers/set_up.md
index a8e75ee..cd21e90 100644
--- a/docs/developers/set_up.md
+++ b/docs/developers/set_up.md
@@ -6,6 +6,8 @@
 with [Homebrew](https://brew.sh/) by running `brew install go`.
    - This is because the build script uses a Go program to generate the
    manifest.
+1. Install the genmanifest Go program. In order to do this, run
+`go install gomodules.avm99963.com/webext/genmanifest@latest`.
 1. [Install NPM](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm/).
 1. Now, you must clone the git repository to your device to retrieve the
 extension source code. To do that,
diff --git a/playbooks/lint/pre.yaml b/playbooks/lint/pre.yaml
index 13ccb60..964416f 100644
--- a/playbooks/lint/pre.yaml
+++ b/playbooks/lint/pre.yaml
@@ -1,4 +1,3 @@
 - hosts: all
   roles:
-    - role: ensure-go
-      go_version: 1.16
+    - role: ensure-genmanifest
diff --git a/roles/build-extension/tasks/main.yaml b/roles/build-extension/tasks/main.yaml
index 7759c47..6ca0225 100644
--- a/roles/build-extension/tasks/main.yaml
+++ b/roles/build-extension/tasks/main.yaml
@@ -3,4 +3,4 @@
     chdir: "{{ zuul.project.src_dir }}"
     target: "{{ make_target }}"
   environment:
-    PATH: /usr/local/go/bin:{{ ansible_env.PATH }}
+    PATH: "{{ ansible_env.HOME }}/go/bin:/usr/local/go/bin:{{ ansible_env.PATH }}"
diff --git a/tools/generateManifest.go b/tools/generateManifest.go
deleted file mode 100644
index 185f1c3..0000000
--- a/tools/generateManifest.go
+++ /dev/null
@@ -1,111 +0,0 @@
-package main
-
-import (
-  "bufio"
-  "flag"
-  "fmt"
-  "io"
-  "log"
-  "os"
-  "regexp"
-  "strings"
-)
-
-// Generates the manifest.json file according to the dependencies passed
-// via CLI arguments
-
-const (
-  manifestTemplate = "templates/manifest.gjson"
-)
-
-var beginningOfIfStatement = regexp.MustCompile(`^\s*#if defined\(([^\(\)]*)\)\s*$`)
-var endOfIfStatement = regexp.MustCompile(`^\s*#endif\s*$`)
-
-var (
-  quietMode = flag.Bool("quiet", false, "Quiet mode")
-  destFile  = flag.String("dest", "", "Destination file")
-)
-
-func FindWithCaseFolding(slice []string, val string) bool {
-  for _, item := range slice {
-    if strings.EqualFold(item, val) {
-      return true
-    }
-  }
-  return false
-}
-
-func WriteManifest(template io.Reader, dest io.Writer, dependencies []string) error {
-  level := 0
-  activeLevel := 0
-  scanner := bufio.NewScanner(template)
-  for scanner.Scan() {
-    line := scanner.Text()
-    considerLine := false
-    if m := beginningOfIfStatement.FindStringSubmatch(line); m != nil {
-      if level == activeLevel {
-        statementDeps := m[1]
-        deps := strings.Split(statementDeps, "||")
-        for _, dep := range deps {
-          dep = strings.TrimSpace(dep)
-          if FindWithCaseFolding(dependencies, dep) {
-            activeLevel++
-            break
-          }
-        }
-      }
-      level++
-    } else if m := endOfIfStatement.MatchString(line); m {
-      if activeLevel == level {
-        activeLevel--
-      }
-      level--
-    } else {
-      considerLine = level == activeLevel
-    }
-
-    if considerLine {
-      _, err := io.WriteString(dest, line + "\n")
-      if err != nil {
-        return fmt.Errorf("Can't write manifest: %v", err)
-      }
-    }
-  }
-
-  return nil
-}
-
-func main() {
-  log.SetPrefix("generateManifest: ")
-  log.SetFlags(0)
-
-  flag.Parse()
-  dependencies := flag.Args()
-
-  if len(dependencies) == 0 {
-    log.Fatalf("Pass the dependencies as arguments (for instance, run `go run generateManifest.go CHROMIUM`).")
-  }
-
-  if *destFile == "" {
-    log.Fatalf("Pass the destination file name via the -dest flag.")
-  }
-
-  template, err := os.Open(manifestTemplate)
-  if err != nil {
-    log.Fatalf("Couldn't open file %v: %v", manifestTemplate, err)
-  }
-  defer template.Close()
-
-  dest, err := os.Create(*destFile)
-  if err != nil {
-    log.Fatalf("Couldn't create file %v: %v", *destFile, err)
-  }
-  defer dest.Close()
-
-  err = WriteManifest(template, dest, dependencies)
-  if err != nil {
-    log.Fatalf("%v", err)
-  } else if !*quietMode {
-    log.Println("Manifest has been generated successfully")
-  }
-}
diff --git a/tools/generateManifest_test.go b/tools/generateManifest_test.go
deleted file mode 100644
index 57f2f56..0000000
--- a/tools/generateManifest_test.go
+++ /dev/null
@@ -1,79 +0,0 @@
-package main
-
-import (
-  "bytes"
-  "crypto/sha256"
-  "encoding/hex"
-  "io"
-  "os"
-  "testing"
-)
-
-type Manifest struct {
-  name string
-  templateFile string
-  expectedFile string
-  dependencies []string
-}
-
-func TestManifestConversions(t *testing.T) {
-  testManifests := []Manifest{
-    {
-      name: "ManifestSmall",
-      templateFile: "testdata/manifest_small1.gjson",
-      expectedFile: "testdata/manifest_small1_expected.json",
-      dependencies: []string{"AAA", "BBB", "D"},
-    },
-    {
-      name: "ManifestFrozenChromium",
-      templateFile: "testdata/manifest_frozen.gjson",
-      expectedFile: "testdata/manifest_frozen_chromium_expected.json",
-      dependencies: []string{"CHROMIUM"},
-    },
-    {
-      name: "ManifestFrozenGecko",
-      templateFile: "testdata/manifest_frozen.gjson",
-      expectedFile: "testdata/manifest_frozen_gecko_expected.json",
-      dependencies: []string{"GECKO"},
-    },
-  }
-
-  for _, m := range testManifests {
-    t.Run(m.name, func(t *testing.T) {
-      template, err := os.Open(m.templateFile)
-      if err != nil {
-        t.Fatalf("Can't open test file: %v", err)
-      }
-      defer template.Close()
-
-      expected, err := os.Open(m.expectedFile)
-      if err != nil {
-        t.Fatalf("Can't open expected file: %v", err)
-      }
-      defer expected.Close()
-
-      dest := bytes.NewBufferString("")
-
-      WriteManifest(template, dest, m.dependencies)
-      if err != nil {
-        t.Fatal(err)
-      }
-
-      h1 := sha256.New()
-      if _, err := io.Copy(h1, dest); err != nil {
-        t.Fatalf("Can't prepare sha256 sum of the result: %v", err)
-      }
-
-      h2 := sha256.New()
-      if _, err := io.Copy(h2, expected); err != nil {
-        t.Fatalf("Can't prepare sha256 sum of the expected file: %v", err)
-      }
-
-      sum1 := h1.Sum(nil)
-      sum2 := h2.Sum(nil)
-      if bytes.Compare(sum1, sum2) != 0 {
-        t.Fatalf("The expected manifest file (sha256: %v) differs from what we got (sha256: %v).", hex.EncodeToString(sum2), hex.EncodeToString(sum1))
-      }
-    })
-  }
-}
diff --git a/tools/testdata/manifest_frozen.gjson b/tools/testdata/manifest_frozen.gjson
deleted file mode 100644
index 8d93b2e..0000000
--- a/tools/testdata/manifest_frozen.gjson
+++ /dev/null
@@ -1,89 +0,0 @@
-{
-  "manifest_version": 2,
-  "name": "__MSG_appName__",
-  "version": "0",
-#if defined(CHROMIUM)
-  "version_name": "dirty",
-#endif
-  "description": "__MSG_appDescription__",
-  "icons": {
-    "512": "icons/512.png",
-    "128": "icons/128.png"
-  },
-  "content_scripts": [
-    {
-      "matches": ["https://support.google.com/s/community*"],
-      "js": ["common/content_scripts.js", "content_scripts/console_inject.js"]
-    },
-    {
-      "matches": ["https://support.google.com/s/community*"],
-      "js": ["common/content_scripts.js", "content_scripts/console_inject_start.js"],
-      "css": ["common/console.css"],
-      "run_at": "document_start"
-    },
-    {
-      "matches": ["https://support.google.com/*/threads*"],
-      "js": ["content_scripts/forum_inject.js"]
-    },
-    {
-      "matches": ["https://support.google.com/*/thread/*"],
-      "exclude_matches": ["https://support.google.com/s/community*", "https://support.google.com/*/thread/new*"],
-      "js": ["common/content_scripts.js", "content_scripts/thread_inject.js"],
-      "run_at": "document_end"
-    },
-    {
-      "matches": ["https://support.google.com/s/community*", "https://support.google.com/*/thread/*"],
-      "exclude_matches": ["https://support.google.com/*/thread/new*"],
-      "js": ["common/content_scripts.js", "common/cs_event_listener.js", "content_scripts/profileindicator_inject.js"]
-    },
-    {
-      "matches": ["https://support.google.com/*/profile/*"],
-      "js": ["common/content_scripts.js", "content_scripts/profile_inject.js"],
-      "css": ["common/forum.css"]
-    }
-  ],
-  "permissions": [
-    "https://support.google.com/s/community*",
-    "https://support.google.com/*/threads*",
-    "https://support.google.com/*/thread/*",
-    "storage"
-  ],
-  "web_accessible_resources": [
-    "injections/profileindicator_inject.js",
-    "injections/profileindicator_inject.css",
-    "injections/ccdarktheme.css",
-    "injections/batchlock_inject.js"
-  ],
-  "browser_action": {},
-#if defined(CHROMIUM)
-  "options_page": "options.html",
-#endif
-  "options_ui": {
-    "page": "options.html",
-#if defined(CHROMIUM)
-    "chrome_style": true,
-#endif
-#if defined(GECKO)
-    "browser_style": true,
-#endif
-    "open_in_tab": false
-  },
-  "background": {
-#if defined(CHROMIUM)
-    "persistent": false,
-#endif
-    "scripts": [
-      "common/common.js",
-      "background.js"
-    ]
-  },
-#if defined(GECKO)
-  "browser_specific_settings": {
-    "gecko": {
-      "id": "twpowertools@avm99963.com",
-      "strict_min_version": "57.0"
-    }
-  },
-#endif
-  "default_locale": "en"
-}
diff --git a/tools/testdata/manifest_frozen_chromium_expected.json b/tools/testdata/manifest_frozen_chromium_expected.json
deleted file mode 100644
index 2bd184b..0000000
--- a/tools/testdata/manifest_frozen_chromium_expected.json
+++ /dev/null
@@ -1,70 +0,0 @@
-{
-  "manifest_version": 2,
-  "name": "__MSG_appName__",
-  "version": "0",
-  "version_name": "dirty",
-  "description": "__MSG_appDescription__",
-  "icons": {
-    "512": "icons/512.png",
-    "128": "icons/128.png"
-  },
-  "content_scripts": [
-    {
-      "matches": ["https://support.google.com/s/community*"],
-      "js": ["common/content_scripts.js", "content_scripts/console_inject.js"]
-    },
-    {
-      "matches": ["https://support.google.com/s/community*"],
-      "js": ["common/content_scripts.js", "content_scripts/console_inject_start.js"],
-      "css": ["common/console.css"],
-      "run_at": "document_start"
-    },
-    {
-      "matches": ["https://support.google.com/*/threads*"],
-      "js": ["content_scripts/forum_inject.js"]
-    },
-    {
-      "matches": ["https://support.google.com/*/thread/*"],
-      "exclude_matches": ["https://support.google.com/s/community*", "https://support.google.com/*/thread/new*"],
-      "js": ["common/content_scripts.js", "content_scripts/thread_inject.js"],
-      "run_at": "document_end"
-    },
-    {
-      "matches": ["https://support.google.com/s/community*", "https://support.google.com/*/thread/*"],
-      "exclude_matches": ["https://support.google.com/*/thread/new*"],
-      "js": ["common/content_scripts.js", "common/cs_event_listener.js", "content_scripts/profileindicator_inject.js"]
-    },
-    {
-      "matches": ["https://support.google.com/*/profile/*"],
-      "js": ["common/content_scripts.js", "content_scripts/profile_inject.js"],
-      "css": ["common/forum.css"]
-    }
-  ],
-  "permissions": [
-    "https://support.google.com/s/community*",
-    "https://support.google.com/*/threads*",
-    "https://support.google.com/*/thread/*",
-    "storage"
-  ],
-  "web_accessible_resources": [
-    "injections/profileindicator_inject.js",
-    "injections/profileindicator_inject.css",
-    "injections/ccdarktheme.css",
-    "injections/batchlock_inject.js"
-  ],
-  "browser_action": {},
-  "options_page": "options.html",
-  "options_ui": {
-    "page": "options.html",
-    "chrome_style": true,
-    "open_in_tab": false
-  },
-  "background": {
-    "persistent": false,
-    "scripts": [
-      "common/common.js",
-      "background.js"
-    ]
-  },
-  "default_locale": "en"
-}
diff --git a/tools/testdata/manifest_frozen_gecko_expected.json b/tools/testdata/manifest_frozen_gecko_expected.json
deleted file mode 100644
index 49792d5..0000000
--- a/tools/testdata/manifest_frozen_gecko_expected.json
+++ /dev/null
@@ -1,73 +0,0 @@
-{
-  "manifest_version": 2,
-  "name": "__MSG_appName__",
-  "version": "0",
-  "description": "__MSG_appDescription__",
-  "icons": {
-    "512": "icons/512.png",
-    "128": "icons/128.png"
-  },
-  "content_scripts": [
-    {
-      "matches": ["https://support.google.com/s/community*"],
-      "js": ["common/content_scripts.js", "content_scripts/console_inject.js"]
-    },
-    {
-      "matches": ["https://support.google.com/s/community*"],
-      "js": ["common/content_scripts.js", "content_scripts/console_inject_start.js"],
-      "css": ["common/console.css"],
-      "run_at": "document_start"
-    },
-    {
-      "matches": ["https://support.google.com/*/threads*"],
-      "js": ["content_scripts/forum_inject.js"]
-    },
-    {
-      "matches": ["https://support.google.com/*/thread/*"],
-      "exclude_matches": ["https://support.google.com/s/community*", "https://support.google.com/*/thread/new*"],
-      "js": ["common/content_scripts.js", "content_scripts/thread_inject.js"],
-      "run_at": "document_end"
-    },
-    {
-      "matches": ["https://support.google.com/s/community*", "https://support.google.com/*/thread/*"],
-      "exclude_matches": ["https://support.google.com/*/thread/new*"],
-      "js": ["common/content_scripts.js", "common/cs_event_listener.js", "content_scripts/profileindicator_inject.js"]
-    },
-    {
-      "matches": ["https://support.google.com/*/profile/*"],
-      "js": ["common/content_scripts.js", "content_scripts/profile_inject.js"],
-      "css": ["common/forum.css"]
-    }
-  ],
-  "permissions": [
-    "https://support.google.com/s/community*",
-    "https://support.google.com/*/threads*",
-    "https://support.google.com/*/thread/*",
-    "storage"
-  ],
-  "web_accessible_resources": [
-    "injections/profileindicator_inject.js",
-    "injections/profileindicator_inject.css",
-    "injections/ccdarktheme.css",
-    "injections/batchlock_inject.js"
-  ],
-  "browser_action": {},
-  "options_ui": {
-    "page": "options.html",
-    "browser_style": true,
-    "open_in_tab": false
-  },
-  "background": {
-    "scripts": [
-      "common/common.js",
-      "background.js"
-    ]
-  },
-  "browser_specific_settings": {
-    "gecko": {
-      "id": "twpowertools@avm99963.com",
-      "strict_min_version": "57.0"
-    }
-  },
-  "default_locale": "en"
-}
diff --git a/tools/testdata/manifest_small1.gjson b/tools/testdata/manifest_small1.gjson
deleted file mode 100644
index 5027087..0000000
--- a/tools/testdata/manifest_small1.gjson
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-  "foo": "option",
-#if defined(AAA)
-  "bar": 1,
-    #endif                   
-#if defined(    BBB )
-  "count": 2,
-  #if defined(B || C)    
-  "mmm": {},
-#endif
-#if defined(C)
-  #if defined(D)  
-  "ok": true,
-#endif
-#endif
-#if defined(D)
-#if defined(C)
-  "ok2": false,
-#endif
-#endif
-#endif
-#if defined(CDE || AAA)
-  "shouldBe": true,
-#endif
-  "so": 3.14
-}
diff --git a/tools/testdata/manifest_small1_expected.json b/tools/testdata/manifest_small1_expected.json
deleted file mode 100644
index 0e32581..0000000
--- a/tools/testdata/manifest_small1_expected.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "foo": "option",
-  "bar": 1,
-  "count": 2,
-  "shouldBe": true,
-  "so": 3.14
-}
diff --git a/webpack.config.js b/webpack.config.js
index 5b897dc..2c94b12 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -73,7 +73,7 @@
       new WebpackShellPluginNext({
         onBuildEnd: {
           scripts:
-              ['go run tools/generateManifest.go -dest=' +
+              ['genmanifest -template templates/manifest.gjson -dest ' +
                path.join(outputPath, 'manifest.json') + ' ' +
                env.browser_target]
         }