Repository: cloudspannerecosystem/harbourbridge
Pull request #215 (2021-11-03 15:01:57)

Fixing golint issues
fixing golint issues. this includes:

- lowercasing first letter of error messages
- removing punctuation at the end of error messages
- switching from ALL_CAPS to CamelCase
- adding comments to exported function/variable
- adding exported function/variable name to beginning of comment
- removing blank imports

also added staticcheck to our linter as it is used by golint

- [x] Tests pass
- [x] Appropriate changes to README are included in PR

Deep1998: LGTM!

Patch:
diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml
index 7104b4b..16d5aa6 100644
--- a/.github/workflows/lint.yaml
+++ b/.github/workflows/lint.yaml
@@ -16,3 +16,4 @@ jobs:
       - run: go vet .
       - run: go get golang.org/x/tools/cmd/goimports && test -z $(goimports -l .)
       - run: go get golang.org/x/lint/golint && golint .
+      - run: go get honnef.co/go/tools/cmd/staticcheck && staticcheck .
diff --git a/cmd/target_profile.go b/cmd/target_profile.go
index c0c2645..e5e5b09 100644
--- a/cmd/target_profile.go
+++ b/cmd/target_profile.go
@@ -53,16 +53,16 @@ func (trg TargetProfile) ToLegacyTargetDb() string {
 				{
 					sp := conn.sp
 					if len(sp.dialect) > 0 && strings.ToLower(sp.dialect) == constants.DIALECT_POSTGRESQL {
-						return constants.TARGET_EXPERIMENTAL_POSTGRES
+						return constants.TargetExperimentalPostgres
 					}
-					return constants.TARGET_SPANNER
+					return constants.TargetSpanner
 				}
 			default:
-				return constants.TARGET_SPANNER
+				return constants.TargetSpanner
 			}
 		}
 	default:
-		return constants.TARGET_SPANNER
+		return constants.TargetSpanner
 	}
 }
 
diff --git a/common/constants/constants.go b/common/constants/constants.go
index 9631b91..2768c8f 100644
--- a/common/constants/constants.go
+++ b/common/constants/constants.go
@@ -21,8 +21,8 @@ const (
 	DYNAMODB string = "dynamodb"
 
 	// Target db for which schema is being generated.
-	TARGET_SPANNER               string = "spanner"
-	TARGET_EXPERIMENTAL_POSTGRES string = "experimental_postgres"
+	TargetSpanner              string = "spanner"
+	TargetExperimentalPostgres string = "experimental_postgres"
 
 	// Supported dialects for Cloud Spanner database.
 	DIALECT_POSTGRESQL string = "postgresql"
diff --git a/conversion/conversion.go b/conversion/conversion.go
index d92008c..d20292e 100644
--- a/conversion/conversion.go
+++ b/conversion/conversion.go
@@ -20,7 +20,6 @@
 // 			key public type definitions next (although often it makes sense to put them next to public functions that use them)
 // 			then public functions (and relevant type definitions)
 // 			and helper functions and other non-public definitions last (generally in order of importance)
-
 package conversion
 
 import (
@@ -48,8 +47,6 @@ import (
 	"github.com/aws/aws-sdk-go/aws"
 	"github.com/aws/aws-sdk-go/aws/session"
 	dydb "github.com/aws/aws-sdk-go/service/dynamodb"
-	_ "github.com/go-sql-driver/mysql"
-	_ "github.com/lib/pq"
 	"golang.org/x/crypto/ssh/terminal"
 	"google.golang.org/api/iterator"
 	"google.golang.org/api/option"
@@ -76,6 +73,7 @@ var (
 	MaxWorkers = 20
 )
 
+// SchemaConv performs the schema conversion
 // The sqlConnectionStr param provides the connection details to use the go SQL library.
 // It is empty in the following cases:
 //  - Driver is DynamoDB or a dump file mode.
@@ -94,6 +92,7 @@ func SchemaConv(driver, sqlConnectionStr, targetDb string, ioHelper *IOStreams,
 	}
 }
 
+// DataConv performs the data conversion
 // The sqlConnectionStr param provides the connection details to use the go SQL library.
 // It is empty in the following cases:
 //  - Driver is DynamoDB or a dump file mode.
@@ -111,7 +110,7 @@ func DataConv(driver, sqlConnectionStr string, ioHelper *IOStreams, client *sp.C
 		return dataFromSQL(driver, sqlConnectionStr, config, client, conv)
 	case constants.PGDUMP, constants.MYSQLDUMP:
 		if conv.SpSchema.CheckInterleaved() {
-			return nil, fmt.Errorf("HarbourBridge does not currently support data conversion from dump files\nif the schema contains interleaved tables. Suggest using direct access to source database\ni.e. using drivers postgres and mysql.")
+			return nil, fmt.Errorf("harbourBridge does not currently support data conversion from dump files\nif the schema contains interleaved tables. Suggest using direct access to source database\ni.e. using drivers postgres and mysql")
 		}
 		return dataFromDump(driver, config, ioHelper, client, conv, dataOnly)
 	case constants.DYNAMODB:
@@ -310,6 +309,7 @@ func dataFromDynamoDB(config spanner.BatchWriterConfig, client *sp.Client, conv
 	return writer, nil
 }
 
+// IOStreams is a struct that contains the file descriptor for dumpFile.
 type IOStreams struct {
 	In, SeekableIn, Out *os.File
 	BytesRead           int64
@@ -530,7 +530,7 @@ func getSeekable(f *os.File) (*os.File, int64, error) {
 	if err != nil {
 		return nil, 0, fmt.Errorf("can't reset file offset: %w", err)
 	}
-	n, err := getSize(fcopy)
+	n, _ := getSize(fcopy)
 	return fcopy, n, nil
 }
 
@@ -566,11 +566,12 @@ func ValidateDDL(ctx context.Context, adminClient *database.DatabaseAdminClient,
 		return fmt.Errorf("can't fetch database ddl: %v", err)
 	}
 	if len(dbDdl.Statements) != 0 {
-		return fmt.Errorf("HarbourBridge supports writing to existing databases only if they have an empty schema")
+		return fmt.Errorf("harbourBridge supports writing to existing databases only if they have an empty schema")
 	}
 	return nil
 }
 
+// CreatesOrUpdatesDatabase updates an existing Spanner database or creates a new one if one does not exist.
 func CreateOrUpdateDatabase(ctx context.Context, adminClient *database.DatabaseAdminClient, dbURI string, conv *internal.Conv, out *os.File) error {
 	dbExists, err := VerifyDb(ctx, adminClient, dbURI)
 	if err != nil {
@@ -604,8 +605,8 @@ func CreateDatabase(ctx context.Context, adminClient *database.DatabaseAdminClie
 	req := &adminpb.CreateDatabaseRequest{
 		Parent: fmt.Sprintf("projects/%s/instances/%s", project, instance),
 	}
-	if conv.TargetDb == constants.TARGET_EXPERIMENTAL_POSTGRES {
-		// TARGET_EXPERIMENTAL_POSTGRES doesn't support:
+	if conv.TargetDb == constants.TargetExperimentalPostgres {
+		// TargetExperimentalPostgres doesn't support:
 		// a) backticks around the database name, and
 		// b) DDL statements as part of a CreateDatabase operation (so schema
 		// must be set using a separate UpdateDatabase operation).
@@ -625,13 +626,14 @@ func CreateDatabase(ctx context.Context, adminClient *database.DatabaseAdminClie
 	}
 	fmt.Fprintf(out, "Created database successfully.\n")
 
-	if conv.TargetDb == constants.TARGET_EXPERIMENTAL_POSTGRES {
+	if conv.TargetDb == constants.TargetExperimentalPostgres {
 		// Update schema separately for PG databases.
 		return UpdateDatabase(ctx, adminClient, dbURI, conv, out)
 	}
 	return nil
 }
 
+// UpdateDatabase updates an existing spanner database.
 func UpdateDatabase(ctx context.Context, adminClient *database.DatabaseAdminClient, dbURI string, conv *internal.Conv, out *os.File) error {
 	fmt.Fprintf(out, "Updating schema for %s with default permissions ... \n", dbURI)
 	// The schema we send to Spanner excludes comments (since Cloud
@@ -722,15 +724,15 @@ Recommended value is between 20-30.`)
 	// too many requests and get throttled due to network or hitting catalog memory limits.
 	// Ensure atmost `MaxWorkers` go routines run in parallel that each update the ddl with one foreign key statement.
 	for _, fkStmt := range fkStmts {
-		workerId := <-workers
-		go func(fkStmt string, workerId int) {
+		workerID := <-workers
+		go func(fkStmt string, workerID int) {
 			defer func() {
 				// Locking the progress reporting otherwise progress results displayed could be in random order.
 				progressMutex.Lock()
 				progress++
 				p.MaybeReport(progress)
 				progressMutex.Unlock()
-				workers <- workerId
+				workers <- workerID
 			}()
 			internal.VerbosePrintf("Submitting new FK create request: %s\n", fkStmt)
 			op, err := adminClient.UpdateDatabaseDdl(ctx, &adminpb.UpdateDatabaseDdlRequest{
@@ -748,7 +750,7 @@ Recommended value is between 20-30.`)
 				return
 			}
 			internal.VerbosePrintln("Updated schema with statement: " + fkStmt)
-		}(fkStmt, workerId)
+		}(fkStmt, workerID)
 	}
 	// Wait for all the goroutines to finish.
 	for i := 1; i <= MaxWorkers; i++ {
@@ -1005,21 +1007,19 @@ func AnalyzeError(err error, URI string) error {
 	project, instance, _ := parseURI(URI)
 	e := strings.ToLower(err.Error())
 	if containsAny(e, []string{"unauthenticated", "cannot fetch token", "default credentials"}) {
-		return fmt.Errorf("%w.\n"+`
+		return fmt.Errorf("%w."+`
 Possible cause: credentials are mis-configured. Do you need to run
 
   gcloud auth application-default login
 
 or configure environment variable GOOGLE_APPLICATION_CREDENTIALS.
-See https://cloud.google.com/docs/authentication/getting-started.
-`, err)
+See https://cloud.google.com/docs/authentication/getting-started`, err)
 	}
 	if containsAny(e, []string{"instance not found"}) && instance != "" {
 		return fmt.Errorf("%w.\n"+`
 Possible cause: Spanner instance specified via instance option does not exist.
 Please check that '%s' is correct and that it is a valid Spanner
-instance for project %s.
-`, err, instance, project)
+instance for project %s`, err, instance, project)
 	}
 	return err
 }
diff --git a/go.mod b/go.mod
index 68e5515..5d7060a 100644
--- a/go.mod
+++ b/go.mod
@@ -24,6 +24,7 @@ require (
 	golang.org/x/tools v0.1.7 // indirect
 	google.golang.org/api v0.57.0
 	google.golang.org/genproto v0.0.0-20210921142501-181ce0d877f6
+	honnef.co/go/tools v0.2.1 // indirect
 )
 
 // cloud.google.com/go will upgrade grpc to v1.40.0
diff --git a/go.sum b/go.sum
index d6644a2..812c98c 100644
--- a/go.sum
+++ b/go.sum
@@ -456,6 +456,7 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q
 github.com/yookoala/realpath v1.0.0/go.mod h1:gJJMA9wuX7AcqLy1+ffPatSCySA1FQ2S8Ya9AIoYBpE=
 github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
@@ -553,6 +554,7 @@ golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/
 golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
@@ -571,6 +573,7 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -604,6 +607,7 @@ golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -661,6 +665,7 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY
 golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
 golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
 golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
@@ -737,8 +742,9 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh
 honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
 honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+honnef.co/go/tools v0.2.1 h1:/EPr//+UMMXwMTkXvCCoaJDq8cpjMO80Ou+L4PDo2mY=
+honnef.co/go/tools v0.2.1/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY=
 k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
 sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
 sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
diff --git a/internal/mapping.go b/internal/mapping.go
index cd28d27..3d3b72b 100644
--- a/internal/mapping.go
+++ b/internal/mapping.go
@@ -43,7 +43,7 @@ func GetSpannerTable(conv *Conv, srcTable string) (string, error) {
 	if sp, found := conv.ToSpanner[srcTable]; found {
 		return sp.Name, nil
 	}
-	spTable := getSpannerId(conv, srcTable)
+	spTable := getSpannerID(conv, srcTable)
 	if spTable != srcTable {
 		VerbosePrintf("Mapping source DB table %s to Spanner table %s\n", srcTable, spTable)
 	}
@@ -135,11 +135,11 @@ func GetSpannerCols(conv *Conv, srcTable string, srcCols []string) ([]string, er
 // (across the database). But in some source databases, such as PostgreSQL,
 // they only have to be unique for a table. Hence we must map each source
 // constraint name to a unique spanner constraint name.
-func ToSpannerForeignKey(conv *Conv, srcId string) string {
-	if srcId == "" {
+func ToSpannerForeignKey(conv *Conv, srcID string) string {
+	if srcID == "" {
 		return ""
 	}
-	return getSpannerId(conv, srcId)
+	return getSpannerID(conv, srcID)
 }
 
 // ToSpannerIndexName maps source index name to legal Spanner index name.
@@ -151,16 +151,16 @@ func ToSpannerForeignKey(conv *Conv, srcId string) string {
 // (across the database). But in some source databases, such as MySQL,
 // they only have to be unique for a table. Hence we must map each source
 // constraint name to a unique spanner constraint name.
-func ToSpannerIndexName(conv *Conv, srcId string) string {
-	return getSpannerId(conv, srcId)
+func ToSpannerIndexName(conv *Conv, srcID string) string {
+	return getSpannerID(conv, srcID)
 }
 
 // conv.UsedNames tracks Spanner names that have been used for table names, foreign key constraints
 // and indexes. We use this to ensure we generate unique names when
 // we map from source dbs to Spanner since Spanner requires all these names to be
 // distinct and should not differ only in case.
-func getSpannerId(conv *Conv, srcId string) string {
-	spKeyName, _ := FixName(srcId)
+func getSpannerID(conv *Conv, srcID string) string {
+	spKeyName, _ := FixName(srcID)
 	if _, found := conv.UsedNames[strings.ToLower(spKeyName)]; found {
 		// spKeyName has been used before.
 		// Add unique postfix: use number of keys so far.
@@ -226,7 +226,7 @@ func resolveTableRef(conv *Conv, tableRef string) (string, error) {
 			return t, nil
 		}
 	}
-	return "", fmt.Errorf("Can't resolve table %v", tableRef)
+	return "", fmt.Errorf("can't resolve table %v", tableRef)
 }
 
 func resolveColRefs(conv *Conv, tableRef string, colRefs []string) ([]string, error) {
@@ -245,7 +245,7 @@ func resolveColRefs(conv *Conv, tableRef string, colRefs []string) ([]string, er
 				return c, nil
 			}
 		}
-		return "", fmt.Errorf("Can't resolve column: table=%v, column=%v", tableRef, colRef)
+		return "", fmt.Errorf("can't resolve column: table=%v, column=%v", tableRef, colRef)
 	}
 	var cols []string
 	for _, colRef := range colRefs {
diff --git a/internal/report.go b/internal/report.go
index 5658186..c44c1fb 100644
--- a/internal/report.go
+++ b/internal/report.go
@@ -97,6 +97,7 @@ type tableReportBody struct {
 	Lines   []string
 }
 
+// AnalyzeTables generates table reports for all processed tables.
 func AnalyzeTables(conv *Conv, badWrites map[string]int64) (r []tableReport) {
 	// Process tables in alphabetical order. This ensures that tables
 	// appear in alphabetical order in report.txt.
@@ -119,7 +120,7 @@ func buildTableReport(conv *Conv, srcTable string, badWrites map[string]int64) t
 	if err != nil || !ok1 || !ok2 {
 		m := "bad source-DB-to-Spanner table mapping or Spanner schema"
 		conv.Unexpected("report: " + m)
-		tr.Body = []tableReportBody{tableReportBody{Heading: "Internal error: " + m}}
+		tr.Body = []tableReportBody{{Heading: "Internal error: " + m}}
 		return tr
 	}
 	issues, cols, warnings := analyzeCols(conv, srcTable, spTable)
@@ -247,7 +248,7 @@ func fillRowStats(conv *Conv, srcTable string, badWrites map[string]int64, tr *t
 	tr.badRows = badConvRows + badRowWrites
 }
 
-// Provides a description and severity for each schema issue.
+// IssueDB provides a description and severity for each schema issue.
 // Note on batch: for some issues, we'd like to report just the first instance
 // in a table and suppress other instances i.e. adding more instances
 // of the issue in the same table has little value and could be very noisy.
@@ -379,6 +380,7 @@ func rateConversion(rows, badRows, cols, warnings int64, missingPKey, summary bo
 	return rate
 }
 
+// GenerateSummary creates a summarized version of a tableReport.
 func GenerateSummary(conv *Conv, r []tableReport, badWrites map[string]int64) string {
 	cols := int64(0)
 	warnings := int64(0)
@@ -407,6 +409,7 @@ func GenerateSummary(conv *Conv, r []tableReport, badWrites map[string]int64) st
 	return rateConversion(rows, badRows, cols, warnings, missingPKey, true, conv.SchemaMode())
 }
 
+// IgnoredStatements creates a list of statements to ignore.
 func IgnoredStatements(conv *Conv) (l []string) {
 	for s := range conv.Stats.Statement {
 		switch s {
diff --git a/main.go b/main.go
index 64a7162..0468f17 100644
--- a/main.go
+++ b/main.go
@@ -49,7 +49,7 @@ var (
 	sessionJSON      string
 	webapi           bool
 	dumpFilePath     string
-	targetDb         = constants.TARGET_SPANNER
+	targetDb         = constants.TargetSpanner
 )
 
 func setupGlobalFlags() {
@@ -66,7 +66,7 @@ func setupGlobalFlags() {
 	flag.StringVar(&sessionJSON, "session", "", "session: specifies the file we restore session state from (used in data-only to provide schema and data mapping)")
 	flag.BoolVar(&webapi, "web", false, "web: run the web interface (experimental)")
 	flag.StringVar(&dumpFilePath, "dump-file", "", "dump-file: location of dump file to process")
-	flag.StringVar(&targetDb, "target-db", constants.TARGET_SPANNER, "target-db: Specifies the target DB. Defaults to spanner")
+	flag.StringVar(&targetDb, "target-db", constants.TargetSpanner, "target-db: Specifies the target DB. Defaults to spanner")
 }
 
 func didSetVerboseTwice() bool {
@@ -121,7 +121,7 @@ func main() {
 
 	// Note: the web interface does not use any commandline flags.
 	if webapi {
-		web.WebApp()
+		web.App()
 		return
 	}
 
@@ -140,11 +140,11 @@ func main() {
 		panic(fmt.Errorf("can't use both schema-only and skip-foreign-keys at once, foreign Key creation can only be skipped when data migration takes place"))
 	}
 
-	if targetDb == constants.TARGET_EXPERIMENTAL_POSTGRES {
+	if targetDb == constants.TargetExperimentalPostgres {
 		if !(driverName == constants.PGDUMP || driverName == constants.POSTGRES) {
 			panic(fmt.Errorf("can only convert to experimental postgres when source %s or %s. (target-db: %s driver: %s)", constants.PGDUMP, constants.POSTGRES, targetDb, driverName))
 		}
-	} else if targetDb != constants.TARGET_SPANNER {
+	} else if targetDb != constants.TargetSpanner {
 		panic(fmt.Errorf("unkown target-db %s", targetDb))
 	}
 	fmt.Printf("Using driver (source DB): %s target-db: %s\n", driverName, targetDb)
diff --git a/sources/common/dbdump.go b/sources/common/dbdump.go
index 365014a..f207dc5 100644
--- a/sources/common/dbdump.go
+++ b/sources/common/dbdump.go
@@ -18,6 +18,7 @@ import (
 	"github.com/cloudspannerecosystem/harbourbridge/internal"
 )
 
+// DbDump common interface for database dump functions.
 type DbDump interface {
 	GetToDdl() ToDdl
 	ProcessDump(conv *internal.Conv, r *internal.Reader) error
diff --git a/sources/common/infoschema.go b/sources/common/infoschema.go
index fd0e174..9b5ac42 100644
--- a/sources/common/infoschema.go
+++ b/sources/common/infoschema.go
@@ -23,6 +23,7 @@ import (
 	"github.com/cloudspannerecosystem/harbourbridge/spanner/ddl"
 )
 
+// InfoSchema contains database information.
 type InfoSchema interface {
 	GetToDdl() ToDdl
 	GetTableName(schema string, tableName string) string
@@ -37,11 +38,13 @@ type InfoSchema interface {
 	ProcessDataRows(conv *internal.Conv, srcTable string, srcCols []string, srcSchema schema.Table, spTable string, spCols []string, spSchema ddl.CreateTable, rows *sql.Rows)
 }
 
+// SchemaAndName contains the schema and name for a table
 type SchemaAndName struct {
 	Schema string
 	Name   string
 }
 
+// FkConstraint contains foreign key constraints
 type FkConstraint struct {
 	Name    string
 	Table   string
diff --git a/sources/common/toddl.go b/sources/common/toddl.go
index fea23d5..e10bb43 100644
--- a/sources/common/toddl.go
+++ b/sources/common/toddl.go
@@ -39,7 +39,7 @@ import (
 	"github.com/cloudspannerecosystem/harbourbridge/spanner/ddl"
 )
 
-// This interface is meant to be implemented by all sources. When support for a
+// ToDdl interface is meant to be implemented by all sources. When support for a
 // new target database is added, please add a new method here with the output
 // type expected. In case a particular source to target transoformation is not
 // supported, an error is to be returned by the corresponding method.
@@ -47,7 +47,7 @@ type ToDdl interface {
 	ToSpannerType(conv *internal.Conv, columnType schema.Type) (ddl.Type, []internal.SchemaIssue)
 }
 
-// schemaToSpannerDDL performs schema conversion from the source DB schema to
+// SchemaToSpannerDDL performs schema conversion from the source DB schema to
 // Spanner. It uses the source schema in conv.SrcSchema, and writes
 // the Spanner schema to conv.SpSchema.
 func SchemaToSpannerDDL(conv *internal.Conv, toddl ToDdl) error {
diff --git a/sources/common/utils.go b/sources/common/utils.go
index 43f9dd6..3a38a02 100644
--- a/sources/common/utils.go
+++ b/sources/common/utils.go
@@ -6,6 +6,7 @@ import (
 	"github.com/cloudspannerecosystem/harbourbridge/internal"
 )
 
+// ToNotNull returns true if a column is not nullable and false if it is.
 func ToNotNull(conv *internal.Conv, isNullable string) bool {
 	switch isNullable {
 	case "YES":
diff --git a/sources/dynamodb/toddl.go b/sources/dynamodb/toddl.go
index eb977e6..d1f47ec 100644
--- a/sources/dynamodb/toddl.go
+++ b/sources/dynamodb/toddl.go
@@ -12,6 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+// Package dynamodb handles schema and data migrations from DynamoDB.
 package dynamodb
 
 import (
diff --git a/sources/mysql/data.go b/sources/mysql/data.go
index b0978bf..590e811 100644
--- a/sources/mysql/data.go
+++ b/sources/mysql/data.go
@@ -118,7 +118,7 @@ func convScalar(conv *internal.Conv, spannerType ddl.Type, srcTypeName string, T
 		return val, nil
 	case ddl.Timestamp:
 		return convTimestamp(srcTypeName, TimezoneOffset, val)
-	case ddl.Json:
+	case ddl.JSON:
 		return val, nil
 	default:
 		return val, fmt.Errorf("data conversion not implemented for type %v", spannerType.Name)
@@ -178,7 +178,7 @@ func convInt64(val string) (int64, error) {
 // convNumeric maps a source database string value (representing a numeric)
 // into a string representing a valid Spanner numeric.
 func convNumeric(conv *internal.Conv, val string) (interface{}, error) {
-	if conv.TargetDb == constants.TARGET_EXPERIMENTAL_POSTGRES {
+	if conv.TargetDb == constants.TargetExperimentalPostgres {
 		return spanner.PGNumeric{Numeric: val, Valid: true}, nil
 	} else {
 		r := new(big.Rat)
diff --git a/sources/mysql/infoschema.go b/sources/mysql/infoschema.go
index 460c3ec..47a016a 100644
--- a/sources/mysql/infoschema.go
+++ b/sources/mysql/infoschema.go
@@ -28,20 +28,22 @@ import (
 	_ "github.com/lib/pq"
 )
 
-// MySQL specific implementation for InfoSchema
+// InfoSchemaImpl is MySQL specific implementation for InfoSchema.
 type InfoSchemaImpl struct {
 	DbName string
 }
 
-//Functions below implement the common.InfoSchema interface
+// GetToDdl implement the common.InfoSchema interface.
 func (isi InfoSchemaImpl) GetToDdl() common.ToDdl {
 	return ToDdlImpl{}
 }
 
+// GetTableName returns table name.
 func (isi InfoSchemaImpl) GetTableName(dbName string, tableName string) string {
 	return tableName
 }
 
+// GetRowsFromTable returns a sql Rows object for a table.
 func (isi InfoSchemaImpl) GetRowsFromTable(conv *internal.Conv, db *sql.DB, table common.SchemaAndName) (*sql.Rows, error) {
 	srcSchema := conv.SrcSchema[table.Name]
 	srcCols := srcSchema.ColNames
@@ -78,6 +80,7 @@ func buildColNameList(srcSchema schema.Table, srcColName []string) string {
 	return colList[:len(colList)-1]
 }
 
+// ProcessDataRows performs data conversion for source database.
 func (isi InfoSchemaImpl) ProcessDataRows(conv *internal.Conv, srcTable string, srcCols []string, srcSchema schema.Table, spTable string, spCols []string, spSchema ddl.CreateTable, rows *sql.Rows) {
 	v, scanArgs := buildVals(len(srcCols))
 	for rows.Next() {
@@ -113,7 +116,7 @@ func (isi InfoSchemaImpl) GetRowCount(db *sql.DB, table common.SchemaAndName) (i
 	return 0, nil //Check if 0 is ok to return
 }
 
-// getTables return list of tables in the selected database.
+// GetTables return list of tables in the selected database.
 // Note that sql.DB already effectively has the dbName
 // embedded within it (dbName is part of the DSN passed to sql.Open),
 // but unfortunately there is no way to extract it from sql.DB.
@@ -134,6 +137,7 @@ func (isi InfoSchemaImpl) GetTables(db *sql.DB) ([]common.SchemaAndName, error)
 	return tables, nil
 }
 
+// GetColumns returns a list of columns with their data type
 func (isi InfoSchemaImpl) GetColumns(table common.SchemaAndName, db *sql.DB) (*sql.Rows, error) {
 	q := `SELECT c.column_name, c.data_type, c.column_type, c.is_nullable, c.column_default, c.character_maximum_length, c.numeric_precision, c.numeric_scale, c.extra
               FROM information_schema.COLUMNS c
@@ -141,6 +145,7 @@ func (isi InfoSchemaImpl) GetColumns(table common.SchemaAndName, db *sql.DB) (*s
 	return db.Query(q, table.Schema, table.Name)
 }
 
+// ProcessColumns returns a list of Column objects and names// ProcessColumns
 func (isi InfoSchemaImpl) ProcessColumns(conv *internal.Conv, cols *sql.Rows, constraints map[string][]string) (map[string]schema.Column, []string) {
 	colDefs := make(map[string]schema.Column)
 	var colNames []string
@@ -180,7 +185,7 @@ func (isi InfoSchemaImpl) ProcessColumns(conv *internal.Conv, cols *sql.Rows, co
 	return colDefs, colNames
 }
 
-// getConstraints returns a list of primary keys and by-column map of
+// GetConstraints returns a list of primary keys and by-column map of
 // other constraints.  Note: we need to preserve ordinal order of
 // columns in primary key constraints.
 // Note that foreign key constraints are handled in getForeignKeys.
@@ -218,7 +223,7 @@ func (isi InfoSchemaImpl) GetConstraints(conv *internal.Conv, db *sql.DB, table
 	return primaryKeys, m, nil
 }
 
-// getForeignKeys return list all the foreign keys constraints.
+// GetForeignKeys return list all the foreign keys constraints.
 // MySQL supports cross-database foreign key constraints. We ignore
 // them because HarbourBridge works database at a time (a specific run
 // of HarbourBridge focuses on a specific database) and so we can't handle
@@ -275,7 +280,7 @@ func (isi InfoSchemaImpl) GetForeignKeys(conv *internal.Conv, db *sql.DB, table
 	return foreignKeys, nil
 }
 
-// getIndexes return a list of all indexes for the specified table.
+// GetIndexes return a list of all indexes for the specified table.
 func (isi InfoSchemaImpl) GetIndexes(conv *internal.Conv, db *sql.DB, table common.SchemaAndName) ([]schema.Index, error) {
 	q := `SELECT DISTINCT INDEX_NAME,COLUMN_NAME,SEQ_IN_INDEX,COLLATION,NON_UNIQUE
 		FROM INFORMATION_SCHEMA.STATISTICS 
diff --git a/sources/mysql/mysqldump.go b/sources/mysql/mysqldump.go
index 2645036..1faf29a 100644
--- a/sources/mysql/mysqldump.go
+++ b/sources/mysql/mysqldump.go
@@ -47,13 +47,15 @@ var spatialRegexps = func() []*regexp.Regexp {
 var spatialIndexRegex = regexp.MustCompile("(?i)\\sSPATIAL\\s")
 var spatialSridRegex = regexp.MustCompile("(?i)\\sSRID\\s\\d*")
 
+// DbDumpImpl MySQL specific implementation for DdlDumpImpl.
 type DbDumpImpl struct{}
 
-//Functions below implement the common.DbDump interface
+// GetToDdl function below implement the common.DbDump interface.
 func (ddi DbDumpImpl) GetToDdl() common.ToDdl {
 	return ToDdlImpl{}
 }
 
+// ProcessDump processes the mysql dump.
 func (ddi DbDumpImpl) ProcessDump(conv *internal.Conv, r *internal.Reader) error {
 	return processMySQLDump(conv, r)
 }
@@ -161,7 +163,7 @@ func processStatement(conv *internal.Conv, stmt ast.StmtNode) bool {
 
 func processCreateIndex(conv *internal.Conv, stmt *ast.CreateIndexStmt) {
 	if stmt.Table == nil {
-		logStmtError(conv, stmt, fmt.Errorf("cannot process index statement with nil table."))
+		logStmtError(conv, stmt, fmt.Errorf("cannot process index statement with nil table"))
 		return
 	}
 	tableName, err := getTableName(stmt.Table)
diff --git a/sources/mysql/toddl.go b/sources/mysql/toddl.go
index 72505cd..e76a5cf 100644
--- a/sources/mysql/toddl.go
+++ b/sources/mysql/toddl.go
@@ -12,6 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+// Package MySQL handles schema and data migrations from MySQL.
 package mysql
 
 import (
@@ -21,18 +22,18 @@ import (
 	"github.com/cloudspannerecosystem/harbourbridge/spanner/ddl"
 )
 
-// MySQL specific implementation for ToDdl
+// ToDdlImpl MySQL specific implementation for ToDdl.
 type ToDdlImpl struct {
 }
 
-// Functions below implement the common.ToDdl interface
-// toSpannerType maps a scalar source schema type (defined by id and
+// ToSpannerType maps a scalar source schema type (defined by id and
 // mods) into a Spanner type. This is the core source-to-Spanner type
 // mapping.  toSpannerType returns the Spanner type and a list of type
 // conversion issues encountered.
+// Functions below implement the common.ToDdl interface
 func (tdi ToDdlImpl) ToSpannerType(conv *internal.Conv, columnType schema.Type) (ddl.Type, []internal.SchemaIssue) {
 	ty, issues := toSpannerTypeInternal(conv, columnType.Name, columnType.Mods)
-	if conv.TargetDb == constants.TARGET_EXPERIMENTAL_POSTGRES {
+	if conv.TargetDb == constants.TargetExperimentalPostgres {
 		ty = overrideExperimentalType(columnType, ty)
 	} else {
 		if len(columnType.ArrayBounds) > 1 {
@@ -83,7 +84,7 @@ func toSpannerTypeInternal(conv *internal.Conv, id string, mods []int64) (ddl.Ty
 	case "set", "enum":
 		return ddl.Type{Name: ddl.String, Len: ddl.MaxLength}, nil
 	case "json":
-		return ddl.Type{Name: ddl.Json}, nil
+		return ddl.Type{Name: ddl.JSON}, nil
 	case "binary", "varbinary":
 		return ddl.Type{Name: ddl.Bytes, Len: ddl.MaxLength}, nil
 	case "tinyblob", "mediumblob", "blob", "longblob":
diff --git a/sources/postgres/data.go b/sources/postgres/data.go
index d799229..da3d237 100644
--- a/sources/postgres/data.go
+++ b/sources/postgres/data.go
@@ -133,7 +133,7 @@ func convScalar(conv *internal.Conv, spannerType ddl.Type, srcTypeName string, l
 		return val, nil
 	case ddl.Timestamp:
 		return convTimestamp(srcTypeName, location, val)
-	case ddl.Json:
+	case ddl.JSON:
 		return val, nil
 	default:
 		return val, fmt.Errorf("data conversion not implemented for type %v", spannerType.Name)
@@ -186,7 +186,7 @@ func convInt64(val string) (int64, error) {
 // convNumeric maps a source database string value (representing a numeric)
 // into a string representing a valid Spanner numeric.
 func convNumeric(conv *internal.Conv, val string) (interface{}, error) {
-	if conv.TargetDb == constants.TARGET_EXPERIMENTAL_POSTGRES {
+	if conv.TargetDb == constants.TargetExperimentalPostgres {
 		return spanner.PGNumeric{Numeric: val, Valid: true}, nil
 	} else {
 		r := new(big.Rat)
diff --git a/sources/postgres/infoschema.go b/sources/postgres/infoschema.go
index 79f345c..7ea1f19 100644
--- a/sources/postgres/infoschema.go
+++ b/sources/postgres/infoschema.go
@@ -32,15 +32,16 @@ import (
 	"github.com/cloudspannerecosystem/harbourbridge/spanner/ddl"
 )
 
-// Postgres specific implementation for InfoSchema
+// InfoSchemaImpl postgres specific implementation for InfoSchema.
 type InfoSchemaImpl struct {
 }
 
-//Functions below implement the common.InfoSchema interface
+// GetToDdl function below implement the common.InfoSchema interface.
 func (isi InfoSchemaImpl) GetToDdl() common.ToDdl {
 	return ToDdlImpl{}
 }
 
+// GetTableName returns table name.
 func (isi InfoSchemaImpl) GetTableName(schema string, tableName string) string {
 	if schema == "public" { // Drop 'public' prefix.
 		return tableName
@@ -48,6 +49,7 @@ func (isi InfoSchemaImpl) GetTableName(schema string, tableName string) string {
 	return fmt.Sprintf("%s.%s", schema, tableName)
 }
 
+// GetRowsFromTable returns a sql Rows object for a table.
 func (isi InfoSchemaImpl) GetRowsFromTable(conv *internal.Conv, db *sql.DB, table common.SchemaAndName) (*sql.Rows, error) {
 	// PostgreSQL schema and name can be arbitrary strings.
 	// Ideally we would pass schema/name as a query parameter,
@@ -60,7 +62,7 @@ func (isi InfoSchemaImpl) GetRowsFromTable(conv *internal.Conv, db *sql.DB, tabl
 	return rows, err
 }
 
-// ProcessSQLData performs data conversion for source database
+// ProcessDataRows performs data conversion for source database
 // 'db'. For each table, we extract data using a "SELECT *" query,
 // convert the data to Spanner data (based on the source and Spanner
 // schemas), and write it to Spanner.  If we can't get/process data
@@ -159,6 +161,7 @@ func (isi InfoSchemaImpl) GetRowCount(db *sql.DB, table common.SchemaAndName) (i
 	return 0, nil //Check if 0 is ok to return
 }
 
+// GetTables return list of tables in the selected database.
 // TODO: All of the queries to get tables and table data should be in
 // a single transaction to ensure we obtain a consistent snapshot of
 // schema information and table data (pg_dump does something
@@ -186,6 +189,7 @@ func (isi InfoSchemaImpl) GetTables(db *sql.DB) ([]common.SchemaAndName, error)
 	return tables, nil
 }
 
+// GetColumns returns a list of columns with their data type
 func (isi InfoSchemaImpl) GetColumns(table common.SchemaAndName, db *sql.DB) (*sql.Rows, error) {
 	q := `SELECT c.column_name, c.data_type, e.data_type, c.is_nullable, c.column_default, c.character_maximum_length, c.numeric_precision, c.numeric_scale
               FROM information_schema.COLUMNS c LEFT JOIN information_schema.element_types e
@@ -195,6 +199,7 @@ func (isi InfoSchemaImpl) GetColumns(table common.SchemaAndName, db *sql.DB) (*s
 	return db.Query(q, table.Schema, table.Name)
 }
 
+// ProcessColumns returns a list of Column objects and names
 func (isi InfoSchemaImpl) ProcessColumns(conv *internal.Conv, cols *sql.Rows, constraints map[string][]string) (map[string]schema.Column, []string) {
 	colDefs := make(map[string]schema.Column)
 	var colNames []string
@@ -232,7 +237,7 @@ func (isi InfoSchemaImpl) ProcessColumns(conv *internal.Conv, cols *sql.Rows, co
 	return colDefs, colNames
 }
 
-// getConstraints returns a list of primary keys and by-column map of
+// GetConstraints returns a list of primary keys and by-column map of
 // other constraints.  Note: we need to preserve ordinal order of
 // columns in primary key constraints.
 // Note that foreign key constraints are handled in getForeignKeys.
@@ -270,7 +275,7 @@ func (isi InfoSchemaImpl) GetConstraints(conv *internal.Conv, db *sql.DB, table
 	return primaryKeys, m, nil
 }
 
-// getForeignKeys returns a list of all the foreign key constraints.
+// GetForeignKeys returns a list of all the foreign key constraints.
 func (isi InfoSchemaImpl) GetForeignKeys(conv *internal.Conv, db *sql.DB, table common.SchemaAndName) (foreignKeys []schema.ForeignKey, err error) {
 	q := `SELECT 
 		schema_name AS "TABLE_SCHEMA", 
@@ -335,7 +340,7 @@ func (isi InfoSchemaImpl) GetForeignKeys(conv *internal.Conv, db *sql.DB, table
 	return foreignKeys, nil
 }
 
-// getIndexes return a list of all indexes for the specified table.
+// GetIndexes return a list of all indexes for the specified table.
 // Note: Extracting index definitions from PostgreSQL information schema tables is complex.
 // See https://stackoverflow.com/questions/6777456/list-all-index-names-column-names-and-its-table-name-of-a-postgresql-database/44460269#44460269
 // for background.
@@ -512,7 +517,7 @@ func cvtSQLScalar(conv *internal.Conv, srcCd schema.Column, spCd ddl.ColumnDef,
 		case time.Time:
 			return v, nil
 		}
-	case ddl.Json:
+	case ddl.JSON:
 		switch v := val.(type) {
 		case string:
 			return string(v), nil
diff --git a/sources/postgres/pgdump.go b/sources/postgres/pgdump.go
index 944538f..4318ae8 100644
--- a/sources/postgres/pgdump.go
+++ b/sources/postgres/pgdump.go
@@ -28,6 +28,7 @@ import (
 	"github.com/cloudspannerecosystem/harbourbridge/sources/common"
 )
 
+// DbDumpImpl Postgres specific implementation for DdlDumpImpl.
 type DbDumpImpl struct{}
 
 type copyOrInsert struct {
@@ -44,16 +45,17 @@ const (
 	insert
 )
 
-//Functions below implement the common.DbDump interface
+// GetToDdl functions below implement the common.DbDump interface
 func (ddi DbDumpImpl) GetToDdl() common.ToDdl {
 	return ToDdlImpl{}
 }
 
+// ProcessDump calls processPgDump to read a Postgres dump file
 func (ddi DbDumpImpl) ProcessDump(conv *internal.Conv, r *internal.Reader) error {
 	return processPgDump(conv, r)
 }
 
-// ProcessPgDump reads pg_dump data from r and does schema or data conversion,
+// processPgDump reads pg_dump data from r and does schema or data conversion,
 // depending on whether conv is configured for schema mode or data mode.
 // In schema mode, ProcessPgDump incrementally builds a schema (updating conv).
 // In data mode, ProcessPgDump uses this schema to convert PostgreSQL data
diff --git a/sources/postgres/toddl.go b/sources/postgres/toddl.go
index b5c8dad..fe88787 100644
--- a/sources/postgres/toddl.go
+++ b/sources/postgres/toddl.go
@@ -12,6 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+// Package postgres handles schema and data migrations from Postgres.
 package postgres
 
 import (
@@ -21,17 +22,17 @@ import (
 	"github.com/cloudspannerecosystem/harbourbridge/spanner/ddl"
 )
 
-// Postgres specific implementation for ToDdl
+// ToDdlImpl Postgres specific implementation for ToDdl.
 type ToDdlImpl struct {
 }
 
-// toSpannerType maps a scalar source schema type (defined by id and
+// ToSpannerType maps a scalar source schema type (defined by id and
 // mods) into a Spanner type. This is the core source-to-Spanner type
 // mapping.  toSpannerType returns the Spanner type and a list of type
 // conversion issues encountered.
 func (tdi ToDdlImpl) ToSpannerType(conv *internal.Conv, columnType schema.Type) (ddl.Type, []internal.SchemaIssue) {
 	ty, issues := toSpannerTypeInternal(conv, columnType.Name, columnType.Mods)
-	if conv.TargetDb == constants.TARGET_EXPERIMENTAL_POSTGRES {
+	if conv.TargetDb == constants.TargetExperimentalPostgres {
 		ty = overrideExperimentalType(columnType, ty)
 	} else {
 		if len(columnType.ArrayBounds) > 1 {
@@ -102,7 +103,7 @@ func toSpannerTypeInternal(conv *internal.Conv, id string, mods []int64) (ddl.Ty
 		}
 		return ddl.Type{Name: ddl.String, Len: ddl.MaxLength}, nil
 	case "json", "jsonb":
-		return ddl.Type{Name: ddl.Json}, nil
+		return ddl.Type{Name: ddl.JSON}, nil
 	}
 	return ddl.Type{Name: ddl.String, Len: ddl.MaxLength}, []internal.SchemaIssue{internal.NoGoodType}
 }
diff --git a/spanner/ddl/ast.go b/spanner/ddl/ast.go
index 33fc8b2..48ad695 100644
--- a/spanner/ddl/ast.go
+++ b/spanner/ddl/ast.go
@@ -49,7 +49,7 @@ const (
 	// Numeric represent NUMERIC type.
 	Numeric string = "NUMERIC"
 	// Json represent JSON type.
-	Json string = "JSON"
+	JSON string = "JSON"
 	// MaxLength is a sentinel for Type's Len field, representing the MAX value.
 	MaxLength = math.MaxInt64
 
@@ -168,7 +168,7 @@ func (c Config) quote(s string) string {
 // needs of PrintCreateTable.
 func (cd ColumnDef) PrintColumnDef(c Config) (string, string) {
 	var s string
-	if c.TargetDb == constants.TARGET_EXPERIMENTAL_POSTGRES {
+	if c.TargetDb == constants.TargetExperimentalPostgres {
 		s = fmt.Sprintf("%s %s", c.quote(cd.Name), cd.T.PGPrintColumnDefType())
 	} else {
 		s = fmt.Sprintf("%s %s", c.quote(cd.Name), cd.T.PrintColumnDefType())
@@ -267,7 +267,7 @@ func (ct CreateTable) PrintCreateTable(config Config) string {
 
 	var interleave string
 	if ct.Parent != "" {
-		if config.TargetDb == constants.TARGET_EXPERIMENTAL_POSTGRES {
+		if config.TargetDb == constants.TargetExperimentalPostgres {
 			// PG spanner only supports PRIMARY KEY() inside the CREATE TABLE()
 			// and thus INTERLEAVE follows immediately after closing brace.
 			interleave = " INTERLEAVE IN PARENT " + config.quote(ct.Parent)
@@ -276,7 +276,7 @@ func (ct CreateTable) PrintCreateTable(config Config) string {
 		}
 	}
 
-	if config.TargetDb == constants.TARGET_EXPERIMENTAL_POSTGRES {
+	if config.TargetDb == constants.TargetExperimentalPostgres {
 		return fmt.Sprintf("%sCREATE TABLE %s (\n%s\tPRIMARY KEY (%s)\n)%s", tableComment, config.quote(ct.Name), cols, strings.Join(keys, ", "), interleave)
 	}
 	return fmt.Sprintf("%sCREATE TABLE %s (\n%s) PRIMARY KEY (%s)%s", tableComment, config.quote(ct.Name), cols, strings.Join(keys, ", "), interleave)
@@ -320,8 +320,10 @@ func (k Foreignkey) PrintForeignKeyAlterTable(c Config, tableName string) string
 	return fmt.Sprintf("ALTER TABLE %s ADD %sFOREIGN KEY (%s) REFERENCES %s (%s)", c.quote(tableName), s, strings.Join(cols, ", "), c.quote(k.ReferTable), strings.Join(referCols, ", "))
 }
 
+// Schema stores a map of table names and Tables.
 type Schema map[string]CreateTable
 
+// NewSchema creates a new Schema object.
 func NewSchema() Schema {
 	return make(map[string]CreateTable)
 }
diff --git a/web/web.go b/web/web.go
index 13324c8..decded0 100644
--- a/web/web.go
+++ b/web/web.go
@@ -43,7 +43,6 @@ import (
 	"github.com/cloudspannerecosystem/harbourbridge/spanner/ddl"
 	_ "github.com/go-sql-driver/mysql"
 	"github.com/gorilla/handlers"
-	_ "github.com/lib/pq"
 )
 
 // TODO:(searce):
@@ -168,7 +167,7 @@ func convertSchemaDump(w http.ResponseWriter, r *http.Request) {
 		http.Error(w, fmt.Sprintf("failed to open dump file %v : %v", dc.FilePath, err), http.StatusNotFound)
 		return
 	}
-	conv, err := conversion.SchemaConv(dc.Driver, "", constants.TARGET_SPANNER, &conversion.IOStreams{In: f, Out: os.Stdout}, 0)
+	conv, err := conversion.SchemaConv(dc.Driver, "", constants.TargetSpanner, &conversion.IOStreams{In: f, Out: os.Stdout}, 0)
 	if err != nil {
 		http.Error(w, fmt.Sprintf("Schema Conversion Error : %v", err), http.StatusNotFound)
 		return
@@ -342,7 +341,7 @@ func updateTableSchema(w http.ResponseWriter, r *http.Request) {
 	srcTableName := sessionState.conv.ToSource[table].Name
 	for colName, v := range t.UpdateCols {
 		if v.Removed {
-			err, status := canRemoveColumn(colName, table)
+			status, err := canRemoveColumn(colName, table)
 			if err != nil {
 				err = rollback(err)
 				http.Error(w, fmt.Sprintf("%v", err), status)
@@ -352,7 +351,7 @@ func updateTableSchema(w http.ResponseWriter, r *http.Request) {
 			continue
 		}
 		if v.Rename != "" && v.Rename != colName {
-			if err, status := canRenameOrChangeType(colName, table); err != nil {
+			if status, err := canRenameOrChangeType(colName, table); err != nil {
 				err = rollback(err)
 				http.Error(w, fmt.Sprintf("%v", err), status)
 				return
@@ -373,7 +372,7 @@ func updateTableSchema(w http.ResponseWriter, r *http.Request) {
 			}
 
 			if typeChange {
-				if err, status := canRenameOrChangeType(colName, table); err != nil {
+				if status, err := canRenameOrChangeType(colName, table); err != nil {
 					err = rollback(err)
 					http.Error(w, fmt.Sprintf("%v", err), status)
 					return
@@ -439,6 +438,7 @@ func getReportFile(w http.ResponseWriter, r *http.Request) {
 	w.Write([]byte(reportAbsPath))
 }
 
+// TableInterleaveStatus stores data regarding interleave status.
 type TableInterleaveStatus struct {
 	Possible bool
 	Parent   string
@@ -856,44 +856,43 @@ func isReferencedByFK(col, table string) (bool, string) {
 	return false, ""
 }
 
-func canRemoveColumn(colName, table string) (error, int) {
+func canRemoveColumn(colName, table string) (int, error) {
 	if isPartOfPK := isPartOfPK(colName, table); isPartOfPK {
-		return fmt.Errorf("column is part of primary key"), http.StatusBadRequest
+		return http.StatusBadRequest, fmt.Errorf("column is part of primary key")
 	}
 	if isPartOfSecondaryIndex, _ := isPartOfSecondaryIndex(colName, table); isPartOfSecondaryIndex {
-		return fmt.Errorf("column is part of secondary index, remove secondary index before making the update"), http.StatusPreconditionFailed
+		return http.StatusPreconditionFailed, fmt.Errorf("column is part of secondary index, remove secondary index before making the update")
 	}
 	isPartOfFK := isPartOfFK(colName, table)
 	isReferencedByFK, _ := isReferencedByFK(colName, table)
 	if isPartOfFK || isReferencedByFK {
-		return fmt.Errorf("column is part of foreign key relation, remove foreign key constraint before making the update"), http.StatusPreconditionFailed
+		return http.StatusPreconditionFailed, fmt.Errorf("column is part of foreign key relation, remove foreign key constraint before making the update")
 	}
-	return nil, http.StatusOK
+	return http.StatusOK, nil
 }
 
-func canRenameOrChangeType(colName, table string) (error, int) {
+func canRenameOrChangeType(colName, table string) (int, error) {
 	isPartOfPK := isPartOfPK(colName, table)
 	isParent, childSchema := isParent(table)
 	isChild := sessionState.conv.SpSchema[table].Parent != ""
 	if isPartOfPK && (isParent || isChild) {
-		return fmt.Errorf("Column : '%s' in table : '%s' is part of parent-child relation with schema : '%s'", colName, table, childSchema), http.StatusBadRequest
+		return http.StatusBadRequest, fmt.Errorf("column : '%s' in table : '%s' is part of parent-child relation with schema : '%s'", colName, table, childSchema)
 	}
 	if isPartOfSecondaryIndex, indexName := isPartOfSecondaryIndex(colName, table); isPartOfSecondaryIndex {
-		return fmt.Errorf("Column : '%s' in table : '%s' is part of secondary index : '%s', remove secondary index before making the update",
-			colName, table, indexName), http.StatusPreconditionFailed
+		return http.StatusPreconditionFailed, fmt.Errorf("column : '%s' in table : '%s' is part of secondary index : '%s', remove secondary index before making the update",
+			colName, table, indexName)
 	}
 	isPartOfFK := isPartOfFK(colName, table)
 	isReferencedByFK, relationTable := isReferencedByFK(colName, table)
 	if isPartOfFK || isReferencedByFK {
 		if isReferencedByFK {
-			return fmt.Errorf("Column : '%s' in table : '%s' is part of foreign key relation with table : '%s', remove foreign key constraint before making the update",
-				colName, table, relationTable), http.StatusPreconditionFailed
-		} else {
-			return fmt.Errorf("Column : '%s' in table : '%s' is part of foreign keys, remove foreign key constraint before making the update",
-				colName, table), http.StatusPreconditionFailed
+			return http.StatusPreconditionFailed, fmt.Errorf("column : '%s' in table : '%s' is part of foreign key relation with table : '%s', remove foreign key constraint before making the update",
+				colName, table, relationTable)
 		}
+		return http.StatusPreconditionFailed, fmt.Errorf("column : '%s' in table : '%s' is part of foreign keys, remove foreign key constraint before making the update",
+			colName, table)
 	}
-	return nil, http.StatusOK
+	return http.StatusOK, nil
 }
 
 func checkPrimaryKeyPrefix(table string, refTable string, fk ddl.Foreignkey, tableInterleaveStatus *TableInterleaveStatus) bool {
@@ -1102,6 +1101,7 @@ func getFilePrefix(now time.Time) (string, error) {
 	return dbName + ".", nil
 }
 
+// SessionState stores information for the current migration session.
 type SessionState struct {
 	sourceDB    *sql.DB        // Connection to source database in case of direct connection
 	dbName      string         // Name of source database
@@ -1160,7 +1160,8 @@ func init() {
 	sessionState.conv = internal.MakeConv()
 }
 
-func WebApp() {
+// App connects to the web app.
+func App() {
 	addr := ":8080"
 	router := getRoutes()
 	log.Printf("Starting server at port 8080\n")


Test patch:
diff --git a/internal/mapping_test.go b/internal/mapping_test.go
index c739261..07424ce 100644
--- a/internal/mapping_test.go
+++ b/internal/mapping_test.go
@@ -111,7 +111,7 @@ func TestToSpannerForeignKey(t *testing.T) {
 	}
 }
 
-func TestGetSpannerId(t *testing.T) {
+func TestGetSpannerID(t *testing.T) {
 	conv := MakeConv()
 	basicTests := []struct {
 		name       string // Name of test.
@@ -134,7 +134,7 @@ func TestGetSpannerId(t *testing.T) {
 		{"Bad name with different case collision", "IN\tDex", "IN_Dex_13"},
 	}
 	for _, tc := range basicTests {
-		spKeyName := getSpannerId(conv, tc.srcKeyName)
+		spKeyName := getSpannerID(conv, tc.srcKeyName)
 		assert.Equal(t, tc.spKeyName, spKeyName, tc.name)
 	}
 }
diff --git a/sources/mysql/data_test.go b/sources/mysql/data_test.go
index 930278b..55223e2 100644
--- a/sources/mysql/data_test.go
+++ b/sources/mysql/data_test.go
@@ -88,7 +88,7 @@ func TestConvertData(t *testing.T) {
 		{"string", ddl.Type{Name: ddl.String, Len: ddl.MaxLength}, "", "eh", "eh"},
 		{"datetime", ddl.Type{Name: ddl.Timestamp}, "datetime", "2019-10-29 05:30:00", getTimeWithoutTimezone(t, "2019-10-29 05:30:00")},
 		{"timestamp", ddl.Type{Name: ddl.Timestamp}, "timestamp", "2019-10-29 05:30:00", getTime(t, "2019-10-29T05:30:00+05:30")},
-		{"json", ddl.Type{Name: ddl.Json}, "", "{\"key1\": \"value1\"}", "{\"key1\": \"value1\"}"},
+		{"json", ddl.Type{Name: ddl.JSON}, "", "{\"key1\": \"value1\"}", "{\"key1\": \"value1\"}"},
 		{"string array(set)", ddl.Type{Name: ddl.String, Len: ddl.MaxLength, IsArray: true}, "", "1,Travel,3,Dance", []spanner.NullString{
 			spanner.NullString{StringVal: "1", Valid: true},
 			spanner.NullString{StringVal: "Travel", Valid: true},
diff --git a/sources/mysql/toddl_test.go b/sources/mysql/toddl_test.go
index 171fcd7..c849d57 100644
--- a/sources/mysql/toddl_test.go
+++ b/sources/mysql/toddl_test.go
@@ -80,7 +80,7 @@ func TestToSpannerType(t *testing.T) {
 			"d": ddl.ColumnDef{Name: "d", T: ddl.Type{Name: ddl.String, Len: int64(6)}},
 			"e": ddl.ColumnDef{Name: "e", T: ddl.Type{Name: ddl.Numeric}},
 			"f": ddl.ColumnDef{Name: "f", T: ddl.Type{Name: ddl.Timestamp}},
-			"g": ddl.ColumnDef{Name: "g", T: ddl.Type{Name: ddl.Json}},
+			"g": ddl.ColumnDef{Name: "g", T: ddl.Type{Name: ddl.JSON}},
 		},
 		Pks: []ddl.IndexKey{ddl.IndexKey{Col: "a"}},
 		Fks: []ddl.Foreignkey{ddl.Foreignkey{Name: "fk_test", Columns: []string{"d"}, ReferTable: "ref_table", ReferColumns: []string{"dref"}},
diff --git a/sources/postgres/pgdump_test.go b/sources/postgres/pgdump_test.go
index d74f8a0..57c65ed 100644
--- a/sources/postgres/pgdump_test.go
+++ b/sources/postgres/pgdump_test.go
@@ -70,8 +70,8 @@ func TestProcessPgDump(t *testing.T) {
 		{"timestamptz(5)", ddl.Type{Name: ddl.Timestamp}},
 		{"varchar", ddl.Type{Name: ddl.String, Len: ddl.MaxLength}},
 		{"varchar(42)", ddl.Type{Name: ddl.String, Len: int64(42)}},
-		{"json", ddl.Type{Name: ddl.Json}},
-		{"jsonb", ddl.Type{Name: ddl.Json}},
+		{"json", ddl.Type{Name: ddl.JSON}},
+		{"jsonb", ddl.Type{Name: ddl.JSON}},
 	}
 	for _, tc := range scalarTests {
 		conv, _ := runProcessPgDump(fmt.Sprintf("CREATE TABLE t (a %s);", tc.ty))
@@ -1503,7 +1503,7 @@ func runProcessPgDump(s string) (*internal.Conv, []spannerData) {
 
 func runProcessPgDumpPGTarget(s string) (*internal.Conv, []spannerData) {
 	conv := internal.MakeConv()
-	conv.TargetDb = constants.TARGET_EXPERIMENTAL_POSTGRES
+	conv.TargetDb = constants.TargetExperimentalPostgres
 	conv.SetLocation(time.UTC)
 	conv.SetSchemaMode()
 	pgDump := DbDumpImpl{}
diff --git a/sources/postgres/toddl_test.go b/sources/postgres/toddl_test.go
index 0552f6c..0cc9bce 100644
--- a/sources/postgres/toddl_test.go
+++ b/sources/postgres/toddl_test.go
@@ -103,7 +103,7 @@ func TestToSpannerType(t *testing.T) {
 func TestToExperimentalSpannerType(t *testing.T) {
 	conv := internal.MakeConv()
 	conv.SetSchemaMode()
-	conv.TargetDb = constants.TARGET_EXPERIMENTAL_POSTGRES
+	conv.TargetDb = constants.TargetExperimentalPostgres
 	name := "test"
 	srcSchema := schema.Table{
 		Name:     name,
diff --git a/spanner/ddl/ast_test.go b/spanner/ddl/ast_test.go
index f605a05..cfaafce 100644
--- a/spanner/ddl/ast_test.go
+++ b/spanner/ddl/ast_test.go
@@ -91,7 +91,7 @@ func TestPrintColumnDefPG(t *testing.T) {
 		{in: ColumnDef{Name: "col1", T: Type{Name: Int64}}, protectIds: true, expected: "`col1` INT8"},
 	}
 	for _, tc := range tests {
-		s, _ := tc.in.PrintColumnDef(Config{ProtectIds: tc.protectIds, TargetDb: constants.TARGET_EXPERIMENTAL_POSTGRES})
+		s, _ := tc.in.PrintColumnDef(Config{ProtectIds: tc.protectIds, TargetDb: constants.TargetExperimentalPostgres})
 		assert.Equal(t, tc.expected, s)
 	}
 }
@@ -108,7 +108,7 @@ func TestPrintIndexKey(t *testing.T) {
 	}
 	for _, tc := range tests {
 		assert.Equal(t, tc.expected, tc.in.PrintIndexKey(Config{ProtectIds: tc.protectIds}))
-		assert.Equal(t, tc.expected, tc.in.PrintIndexKey(Config{ProtectIds: tc.protectIds, TargetDb: constants.TARGET_EXPERIMENTAL_POSTGRES}))
+		assert.Equal(t, tc.expected, tc.in.PrintIndexKey(Config{ProtectIds: tc.protectIds, TargetDb: constants.TargetExperimentalPostgres}))
 	}
 }
 
@@ -246,7 +246,7 @@ func TestPrintCreateTablePG(t *testing.T) {
 		},
 	}
 	for _, tc := range tests {
-		assert.Equal(t, tc.expected, tc.ct.PrintCreateTable(Config{ProtectIds: tc.protectIds, TargetDb: constants.TARGET_EXPERIMENTAL_POSTGRES}))
+		assert.Equal(t, tc.expected, tc.ct.PrintCreateTable(Config{ProtectIds: tc.protectIds, TargetDb: constants.TargetExperimentalPostgres}))
 	}
 }
 
@@ -276,7 +276,7 @@ func TestPrintCreateIndex(t *testing.T) {
 	}
 	for _, tc := range tests {
 		assert.Equal(t, tc.expected, tc.index.PrintCreateIndex(Config{ProtectIds: tc.protectIds}))
-		assert.Equal(t, tc.expected, tc.index.PrintCreateIndex(Config{ProtectIds: tc.protectIds, TargetDb: constants.TARGET_EXPERIMENTAL_POSTGRES}))
+		assert.Equal(t, tc.expected, tc.index.PrintCreateIndex(Config{ProtectIds: tc.protectIds, TargetDb: constants.TargetExperimentalPostgres}))
 	}
 }
 
@@ -307,7 +307,7 @@ func TestPrintForeignKey(t *testing.T) {
 	}
 	for _, tc := range tests {
 		assert.Equal(t, tc.expected, tc.fk.PrintForeignKey(Config{ProtectIds: tc.protectIds}))
-		assert.Equal(t, tc.expected, tc.fk.PrintForeignKey(Config{ProtectIds: tc.protectIds, TargetDb: constants.TARGET_EXPERIMENTAL_POSTGRES}))
+		assert.Equal(t, tc.expected, tc.fk.PrintForeignKey(Config{ProtectIds: tc.protectIds, TargetDb: constants.TargetExperimentalPostgres}))
 	}
 }
 
@@ -339,7 +339,7 @@ func TestPrintForeignKeyAlterTable(t *testing.T) {
 	}
 	for _, tc := range tests {
 		assert.Equal(t, tc.expected, tc.fk.PrintForeignKeyAlterTable(Config{ProtectIds: tc.protectIds}, tc.table))
-		assert.Equal(t, tc.expected, tc.fk.PrintForeignKeyAlterTable(Config{ProtectIds: tc.protectIds, TargetDb: constants.TARGET_EXPERIMENTAL_POSTGRES}, tc.table))
+		assert.Equal(t, tc.expected, tc.fk.PrintForeignKeyAlterTable(Config{ProtectIds: tc.protectIds, TargetDb: constants.TargetExperimentalPostgres}, tc.table))
 	}
 }
 
@@ -473,7 +473,7 @@ func TestGetPGDDL(t *testing.T) {
 		Fks:    []Foreignkey{{Name: "fk3", Columns: []string{"c"}, ReferTable: "ref_table3", ReferColumns: []string{"ref_c"}}},
 		Parent: "table1",
 	}
-	tablesOnly := s.GetDDL(Config{Tables: true, ForeignKeys: false, TargetDb: constants.TARGET_EXPERIMENTAL_POSTGRES})
+	tablesOnly := s.GetDDL(Config{Tables: true, ForeignKeys: false, TargetDb: constants.TargetExperimentalPostgres})
 	e := []string{
 		"CREATE TABLE table1 (\n" +
 			"	a INT8,\n" +
@@ -497,7 +497,7 @@ func TestGetPGDDL(t *testing.T) {
 	}
 	assert.ElementsMatch(t, e, tablesOnly)
 
-	fksOnly := s.GetDDL(Config{Tables: false, ForeignKeys: true, TargetDb: constants.TARGET_EXPERIMENTAL_POSTGRES})
+	fksOnly := s.GetDDL(Config{Tables: false, ForeignKeys: true, TargetDb: constants.TargetExperimentalPostgres})
 	e2 := []string{
 		"ALTER TABLE table1 ADD CONSTRAINT fk1 FOREIGN KEY (b) REFERENCES ref_table1 (ref_b)",
 		"ALTER TABLE table2 ADD CONSTRAINT fk2 FOREIGN KEY (b, c) REFERENCES ref_table2 (ref_b, ref_c)",
@@ -505,7 +505,7 @@ func TestGetPGDDL(t *testing.T) {
 	}
 	assert.ElementsMatch(t, e2, fksOnly)
 
-	tablesAndFks := s.GetDDL(Config{Tables: true, ForeignKeys: true, TargetDb: constants.TARGET_EXPERIMENTAL_POSTGRES})
+	tablesAndFks := s.GetDDL(Config{Tables: true, ForeignKeys: true, TargetDb: constants.TargetExperimentalPostgres})
 	e3 := []string{
 		"CREATE TABLE table1 (\n" +
 			"	a INT8,\n" +