Repository: onflow/flow-cli
Pull request #66 (2021-02-19 20:12:33)

Rename deployment fix
Changes `deploy` to `deployments` as it is more clear
______

For contributor use:

- [ ] Targeted PR against `master` branch
- [ ] Linked to Github issue with discussion and accepted design OR link to spec that describes this work
- [ ] Code follows the [standards mentioned here](https://github.com/onflow/flow-cli/blob/master/CONTRIBUTING.md#styleguides)
- [ ] Updated relevant documentation
- [ ] Re-reviewed `Files changed` in the Github PR explorer
- [ ] Added appropriate labels



Patch:
diff --git a/docs/deploy-project-contracts.md b/docs/deploy-project-contracts.md
new file mode 100644
index 00000000..1cf3cc06
--- /dev/null
+++ b/docs/deploy-project-contracts.md
@@ -0,0 +1,111 @@
+---
+title: Deploy a Flow Project
+sidebar_title: Deploy a Project
+description: How to deploy Flow project contracts with the CLI
+---
+
+⚠️ _Warning: CLI projects are an experimental feature. Functionality is subject to change._
+
+```shell
+flow project deploy
+```
+
+This command automatically deploys your project's contracts based on the 
+configuration defined in your `flow.json` file.
+
+Before using this command, read about how to 
+[configure project contracts and deployment targets](https://docs.onflow.org/flow-cli/project-contracts/).
+
+## Example Usage
+
+```shell
+# Deploy project contracts to all Testnet targets
+> flow project deploy --network=testnet
+
+NonFungibleToken -> 0xf8d6e0586b0a20c7
+FungibleToken -> 0xf8d6e0586b0a20c7
+Kibble -> 0xf8d6e0586b0a20c7
+
+✅ All contracts deployed successfully
+```
+
+In the example above, your `flow.json` file might look something like this:
+
+```json
+{
+  "contracts": {
+    "Foo": "./cadence/contracts/FooContract.cdc",
+    "Bar": "./cadence/contracts/BarContract.cdc"
+  },
+  "deployments": {
+    "testnet": {
+      "my-testnet-account": ["Foo", "Bar"]
+    }
+  }
+}
+```
+
+Here's a sketch of the contract source files:
+
+```cadence:title=Foo.cdc
+pub contract Foo { 
+  // ...
+}
+```
+
+```cadence:title=Bar.cdc
+import Foo from Foo.cdc
+
+pub contract Bar { 
+  // ...
+}
+```
+
+## Dependency Resolution
+
+The `deploy` command attempts to resolve the import statements in all contracts being deployed.
+
+After the dependencies are found, the CLI will deploy the contracts in a deterministic order
+such that no contract is deployed until all of its dependencies are deployed.
+The command will return an error if no such ordering exists due to one or more cyclic dependencies.
+
+In the example above, `Foo` will always be deployed before `Bar`.
+
+## Address Replacement
+
+After resolving all dependencies, the `deploy` command rewrites each contract so 
+that its dependencies are imported from their _target addresses_ rather than their 
+source file location.
+
+The rewritten versions are then deployed to their respective targets,
+leaving the original contract files unchanged.
+
+In the example above, the `Bar` contract would be rewritten like this:
+
+```cadence:title=Bar.cdc
+import Foo from 0xf8d6e0586b0a20c7
+
+pub contract Bar { 
+  // ...
+}
+```
+
+## Options
+
+### Network
+
+- Flag: `--network`
+- Valid inputs: the name of a network configured in `flow.json`
+- Default: `emulator`
+
+Specify which network you want to deploy the project contracts to.
+
+### Allow Updates
+
+- Flag: `--update`
+- Valid inputs: `true`, `false`
+- Default: `false`
+
+Indicate whether to overwrite and upgrade existing contracts.
+
+⚠️ _Warning: contract upgrades are a dangerous experimental feature._
diff --git a/docs/initialize-project.md b/docs/initialize-project.md
new file mode 100644
index 00000000..f3b7fc06
--- /dev/null
+++ b/docs/initialize-project.md
@@ -0,0 +1,266 @@
+---
+title: Initialize a Flow Project
+sidebar_title: Initialize a Project
+description: How to initialize a new Flow project with the CLI
+---
+
+⚠️ _Warning: CLI projects are an experimental feature. Functionality is subject to change._
+
+```shell
+flow project init
+```
+
+This command initializes an empty Flow project by creating a `flow.json` file
+in the current directory.
+
+The new `flow.json` file will contain the following:
+- A `networks` list pre-populated with the Flow Emulator connection configuration.
+- An `accounts` list pre-populated with the Flow Emulator service account.
+- An `emulators` list pre-populated with Flow Emulator configuration.
+- A `deployments` empty object where all [deployment targets](https://docs.onflow.org/flow-cli/project-contracts/) can be defined. 
+- A `contracts` empty object where you [define contracts](https://docs.onflow.org/flow-cli/project-contracts/) you wish to deploy.
+
+## Example Project Configuration
+
+```json
+{
+  "emulators": {
+    "default": {
+      "port": 3569,
+      "serviceAccount": "emulator-account"
+    }
+  },
+  "networks": {
+    "emulator": {
+      "host": "127.0.0.1:3569",
+      "chain": "flow-emulator"
+    }
+  },
+  "accounts": {
+    "emulator-account": {
+      "address": "f8d6e0586b0a20c7",
+      "keys": "ae1b44c0f5e8f6992ef2348898a35e50a8b0b9684000da8b1dade1b3bcd6ebee",
+      "chain": "flow-emulator"
+    }
+  },
+  "deployments": {},
+  "contracts": {}
+}
+```
+
+## Configuration
+
+Below is an example of a configuration file for a complete Flow project.
+We'll walk through each property one by one.
+
+```
+{
+  "contracts": {
+    "NonFungibleToken": "./cadence/contracts/NonFungibleToken.cdc",
+    "Kibble": "./cadence/contracts/Kibble.cdc",
+    "KittyItems": "./cadence/contracts/KittyItems.cdc",
+    "KittyItemsMarket": "./cadence/contracts/KittyItemsMarket.cdc",
+    "FungibleToken": {
+      "source": "./cadence/contracts/NonFungibleToken.cdc",
+      "aliases": {
+        "testnet": "12f54cb6e3f42a14"
+      }
+    }
+  },
+
+  "deployments": {
+    "testnet": {
+      "admin-account": ["NonFungibleToken"],
+      "user-account": ["Kibble", "KittyItems", "KittyItemsMarket"]
+    }, 
+    "emulator": {
+      "emulator-account": [
+        "NonFungibleToken",
+        "FungibleToken",
+        "Kibble",
+        "KittyItems",
+        "KittyItemsMarket"
+      ]
+    }
+  },
+
+  "accounts": {
+    "admin-account": {
+      "address": "3ae53cb6e3f42a79",
+      "keys": "22232967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"
+    },
+    "user-account": {
+      "address": "e2a8b7f23e8b548f",
+      "keys": "22232967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"
+    },
+    "emulator-account": {
+      "address": "f8d6e0586b0a20c7",
+      "keys": "2eae2f31cb5b756151fa11d82949c634b8f28796a711d7eb1e52cc301edfb3e0",
+      "chain": "flow-emulator"
+    }
+  },
+
+  "networks": {
+    "emulator": {
+      "host": "127.0.0.1:3569",
+      "serviceAccount": "emulator-service"
+    },
+    "testnet": "access.testnet.nodes.onflow.org:9000"
+  }
+}
+```
+
+### Contracts
+
+Contracts are specified as key-value pairs, where the key is the contract name, 
+and the value is the location of the Cadence source code.
+
+The advanced format allows us to specify aliases for each network.
+
+#### Simple Format 
+
+```
+...
+
+"contracts": {
+  "NonFungibleToken": "./cadence/contracts/NonFungibleToken.cdc"
+}
+
+...
+```
+
+#### Advanced Format 
+
+Using advanced format we can define `aliases`. Aliases define an address where the contract is already deployed for that specific network. 
+In the example scenario below the contract `FungibleToken` would be imported from the address `12f54cb6e3f42a14` when deploying to testnet network. 
+We can specify aliases for each network we have defined. When deploying to testnet it is always a good idea to specify aliases for all the [common 
+contracts](https://docs.onflow.org/core-contracts) that have already been deployed to the testnet.
+
+```
+...
+
+"FungibleToken": {
+  "source": "./cadence/contracts/NonFungibleToken.cdc",
+  "aliases": {
+    "testnet": "12f54cb6e3f42a14"
+  }
+}
+
+...
+```
+
+### Accounts
+
+The accounts section is used to define account properties such as keys and addresses. 
+Each account must include a name, which is then referenced throughout the configuration file.
+
+#### Simple Format
+
+When using the simple format, simply specify the address for the account and a single hex-encoded
+private key.
+
+```
+...
+
+"accounts": {
+  "admin-account": {
+    "address": "f8d6e0586b0a20c7",
+    "keys": "22232967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"
+  }
+}
+
+...
+```
+
+#### Advanced format
+
+The advanced format allows us to define more properties for the account. 
+We can define the signature algorithm and hashing algorithm, as well as custom key formats.
+
+Please note that we can use `service` for address in case the account is used on `emulator` network as this is a special 
+value that is defined on the run time to the default service address on the emulator network.
+
+```
+...
+
+"accounts": {
+  "admin-account": {
+    "address": "service",
+    "chain": "flow-emulator",
+    "keys": [
+      {
+        "type": "hex",
+        "index": 0,
+        "signatureAlgorithm": "ECDSA_P256",
+        "hashAlgorithm": "SHA3_256",
+        "context": {
+          "privateKey": "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"
+        }
+      },
+      {
+        "type": "hex",
+        "index": 1,
+        "signatureAlgorithm": "ECDSA_P256",
+        "hashAlgorithm": "SHA3_256",
+        "context": {
+          "privateKey": "2372967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"
+        }
+      }
+    ]
+  }
+}
+
+...
+```
+
+### Deployments
+
+The deployments section defines where the `project deploy` command will deploy specified contracts. 
+This configuration property acts as the glue that ties together accounts, 
+contracts and networks, all of which are referenced by name.
+
+```
+...
+
+"deployments": {
+  "emulator": {
+    "emulator-account": [
+      "NonFungibleToken",
+      "FungibleToken",
+      "Kibble",
+      "KittyItems",
+      "KittyItemsMarket"
+    ]
+  },
+  "testnet": {
+    "admin-account": ["NonFungibleToken"],
+    "user-account": [
+      "Kibble",
+      "KittyItems",
+      "KittyItemsMarket"
+    ]
+  }
+}
+
+...
+```
+
+### Networks
+
+Use this section to define networks and connection parameters for that specific network. 
+
+#### Simple format
+
+```
+...
+
+"networks": {
+  "emulator": {
+    "host": "127.0.0.1:3569",
+    "serviceAccount": "emulator-service"
+  },
+  "testnet": "access.testnet.nodes.onflow.org:9000"
+}
+
+...
+```
diff --git a/docs/install.md b/docs/install.md
index 4f4e04a8..fe9feb0b 100644
--- a/docs/install.md
+++ b/docs/install.md
@@ -1,6 +1,6 @@
 ---
 title: Install the Flow CLI
-description: How to install the Flow command-line interface
+description: How to install the Flow command-line interface (CLI)
 ---
 
 The Flow CLI can be installed on macOS, Windows (7 or greater) and most Linux systems.
diff --git a/docs/project-contracts.md b/docs/project-contracts.md
new file mode 100644
index 00000000..dd1b5e12
--- /dev/null
+++ b/docs/project-contracts.md
@@ -0,0 +1,53 @@
+---
+title: Add Contracts to a Flow Project
+sidebar_title: Add Project Contracts
+description: How to define the Cadence contracts for Flow project
+---
+
+⚠️ _Warning: CLI projects are an experimental feature. Functionality is subject to change._
+
+## Add a Contract
+
+To add a contract to your project, update the `"contracts"` section of your `flow.json` file.
+
+Contracts are specified as key-value pairs, where the key is the contract name,
+and the value is the location of the Cadence source code.
+
+For example, the configuration below will register the 
+contract `Foo` from the `FooContract.cdc` file.
+
+```json
+{
+  "contracts": {
+    "Foo": "./cadence/contracts/FooContract.cdc"
+  }
+}
+```
+
+## Define Contract Deployment Targets
+
+Once a contract is added, it can then be assigned to one or more deployment targets.
+
+A deployment target is an account to which the contract will be deployed.
+In a typical project, a contract has one deployment target per network (e.g. Emulator, Testnet, Mainnet).
+
+Deployment targets are defined in the `"deployments"` section of your `flow.json` file.
+
+Targets are grouped by network, where each network is a mapping from target account to contract list. 
+Multiple contracts can be deployed to the same target account.
+
+For example, here's how we'd deploy contracts `Foo` and `Bar` to the account `my-testnet-account`:
+
+```json
+{
+  "contracts": {
+    "Foo": "./cadence/contracts/FooContract.cdc",
+    "Bar": "./cadence/contracts/BarContract.cdc"
+  },
+  "deployments": {
+    "testnet": {
+      "my-testnet-account": ["Foo", "Bar"]
+    }
+  }
+}
+```
diff --git a/flow/project/cli/config/config.go b/flow/project/cli/config/config.go
index 2ca1d7a1..2fbe8ccb 100644
--- a/flow/project/cli/config/config.go
+++ b/flow/project/cli/config/config.go
@@ -25,17 +25,17 @@ import (
 )
 
 type Config struct {
-	Emulators Emulators
-	Contracts Contracts
-	Networks  Networks
-	Accounts  Accounts
-	Deploys   Deploys
+	Emulators   Emulators
+	Contracts   Contracts
+	Networks    Networks
+	Accounts    Accounts
+	Deployments Deployments
 }
 
 type Contracts []Contract
 type Networks []Network
 type Accounts []Account
-type Deploys []Deploy
+type Deployments []Deploy
 type Emulators []Emulator
 
 // Network config sets host and chain id
@@ -146,15 +146,15 @@ func (a *Accounts) GetByAddress(address string) Account {
 	}).([]Account)[0]
 }
 
-// GetByNetwork get all deploys by network
-func (d *Deploys) GetByNetwork(network string) Deploys {
+// GetByNetwork get all deployments by network
+func (d *Deployments) GetByNetwork(network string) Deployments {
 	return funk.Filter([]Deploy(*d), func(d Deploy) bool {
 		return d.Network == network
 	}).([]Deploy)
 }
 
 // GetByAccountAndNetwork get deploy by account and network
-func (d *Deploys) GetByAccountAndNetwork(account string, network string) []Deploy {
+func (d *Deployments) GetByAccountAndNetwork(account string, network string) []Deploy {
 	return funk.Filter([]Deploy(*d), func(d Deploy) bool {
 		return d.Account == account && d.Network == network
 	}).([]Deploy)
diff --git a/flow/project/cli/config/json/config.go b/flow/project/cli/config/json/config.go
index 21a5d404..41f61c3e 100644
--- a/flow/project/cli/config/json/config.go
+++ b/flow/project/cli/config/json/config.go
@@ -29,30 +29,30 @@ import (
 )
 
 type jsonConfig struct {
-	Emulators jsonEmulators `json:"emulators"`
-	Contracts jsonContracts `json:"contracts"`
-	Networks  jsonNetworks  `json:"networks"`
-	Accounts  jsonAccounts  `json:"accounts"`
-	Deploys   jsonDeploys   `json:"deploys"`
+	Emulators   jsonEmulators   `json:"emulators"`
+	Contracts   jsonContracts   `json:"contracts"`
+	Networks    jsonNetworks    `json:"networks"`
+	Accounts    jsonAccounts    `json:"accounts"`
+	Deployments jsonDeployments `json:"deployments"`
 }
 
 func (j jsonConfig) transformToConfig() *config.Config {
 	return &config.Config{
-		Emulators: j.Emulators.transformToConfig(),
-		Contracts: j.Contracts.transformToConfig(),
-		Networks:  j.Networks.transformToConfig(),
-		Accounts:  j.Accounts.transformToConfig(),
-		Deploys:   j.Deploys.transformToConfig(),
+		Emulators:   j.Emulators.transformToConfig(),
+		Contracts:   j.Contracts.transformToConfig(),
+		Networks:    j.Networks.transformToConfig(),
+		Accounts:    j.Accounts.transformToConfig(),
+		Deployments: j.Deployments.transformToConfig(),
 	}
 }
 
 func transformConfigToJSON(config *config.Config) jsonConfig {
 	return jsonConfig{
-		Emulators: transformEmulatorsToJSON(config.Emulators),
-		Contracts: transformContractsToJSON(config.Contracts),
-		Networks:  transformNetworksToJSON(config.Networks),
-		Accounts:  transformAccountsToJSON(config.Accounts),
-		Deploys:   transformDeploysToJSON(config.Deploys),
+		Emulators:   transformEmulatorsToJSON(config.Emulators),
+		Contracts:   transformContractsToJSON(config.Contracts),
+		Networks:    transformNetworksToJSON(config.Networks),
+		Accounts:    transformAccountsToJSON(config.Accounts),
+		Deployments: transformDeploymentsToJSON(config.Deployments),
 	}
 }
 
diff --git a/flow/project/cli/config/json/deploy.go b/flow/project/cli/config/json/deploy.go
index a239e773..e3c02379 100644
--- a/flow/project/cli/config/json/deploy.go
+++ b/flow/project/cli/config/json/deploy.go
@@ -24,11 +24,11 @@ import (
 	"github.com/onflow/flow-cli/flow/project/cli/config"
 )
 
-type jsonDeploys map[string]jsonDeploy
+type jsonDeployments map[string]jsonDeploy
 
 // transformToConfig transforms json structures to config structure
-func (j jsonDeploys) transformToConfig() config.Deploys {
-	deploys := make(config.Deploys, 0)
+func (j jsonDeployments) transformToConfig() config.Deployments {
+	deployments := make(config.Deployments, 0)
 
 	for networkName, d := range j {
 		for accountName, contracts := range d.Simple {
@@ -38,22 +38,22 @@ func (j jsonDeploys) transformToConfig() config.Deploys {
 				Contracts: contracts,
 			}
 
-			deploys = append(deploys, deploy)
+			deployments = append(deployments, deploy)
 		}
 	}
 
-	return deploys
+	return deployments
 }
 
 // transformToJSON transforms config structure to json structures for saving
-func transformDeploysToJSON(deploys config.Deploys) jsonDeploys {
-	jsonDeploys := jsonDeploys{}
+func transformDeploymentsToJSON(deployments config.Deployments) jsonDeployments {
+	jsonDeployments := jsonDeployments{}
 
-	for _, d := range deploys {
-		if _, exists := jsonDeploys[d.Network]; exists {
-			jsonDeploys[d.Network].Simple[d.Account] = d.Contracts
+	for _, d := range deployments {
+		if _, exists := jsonDeployments[d.Network]; exists {
+			jsonDeployments[d.Network].Simple[d.Account] = d.Contracts
 		} else {
-			jsonDeploys[d.Network] = jsonDeploy{
+			jsonDeployments[d.Network] = jsonDeploy{
 				Simple: map[string][]string{
 					d.Account: d.Contracts,
 				},
@@ -61,7 +61,7 @@ func transformDeploysToJSON(deploys config.Deploys) jsonDeploys {
 		}
 	}
 
-	return jsonDeploys
+	return jsonDeployments
 }
 
 type Simple map[string][]string
diff --git a/flow/project/cli/project.go b/flow/project/cli/project.go
index 79bc0403..817f6130 100644
--- a/flow/project/cli/project.go
+++ b/flow/project/cli/project.go
@@ -165,8 +165,8 @@ func (p *Project) EmulatorServiceAccount() config.Account {
 func (p *Project) GetContractsByNetwork(network string) []Contract {
 	contracts := make([]Contract, 0)
 
-	// get deploys for specific network
-	for _, deploy := range p.conf.Deploys.GetByNetwork(network) {
+	// get deployments for specific network
+	for _, deploy := range p.conf.Deployments.GetByNetwork(network) {
 		account := p.GetAccountByName(deploy.Account)
 
 		// go through each contract for this deploy
diff --git a/flow/project/commands/deploy_contracts/deploy.go b/flow/project/commands/deploy_contracts/deploy.go
index 0295c4e2..2df2d1a7 100644
--- a/flow/project/commands/deploy_contracts/deploy.go
+++ b/flow/project/commands/deploy_contracts/deploy.go
@@ -59,7 +59,7 @@ var Cmd = &cobra.Command{
 
 		// check there are not multiple accounts with same contract
 		if project.ContractConflictExists(conf.Network) {
-			fmt.Println("\n❌ Currently it is not possible to deploy same contract with multiple accounts, please check Deploys in config and make sure contract is only present in one account")
+			fmt.Println("\n❌ Currently it is not possible to deploy same contract with multiple accounts, please check Deployments in config and make sure contract is only present in one account")
 			cli.Exit(1, "")
 			return
 		}


Test patch:
diff --git a/flow/project/cli/config/config_test.go b/flow/project/cli/config/config_test.go
index 32c2cb1b..b8159023 100644
--- a/flow/project/cli/config/config_test.go
+++ b/flow/project/cli/config/config_test.go
@@ -57,7 +57,7 @@ func generateComplexConfig() Config {
 			Source:  "0x123123123",
 			Network: "testnet",
 		}},
-		Deploys: Deploys{{
+		Deployments: Deployments{{
 			Network:   "emulator",
 			Account:   "emulator-account",
 			Contracts: []string{"KittyItems", "KittyItemsMarket"},
@@ -162,11 +162,11 @@ func Test_GetAccountByAddressComplex(t *testing.T) {
 	assert.Equal(t, acc2.Name, "account-2")
 }
 
-func Test_GetDeploysByNetworkComplex(t *testing.T) {
+func Test_GetDeploymentsByNetworkComplex(t *testing.T) {
 	conf := generateComplexConfig()
-	deploys := conf.Deploys.GetByAccountAndNetwork("account-2", "testnet")
+	deployments := conf.Deployments.GetByAccountAndNetwork("account-2", "testnet")
 
-	assert.Equal(t, deploys[0].Contracts, []string{"FungibleToken", "NonFungibleToken", "Kibble", "KittyItems"})
+	assert.Equal(t, deployments[0].Contracts, []string{"FungibleToken", "NonFungibleToken", "Kibble", "KittyItems"})
 }
 
 func Test_GetNetworkByNameComplex(t *testing.T) {
diff --git a/flow/project/cli/config/json/deploy_test.go b/flow/project/cli/config/json/deploy_test.go
index 367d396a..32ceb6d5 100644
--- a/flow/project/cli/config/json/deploy_test.go
+++ b/flow/project/cli/config/json/deploy_test.go
@@ -25,7 +25,7 @@ import (
 	"github.com/stretchr/testify/require"
 )
 
-func Test_ConfigDeploySimple(t *testing.T) {
+func Test_ConfigDeploymentsSimple(t *testing.T) {
 	b := []byte(`{
 		"testnet": {
 			"account-2": ["FungibleToken", "NonFungibleToken", "Kibble", "KittyItems"]
@@ -36,32 +36,33 @@ func Test_ConfigDeploySimple(t *testing.T) {
 		}
 	}`)
 
-	var jsonDeploys jsonDeploys
-	err := json.Unmarshal(b, &jsonDeploys)
+	var jsonDeployments jsonDeployments
+	err := json.Unmarshal(b, &jsonDeployments)
 	require.NoError(t, err)
 
-	deploys := jsonDeploys.transformToConfig()
+	deployments := jsonDeployments.transformToConfig()
 
-	assert.Equal(t, deploys.GetByAccountAndNetwork("account-2", "testnet")[0].Account, "account-2")
-	assert.Equal(t, deploys.GetByAccountAndNetwork("account-2", "testnet")[0].Contracts, []string{"FungibleToken", "NonFungibleToken", "Kibble", "KittyItems"})
+	//TODO: fix test to be sorted since its not necessary correct order
+	assert.Equal(t, "account-2", deployments.GetByNetwork("testnet")[0].Account)
+	assert.Equal(t, []string{"FungibleToken", "NonFungibleToken", "Kibble", "KittyItems"}, deployments.GetByNetwork("testnet")[0].Contracts)
 
-	assert.Len(t, deploys.GetByNetwork("emulator"), 2)
-	assert.Equal(t, deploys.GetByAccountAndNetwork("account-3", "emulator")[0].Account, "account-3")
-	assert.Equal(t, deploys.GetByAccountAndNetwork("account-4", "emulator")[0].Account, "account-4")
-	assert.Equal(t, deploys.GetByAccountAndNetwork("account-3", "emulator")[0].Contracts, []string{"KittyItems", "KittyItemsMarket"})
-	assert.Equal(t, deploys.GetByAccountAndNetwork("account-4", "emulator")[0].Contracts, []string{"FungibleToken", "NonFungibleToken", "Kibble", "KittyItems", "KittyItemsMarket"})
+	assert.Equal(t, 2, len(deployments.GetByNetwork("emulator")))
+	assert.Equal(t, "account-3", deployments.GetByNetwork("emulator")[0].Account)
+	assert.Equal(t, "account-4", deployments.GetByNetwork("emulator")[1].Account)
+	assert.Equal(t, []string{"KittyItems", "KittyItemsMarket"}, deployments.GetByNetwork("emulator")[0].Contracts)
+	assert.Equal(t, []string{"FungibleToken", "NonFungibleToken", "Kibble", "KittyItems", "KittyItemsMarket"}, deployments.GetByNetwork("emulator")[1].Contracts)
 }
 
 func Test_TransformDeployToJSON(t *testing.T) {
 	b := []byte(`{"emulator":{"account-3":["KittyItems","KittyItemsMarket"],"account-4":["FungibleToken","NonFungibleToken","Kibble","KittyItems","KittyItemsMarket"]},"testnet":{"account-2":["FungibleToken","NonFungibleToken","Kibble","KittyItems"]}}`)
 
-	var jsonDeploys jsonDeploys
-	err := json.Unmarshal(b, &jsonDeploys)
+	var jsonDeployments jsonDeployments
+	err := json.Unmarshal(b, &jsonDeployments)
 	require.NoError(t, err)
 
-	deploys := jsonDeploys.transformToConfig()
+	deployments := jsonDeployments.transformToConfig()
 
-	j := transformDeploysToJSON(deploys)
+	j := transformDeploymentsToJSON(deployments)
 	x, _ := json.Marshal(j)
 
 	assert.Equal(t, string(b), string(x))
diff --git a/flow/project/cli/project_test.go b/flow/project/cli/project_test.go
index 26fca003..3179bed2 100644
--- a/flow/project/cli/project_test.go
+++ b/flow/project/cli/project_test.go
@@ -62,7 +62,7 @@ func generateComplexProject() Project {
 			Source:  "0x123123123",
 			Network: "testnet",
 		}},
-		Deploys: config.Deploys{{
+		Deployments: config.Deployments{{
 			Network:   "emulator",
 			Account:   "emulator-account",
 			Contracts: []string{"KittyItems", "KittyItemsMarket"},
@@ -142,7 +142,7 @@ func generateSimpleProject() Project {
 			Source:  "../hungry-kitties/cadence/contracts/NonFungibleToken.cdc",
 			Network: "emulator",
 		}},
-		Deploys: config.Deploys{{
+		Deployments: config.Deployments{{
 			Network:   "emulator",
 			Account:   "emulator-account",
 			Contracts: []string{"NonFungibleToken"},
@@ -193,7 +193,7 @@ func generateAliasesProject() Project {
 			Network: "emulator",
 			Alias:   "ee82856bf20e2aa6",
 		}},
-		Deploys: config.Deploys{{
+		Deployments: config.Deployments{{
 			Network:   "emulator",
 			Account:   "emulator-account",
 			Contracts: []string{"NonFungibleToken"},
@@ -253,7 +253,7 @@ func generateAliasesComplexProject() Project {
 			Network: "emulator",
 			Alias:   "ee82856bf20e2aa6",
 		}},
-		Deploys: config.Deploys{{
+		Deployments: config.Deployments{{
 			Network:   "emulator",
 			Account:   "emulator-account",
 			Contracts: []string{"NonFungibleToken"},