repo: Prevent cleaning a new repository

After creating keys in a new repository, repo.Clean would remove the
staged root.json, rendering the keys unusable.

Given Clean is only useful to reset the state to what is committed, it
only makes sense to call it when something has been committed already,
so this change prevents cleaning a new repository.

Signed-off-by: Lewis Marshall <lewis@lmars.net>
diff --git a/cmd/tuf/clean.go b/cmd/tuf/clean.go
index 650489e..39f62d0 100644
--- a/cmd/tuf/clean.go
+++ b/cmd/tuf/clean.go
@@ -1,6 +1,9 @@
 package main
 
 import (
+	"fmt"
+	"os"
+
 	"github.com/flynn/go-tuf"
 	"github.com/flynn/go-tuf/Godeps/_workspace/src/github.com/flynn/go-docopt"
 )
@@ -14,5 +17,10 @@
 }
 
 func cmdClean(args *docopt.Args, repo *tuf.Repo) error {
-	return repo.Clean()
+	err := repo.Clean()
+	if err == tuf.ErrNewRepository {
+		fmt.Fprintln(os.Stderr, "tuf: refusing to clean new repository")
+		return nil
+	}
+	return err
 }
diff --git a/errors.go b/errors.go
index 3b11904..c471dc4 100644
--- a/errors.go
+++ b/errors.go
@@ -6,7 +6,10 @@
 	"time"
 )
 
-var ErrInitNotAllowed = errors.New("tuf: repository already initialized")
+var (
+	ErrInitNotAllowed = errors.New("tuf: repository already initialized")
+	ErrNewRepository  = errors.New("tuf: repository not yet committed")
+)
 
 type ErrMissingMetadata struct {
 	Name string
diff --git a/local_store.go b/local_store.go
index 8d7fb1c..c151ef3 100644
--- a/local_store.go
+++ b/local_store.go
@@ -400,6 +400,12 @@
 }
 
 func (f *fileSystemStore) Clean() error {
+	_, err := os.Stat(filepath.Join(f.repoDir(), "root.json"))
+	if os.IsNotExist(err) {
+		return ErrNewRepository
+	} else if err != nil {
+		return err
+	}
 	if err := os.RemoveAll(f.stagedDir()); err != nil {
 		return err
 	}
diff --git a/repo_test.go b/repo_test.go
index e407ab0..af024b7 100644
--- a/repo_test.go
+++ b/repo_test.go
@@ -491,6 +491,9 @@
 	// don't use consistent snapshots to make the checks simpler
 	c.Assert(r.Init(false), IsNil)
 
+	// cleaning with nothing staged or committed should fail
+	c.Assert(r.Clean(), Equals, ErrNewRepository)
+
 	// generating keys should stage root.json and create repo dirs
 	genKey(c, r, "root")
 	genKey(c, r, "targets")
@@ -500,6 +503,9 @@
 	tmp.assertEmpty("repository")
 	tmp.assertEmpty("staged/targets")
 
+	// cleaning with nothing committed should fail
+	c.Assert(r.Clean(), Equals, ErrNewRepository)
+
 	// adding a non-existent file fails
 	c.Assert(r.AddTarget("foo.txt", nil), Equals, ErrFileNotFound{tmp.stagedTargetPath("foo.txt")})
 	tmp.assertEmpty("repository")