Merging master onto the feat/more-cfg
diff --git a/LICENSE b/LICENSE
index 5af85b0..f342051 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 Glide
 The Masterminds
-Copyright (C) 2014-2015, Matt Butcher and Matt Farina
+Copyright (C) 2014-2016, Matt Butcher and Matt Farina
 Copyright (C) 2015, Google
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/cfg/cfg.go b/cfg/cfg.go
index 52874d2..e370c13 100644
--- a/cfg/cfg.go
+++ b/cfg/cfg.go
@@ -1,2 +1,6 @@
 // Package cfg handles working with the Glide configuration files.
+//
+// The cfg package contains the ability to parse (unmarshal) and write (marshal)
+// glide.yaml and glide.lock files. These files contains the details about
+// projects managed by Glide.
 package cfg
diff --git a/cfg/config.go b/cfg/config.go
index cca4072..2aea716 100644
--- a/cfg/config.go
+++ b/cfg/config.go
@@ -14,18 +14,52 @@
 
 // Config is the top-level configuration object.
 type Config struct {
-	Name       string       `yaml:"package"`
-	Ignore     []string     `yaml:"ignore,omitempty"`
-	Imports    Dependencies `yaml:"import"`
+
+	// Name is the name of the package or application.
+	Name string `yaml:"package"`
+
+	// Description is a short description for a package, application, or library.
+	// This description is similar but different to a Go package description as
+	// it is for marketing and presentation purposes rather than technical ones.
+	Description string `json:"description,omitempty"`
+
+	// Home is a url to a website for the package.
+	Home string `yaml:"homepage,omitempty"`
+
+	// License provides either a SPDX license or a path to a file containing
+	// the license. For more information on SPDX see http://spdx.org/licenses/.
+	// When more than one license an SPDX expression can be used.
+	License string `yaml:"license,omitempty"`
+
+	// Owners is an array of owners for a project. See the Owner type for
+	// more detail. These can be one or more people, companies, or other
+	// organizations.
+	Owners Owners `yaml:"owners,omitempty"`
+
+	// Ignore contains a list of packages to ignore fetching. This is useful
+	// when walking the package tree (including packages of packages) to list
+	// those to skip.
+	Ignore []string `yaml:"ignore,omitempty"`
+
+	// Imports contains a list of all non-development imports for a project. For
+	// more detail on how these are captured see the Dependency type.
+	Imports Dependencies `yaml:"import"`
+
+	// DevImports contains the test or other development imports for a project.
+	// See the Dependency type for more details on how this is recorded.
 	DevImports Dependencies `yaml:"devimport,omitempty"`
 }
 
 // A transitive representation of a dependency for importing and exporting to yaml.
 type cf struct {
-	Name       string       `yaml:"package"`
-	Ignore     []string     `yaml:"ignore,omitempty"`
-	Imports    Dependencies `yaml:"import"`
-	DevImports Dependencies `yaml:"devimport,omitempty"`
+	Name        string       `yaml:"package"`
+	Description string       `yaml:"description,omitempty"`
+	Home        string       `yaml:"homepage,omitempty"`
+	License     string       `yaml:"license,omitempty"`
+	Owners      Owners       `yaml:"owners,omitempty"`
+	Ignore      []string     `yaml:"ignore,omitempty"`
+	Imports     Dependencies `yaml:"import"`
+	DevImports  Dependencies `yaml:"devimport,omitempty"`
 }
 
 // ConfigFromYaml returns an instance of Config from YAML
@@ -51,6 +85,10 @@
 		return err
 	}
 	c.Name = newConfig.Name
+	c.Description = newConfig.Description
+	c.Home = newConfig.Home
+	c.License = newConfig.License
+	c.Owners = newConfig.Owners
 	c.Ignore = newConfig.Ignore
 	c.Imports = newConfig.Imports
 	c.DevImports = newConfig.DevImports
@@ -64,8 +102,12 @@
 // MarshalYAML is a hook for gopkg.in/yaml.v2 in the marshaling process
 func (c *Config) MarshalYAML() (interface{}, error) {
 	newConfig := &cf{
-		Name:   c.Name,
-		Ignore: c.Ignore,
+		Name:        c.Name,
+		Description: c.Description,
+		Home:        c.Home,
+		License:     c.License,
+		Owners:      c.Owners,
+		Ignore:      c.Ignore,
 	}
 	i, err := c.Imports.Clone().DeDupe()
 	if err != nil {
@@ -116,6 +158,10 @@
 func (c *Config) Clone() *Config {
 	n := &Config{}
 	n.Name = c.Name
+	n.Description = c.Description
+	n.Home = c.Home
+	n.License = c.License
+	n.Owners = c.Owners.Clone()
 	n.Ignore = c.Ignore
 	n.Imports = c.Imports.Clone()
 	n.DevImports = c.DevImports.Clone()
@@ -408,6 +454,42 @@
 	return false
 }
 
+// Owners is a list of owners for a project.
+type Owners []*Owner
+
+// Clone performs a deep clone of Owners
+func (o Owners) Clone() Owners {
+	n := make(Owners, 0, 1)
+	for _, v := range o {
+		n = append(n, v.Clone())
+	}
+	return n
+}
+
+// Owner describes an owner of a package. This can be a person, company, or
+// other organization. This is useful if someone needs to contact the
+// owner of a package to address things like a security issue.
+type Owner struct {
+
+	// Name describes the name of an organization.
+	Name string `yaml:"name,omitempty"`
+
+	// Email is an email address to reach the owner at.
+	Email string `yaml:"email,omitempty"`
+
+	// Home is a url to a website for the owner.
+	Home string `yaml:"homepage,omitempty"`
+}
+
+// Clone creates a clone of a Dependency
+func (o *Owner) Clone() *Owner {
+	return &Owner{
+		Name:  o.Name,
+		Email: o.Email,
+		Home:  o.Home,
+	}
+}
+
 func stringArrayDeDupe(s []string, items ...string) []string {
 	for _, item := range items {
 		exists := false
diff --git a/cfg/config_test.go b/cfg/config_test.go
index 03ba08e..06ade6d 100644
--- a/cfg/config_test.go
+++ b/cfg/config_test.go
@@ -8,6 +8,13 @@
 
 var yml = `
 package: fake/testing
+description: foo bar baz
+homepage: https://example.com
+license: MIT
+owners:
+- name: foo
+  email: bar@example.com
+  homepage: https://example.com
 import:
   - package: github.com/kylelemons/go-gypsy
     subpackages:
@@ -45,6 +52,18 @@
 		t.Errorf("Inaccurate name found %s", cfg.Name)
 	}
 
+	if cfg.Description != "foo bar baz" {
+		t.Errorf("Inaccurate description found %s", cfg.Description)
+	}
+
+	if cfg.Home != "https://example.com" {
+		t.Errorf("Inaccurate homepage found %s", cfg.Home)
+	}
+
+	if cfg.License != "MIT" {
+		t.Errorf("Inaccurate license found %s", cfg.License)
+	}
+
 	found := false
 	found2 := false
 	for _, i := range cfg.Imports {
@@ -82,6 +101,9 @@
 	if cfg2.Name != "fake/testing" {
 		t.Error("Config cloning failed")
 	}
+	if cfg2.License != "MIT" {
+		t.Error("Config cloning failed to copy License")
+	}
 	cfg.Name = "foo"
 
 	if cfg.Name == cfg2.Name {
@@ -114,3 +136,43 @@
 		t.Error("HasDependency picking up dependency it shouldn't")
 	}
 }
+
+func TestOwners(t *testing.T) {
+	o := new(Owner)
+	o.Name = "foo"
+	o.Email = "foo@example.com"
+	o.Home = "https://foo.example.com"
+
+	o2 := o.Clone()
+	if o2.Name != o.Name || o2.Email != o.Email || o2.Home != o.Home {
+		t.Error("Unable to clone Owner")
+	}
+
+	o.Name = "Bar"
+	if o.Name == o2.Name {
+		t.Error("Owner clone is a pointer instead of a clone")
+	}
+
+	s := make(Owners, 0, 1)
+	s = append(s, o)
+	s2 := s.Clone()
+	o3 := s2[0]
+
+	o3.Name = "Qux"
+
+	if o3.Name == o.Name {
+		t.Error("Owners cloning isn't deep")
+	}
+
+	cfg := &Config{}
+	err := yaml.Unmarshal([]byte(yml), &cfg)
+	if err != nil {
+		t.Errorf("Unable to Unmarshal config yaml")
+	}
+
+	if cfg.Owners[0].Name != "foo" ||
+		cfg.Owners[0].Email != "bar@example.com" ||
+		cfg.Owners[0].Home != "https://example.com" {
+		t.Error("Unable to parse owners from yaml")
+	}
+}