Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d011d66
Add some initial logic for the networking file
dimitrovmaksim Mar 7, 2022
8d63378
Move logic into a command-helper
dimitrovmaksim Mar 7, 2022
04c00a6
Add spinner
dimitrovmaksim Mar 7, 2022
ba2c33b
Code cleanup
dimitrovmaksim Mar 7, 2022
753fc85
Initialize networks.json whne running init command
dimitrovmaksim Mar 7, 2022
1f43cf2
Update tests
dimitrovmaksim Mar 7, 2022
1cdb285
Add await on filesystem read
dimitrovmaksim Mar 7, 2022
b9cbdfb
Rename networks.js to networks.js. Rename flag and var to singular. E…
dimitrovmaksim Mar 8, 2022
46359bb
Merge branch 'main' into add-network-config-file
dimitrovmaksim Mar 10, 2022
7c1b5bb
Throw error if subgraph.yaml datasource is not specified in a network…
dimitrovmaksim Mar 10, 2022
4f521b0
Add .DS_Store to .gitignore
dimitrovmaksim Mar 10, 2022
593037c
Add tests
dimitrovmaksim Mar 13, 2022
c7c04d4
Throw error if networkFile path is not file
dimitrovmaksim Mar 13, 2022
0d99416
Add back accidentally deleted line
dimitrovmaksim Mar 13, 2022
eaa51d1
Rename some variables. Update message
dimitrovmaksim Mar 13, 2022
887807f
Remove jsonIndent option
dimitrovmaksim Mar 13, 2022
c945e76
Merge branch 'main' into add-network-config-file
dimitrovmaksim Mar 17, 2022
10dd401
Address comments
dimitrovmaksim Mar 21, 2022
0b03a19
Merge branch 'main' into add-network-config-file
dimitrovmaksim Mar 21, 2022
9c479ec
Use current datasources protocol to determine if network uses account…
dimitrovmaksim Mar 21, 2022
0247eda
Pass only the indentifierName to updateSubgraphNetwork
dimitrovmaksim Mar 22, 2022
f138af6
Update tests
dimitrovmaksim Mar 22, 2022
f5f5b7d
Fix arguments
dimitrovmaksim Mar 22, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,6 @@ examples/example-subgraph/node_modules

# validation tests output
tests/cli/validation/*/generated

# Ignore Mac DS_Store files
.DS_Store
113 changes: 113 additions & 0 deletions src/command-helpers/network.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
const path = require('path')
const yaml = require('yaml')
const { step, withSpinner } = require('../command-helpers/spinner')

const updateSubgraphNetwork = async (toolbox, manifest, network, networksFile, identifierName) =>
await withSpinner(
`Update sources network`,
`Failed to update sources network`,
`Warnings while updating sources network`,
async spinner => {
let allNetworks

step(spinner, `Reading networks config`)
allNetworks = await toolbox.filesystem.read(networksFile, "json")
let networkConfig = allNetworks[network]

// Exit if the network passed with --network does not exits in networks.json
if(!networkConfig) {
throw new Error(`Network '${network}' was not found in '${networksFile}'`)
}

await toolbox.patching.update(manifest, content => {
let subgraph = yaml.parse(content)
let networkSources = Object.keys(networkConfig)
let subgraphSources = subgraph.dataSources.map(value => value.name);

// Update the dataSources network config
subgraph.dataSources = subgraph.dataSources.map(source => {
if (!networkSources.includes(source.name)) {
throw new Error(`'${source.name}' was not found in the '${network}' configuration, please update!`)
}

if (hasChanges(identifierName, network, networkConfig[source.name], source)) {
step(spinner, `Update '${source.name}' network configuration`)
source.network = network
source.source = source.source.abi ? { abi: source.source.abi } : {}
Object.assign(source.source, networkConfig[source.name])
} else {
step(spinner, `Skip '${source.name}': No changes to network configuration`)
}

return source
}
)

// All data sources shoud be on the same network,
// so we have to update the network of all templates too.
if(subgraph.templates) {
subgraph.templates = subgraph.templates.map(template => ({
...template,
network,
}))
}

let unsusedSources = networkSources.filter(x => !subgraphSources.includes(x))

unsusedSources.forEach(source => {
step(spinner, `dataSource '${source}' from '${networksFile}' not found in ${manifest}`)
})

let yaml_doc = new yaml.Document()
yaml_doc.contents = subgraph
return yaml_doc.toString()
})
})

const initNetworksConfig = async(toolbox, directory, identifierName) =>
await withSpinner(
`Initialize networks config`,
`Failed to initialize networks config`,
`Warnings while initializing networks config`,
async spinner => {
let subgraphStr = await toolbox.filesystem.read(path.join(directory, 'subgraph.yaml'))
let subgraph = yaml.parse(subgraphStr)

const networks = subgraph.dataSources.reduce((acc, source) =>
Object.assign(
acc,
{
[source.network]: {
[source.name]: {
[identifierName]: source.source.address,
startBlock: source.source.startBlock,
},
},
}
)
, {})

await toolbox.filesystem.write(`${directory}/networks.json`, networks)

return true
},
)

// Checks if any network attribute has been changed
function hasChanges(identifierName, network, networkConfig, dataSource) {
let networkChanged = dataSource.network !== network

// Return directly if the network is different
if (networkChanged) return networkChanged

let addressChanged = networkConfig[identifierName] !== dataSource.source[identifierName]

let startBlockChanged = networkConfig.startBlock !== dataSource.source.startBlock

return networkChanged || addressChanged || startBlockChanged
}

module.exports = {
updateSubgraphNetwork,
initNetworksConfig
}
78 changes: 78 additions & 0 deletions src/command-helpers/network.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
const { initNetworksConfig, updateSubgraphNetwork } = require('../command-helpers/network')
const toolbox = require('gluegun/toolbox')
const yaml = require('yaml')

describe('initNetworksConfig', () => {
beforeAll(async () => {
await initNetworksConfig(toolbox, './examples/example-subgraph', 'address')
})
afterAll(async () => {
await toolbox.filesystem.remove('./examples/example-subgraph/networks.json')
})

test('generates networks.json from subgraph.yaml', () => {
expect(toolbox.filesystem.exists('./examples/example-subgraph/networks.json')).toBe('file')
})

test('Populates the networks.json file with the data from subgraph.yaml', async () => {
let networksStr = await toolbox.filesystem.read('./examples/example-subgraph/networks.json')
let networks = JSON.parse(networksStr)

let expected = {
mainnet: {
ExampleSubgraph: { address: '0x22843e74c59580b3eaf6c233fa67d8b7c561a835' }
}
}

expect(networks).toStrictEqual(expected)
})
})

describe('updateSubgraphNetwork', () => {
beforeAll(async () => {
let content = {
optimism: {
ExampleSubgraph: { address: '0x12345...' }
}
}

await toolbox.filesystem.write('./examples/example-subgraph/networks.json', content)
await toolbox.filesystem.copy('./examples/example-subgraph/subgraph.yaml', './examples/example-subgraph/subgraph_copy.yaml')
})

afterAll(async () => {
await toolbox.filesystem.remove('./examples/example-subgraph/networks.json')
await toolbox.filesystem.remove('./examples/example-subgraph/subgraph_copy.yaml')
})

test('Updates subgraph.yaml', async () => {
let manifest = './examples/example-subgraph/subgraph_copy.yaml'
let networksFie = './examples/example-subgraph/networks.json'
let subgraph = await toolbox.filesystem.read(manifest)
let subgraphObj = yaml.parse(subgraph)

let network = subgraphObj.dataSources[0].network
let address = subgraphObj.dataSources[0].source.address

expect(network).toBe('mainnet')
expect(address).toBe('0x22843e74c59580b3eaf6c233fa67d8b7c561a835')

await updateSubgraphNetwork(
toolbox,
manifest,
'optimism',
networksFie,
'address'
)

subgraph = await toolbox.filesystem.read(manifest)
subgraphObj = yaml.parse(subgraph)

network = subgraphObj.dataSources[0].network
address = subgraphObj.dataSources[0].source.address

expect(network).toBe('optimism')
expect(address).toBe('0x12345...')
})

})
22 changes: 21 additions & 1 deletion src/commands/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const chalk = require('chalk')

const { createCompiler } = require('../command-helpers/compiler')
const { fixParameters } = require('../command-helpers/gluegun')
const { updateSubgraphNetwork } = require('../command-helpers/network')
const DataSourcesExtractor = require('../command-helpers/data-sources')
const Protocol = require('../protocols')

Expand All @@ -16,13 +17,15 @@ Options:
-t, --output-format <format> Output format for mappings (wasm, wast) (default: wasm)
--skip-migrations Skip subgraph migrations (default: false)
-w, --watch Regenerate types when subgraph files change (default: false)
--network <name> Network to use from networks.json
--network-file <path> Networks file (default: "./networks.json")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is missing a space before Networks file

`

module.exports = {
description: 'Builds a subgraph and (optionally) uploads it to IPFS',
run: async toolbox => {
// Obtain tools
let { filesystem, print, system } = toolbox
let { filesystem, patching, print, system } = toolbox

// Parse CLI parameters
let {
Expand All @@ -37,6 +40,8 @@ module.exports = {
t,
w,
watch,
network,
networkFile
} = toolbox.parameters.options

// Support both short and long option variants
Expand Down Expand Up @@ -68,6 +73,10 @@ module.exports = {
manifest !== undefined && manifest !== ''
? manifest
: filesystem.resolve('subgraph.yaml')
networkFile =
networkFile !== undefined && networkFile !== ''
? networkFile
: filesystem.resolve("networks.json")

// Show help text if requested
if (help) {
Expand All @@ -86,6 +95,17 @@ module.exports = {
return
}

if (network && filesystem.exists(networkFile) !== "file") {
print.error(`Network file '${networkFile}' does not exists or is not a file!`)
process.exitCode = 1
return
}

if (network) {
let identifierName = protocol.getContract().identifierName()
await updateSubgraphNetwork(toolbox, manifest, network, networkFile, identifierName)
}

let compiler = createCompiler(manifest, {
ipfs,
outputDir,
Expand Down
21 changes: 18 additions & 3 deletions src/commands/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ const immutable = require('immutable')
const os = require('os')
const path = require('path')
const toolbox = require('gluegun/toolbox')
const yaml = require('yaml')

const {
getSubgraphBasename,
validateSubgraphName,
} = require('../command-helpers/subgraph')
const DataSourcesExtractor = require('../command-helpers/data-sources')
const { validateStudioNetwork } = require('../command-helpers/studio')
const { initNetworksConfig } = require('../command-helpers/network')
const { withSpinner, step } = require('../command-helpers/spinner')
const { fixParameters } = require('../command-helpers/gluegun')
const { chooseNodeUrl } = require('../command-helpers/node')
Expand Down Expand Up @@ -132,7 +134,7 @@ const processInitForm = async (
return `${e.message}

Examples:

$ graph init ${os.userInfo().username}/${name}
$ graph init ${name} --allow-simple-name`
}
Expand Down Expand Up @@ -288,7 +290,7 @@ const getEtherscanLikeAPIUrl = (network) => {
case "optimism-kovan": return `https://api-kovan-optimistic.etherscan.io/api`;
default: return `https://api-${network}.etherscan.io/api`;
}
}
}

const loadAbiFromEtherscan = async (ABI, network, address) =>
await withSpinner(
Expand Down Expand Up @@ -356,7 +358,7 @@ module.exports = {

node = node || g
;({ node, allowSimpleName } = chooseNodeUrl({ product, studio, node, allowSimpleName }))

if (fromContract && fromExample) {
print.error(`Only one of --from-example and --from-contract can be used at a time.`)
process.exitCode = 1
Expand Down Expand Up @@ -686,6 +688,12 @@ const initSubgraphFromExample = async (
return
}

let networkConf = await initNetworksConfig(toolbox, directory, "address")
if (networkConf !== true) {
process.exitCode = 1
return
}

// Update package.json to match the subgraph name
let prepared = await withSpinner(
`Update subgraph name and commands in package.json`,
Expand Down Expand Up @@ -827,6 +835,13 @@ const initSubgraphFromContract = async (
return
}

let identifierName = protocolInstance.getContract().identifierName()
let networkConf = await initNetworksConfig(toolbox, directory, identifierName)
if (networkConf !== true) {
process.exitCode = 1
return
}

// Initialize a fresh Git repository
let repo = await initRepository(toolbox, directory)
if (repo !== true) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
Write subgraph to directory
- Create subgraph scaffold
✔ Create subgraph scaffold
- Initialize networks config
✔ Initialize networks config
- Initialize subgraph repository
✔ Initialize subgraph repository
- Install dependencies with yarn
Expand Down
2 changes: 2 additions & 0 deletions tests/cli/init/ethereum/from-contract-with-abi.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
Write subgraph to directory
- Create subgraph scaffold
✔ Create subgraph scaffold
- Initialize networks config
✔ Initialize networks config
- Initialize subgraph repository
✔ Initialize subgraph repository
- Install dependencies with yarn
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
Write subgraph to directory
- Create subgraph scaffold
✔ Create subgraph scaffold
- Initialize networks config
✔ Initialize networks config
- Initialize subgraph repository
✔ Initialize subgraph repository
- Install dependencies with yarn
Expand Down
2 changes: 2 additions & 0 deletions tests/cli/init/ethereum/from-contract.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
Write subgraph to directory
- Create subgraph scaffold
✔ Create subgraph scaffold
- Initialize networks config
✔ Initialize networks config
- Initialize subgraph repository
✔ Initialize subgraph repository
- Install dependencies with yarn
Expand Down
2 changes: 2 additions & 0 deletions tests/cli/init/ethereum/from-example.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
- Cloning example subgraph
✔ Cloning example subgraph
- Initialize networks config
✔ Initialize networks config
- Update subgraph name and commands in package.json
✔ Update subgraph name and commands in package.json
- Initialize subgraph repository
Expand Down
2 changes: 2 additions & 0 deletions tests/cli/init/near/from-contract.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
Write subgraph to directory
- Create subgraph scaffold
✔ Create subgraph scaffold
- Initialize networks config
✔ Initialize networks config
- Initialize subgraph repository
✔ Initialize subgraph repository
- Install dependencies with yarn
Expand Down