Display five contracts per page in the dashboard. Display ten contracts per
page in the contracts explorer and deployment page.
Sort contracts by name. In the future we can implement an option to sort by
block number and index within a block by calculating and including that
information as part of the server-side api response (based on a contract's
txhash).
Remove unnecessary contract filtering in the components since the containers
take care of it.
Make use of `listenToContracts` / `stopContracts` in DeploymentContainer.
feature(@embark/embarkjs-whisper: make embarkjs whisper plugin a module on its own
feature(@embark/embarkjs-whisper: make embarkjs whisper plugin a module on its own
During work on PRs #1492 and #1494 it became evident that it's not desirable to
show pagination controls unless the number of pages is greater than one.
Display a truncated account balance if the balance is greater than 20
characters in length. This keeps the "Balance", "Tx Count", and "Index" fields
well-aligned in lists of accounts.
In the account details page continue to show the full balance.
Display two accounts per page in the explorer overview. Display ten accounts
per page in the accounts explorer page.
Sort accounts by their api-supplied index numbers with the lowest index coming
first.
Change the `initBlockHeader` saga so that it triggers a re-fetch of accounts
and therefore the "Tx Count" numbers of displayed accounts will reflect
increased counts.
During deploy with a failing transaction, embark was crashing due to the variable `line` being passed in as undefined.
Add better error handling to catch this error and prevent embark from crashing.
Make tabs draggable so they can be arranged how the user would like.
The dragging functionality locks the tabs to the parent container.
Support for multiple rows of tabs.
Styling updates for selected tabs.
When connected to metamask, and “Injected Web3” is selected on the Deployment page of Cockpit, check to see if contracts have already been deployed or not.
For contracts that have not been deployed, or set to an address in the config, these should now all be re-deployable.
Supports libraries (that have bytecode with `0x73<address><bytecode>`).
Compare a contract's `originalFilename` property to a contract file's
normalized `originalPath` property instead of `filename`. The `filename`
property seems to have been removed.
Contract app hangs when attempting to test the solc contract in the test folder.
There were several causes:
1. The test contract needed a referenced contract path updated
2. Contracts that had been compiled in the JS tests were being deleted at the end of the JS test run, which caused errors with the files not being found. The fix was to reset the contracts config to no longer require the non-test contracts to be compiled/deployed.
3. Contract filtering was attempting to filter on a property `filename` that must have been changed to `originalFilename` at some point and therefore was not filtering properly.
4. The accounts used by the contract deployer were getting overwritten when `SolcTest` was instantiated and thus preventing the `remix_tests` `Assert` library from getting deployed.
Fix hang when the storage provider (IPFS or Swarm) was started externally before running Embark.
If IPFS/Swarm was already running before `embark run` was run, then the relevant `registerProvider` and `setProvider` code was not being run through the console, and thus the module init event was never fired, preventing the DApp from being built.
This PR refactors the way the IPFS/Swarm process is launched so that the `registerProvider` and `setProvider` code snippets are run through the console in the case of:
* IPFS/Swarm running externally from Embark
* IPFS/Swarm started in a child process by Embark
* Storage is disabled in the DApp config
TL;DR
=====
Unregister (disable) the service worker in production builds of Cockpit. The
CRA dev server doesn't enable the service worker, so no changes are needed in
that context, i.e. `yarn start` in the monorepo.
**NOTE**: to effect these changes a user will need to load production Cockpit at
`localhost:55555` and then close all Cockpit tabs (or restart the
browser). This should be done for each browser that has been used to access
production Cockpit. See the *Step-by-Step* section below for more information.
Rationale
=========
There are a couple of factors:
* It's a bit confusing that after stopping `embark run` the production build of
Cockpit is still accessible at `localhost:55555`. That's owing to CRA's
[offline-first behavior][PWA] per the service worker it creates, which
Cockpit [currently registers][current] (enables).
* It can be really confusing, if you don't know or forget about the service
worker's behavior, that after a production rebuild of Cockpit the old build
is still used in the browser, even after a page refresh. As [explained][ofb]
in CRA's docs: *"users will end up seeing older content until they
close (reloading is not enough) their existing, open tabs."* A similar effect
is seen when switching between DApps, e.g. teller and embark_demo.
The CRA docs point to [some code][code] that could be adapted to an alert in
the UI prompting the user to close all tabs and reopen the app. That approach
definitely makes sense for DApps built with CRA that have opted-in to the
service worker. In fact, the service worker behavior would be critical in DApps
that make use of connected-/react-router because cold loads of routes that
don't actually correspond to static files couldn't otherwise work, i.e. if the
DApp is being served from ipfs/swarm.
But for Cockpit itself, when served from localhost with an express backend that
we control, little seems to be gained from offline-first behavior vs. a more
familiar behavior, i.e. when `embark run` isn't running then Cockpit isn't
accessible.
Step-by-Step
============
Flushing a site's service worker from cache can be tricky. The following steps
outline an approach to making sure the Cockpit in use is the one with service
worker disabled.
1. The first screenshot below shows the JavaScript console from a fresh load of
Cockpit with the service worker enabled, i.e. from a build on `master` at time
of writing and `embark run` running for the `embark_demo`. Note the messages
re: *"workbox"* and *"precaching"*.
![][step-1]
2. The next screenshot shows what happens when `embark run` is stopped and the
browser is refreshed. Service worker makes the page available offline, though
there are errors related to embark's API not being accessible.
![][step-2]
3. (a) Cockpit gets rebuilt on this PR's `refactor/cockpit-service-worker`
branch and `EMBARK_UI_STATIC=t embark run` is started; see [previous
commit][prevcom] re: `EMBARK_UI_STATIC`. (b) The browser is refreshed. Note the
message at the bottom re: *"New content is available"*.
![][step-3]
4. The Chrome browser is closed completely (command-Q), reopened and
`localhost:55555` is loaded again. Note there are *still* messages re:
*"workbox"* and *"precaching"*.
![][step-4]
5. The page is refreshed again and now the messages are completely gone.
![][step-5]
6. `embark run` is stopped and the page is reloaded, but there's a connection
error because no process is listening on `localhost:55555` — proof that
the service worker is no longer in play!
![][step-6]
Steps 3(b) to 6 will need to be repeated for each browser (Firefox, Safari,
etc.) that visited `localhost:55555` when the service worker was enabled. And
they'll need to be repeated again if the browser is later used with a build of
Cockpit predating this PR.
[PWA]: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
[current]: 4d4704ac6f/packages/embark-ui/src/index.js (L39)
[ofb]: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app#offline-first-considerations
[code]: https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/src/serviceWorker.js#L66-L93
[step-1]: https://user-images.githubusercontent.com/194260/54885199-adfa0900-4e47-11e9-830b-1b92816b2354.jpg
[step-2]: https://user-images.githubusercontent.com/194260/54885202-b3575380-4e47-11e9-9c1e-24817472d9c4.jpg
[step-3]: https://user-images.githubusercontent.com/194260/54885209-bb16f800-4e47-11e9-8e23-8fbc3b4f48fa.jpg
[prevcom]: https://github.com/embark-framework/embark/commit/322033cc
[step-4]: https://user-images.githubusercontent.com/194260/54885212-bfdbac00-4e47-11e9-9c8c-db90228d953a.jpg
[step-5]: https://user-images.githubusercontent.com/194260/54885214-c538f680-4e47-11e9-9963-58fd041675f0.jpg
[step-6]: https://user-images.githubusercontent.com/194260/54885217-ccf89b00-4e47-11e9-967a-7f8a523d4a92.jpg
Implement a `/*` server-side catch-all route for Cockpit that loads Cockpit's
`index.html`.
This change is necessary with intent to disable offline-first behavior in
production builds of Cockpit. Cockpit's service worker effectively translates
server-side route unavailability into client-side behaviors of
connected-react-router. When the service worker is unregistered the same will
be accomplished via the server-side catch-all route.
Implement fallback pages for when embark is in the monorepo but Cockpit's
Create React App development server isn't yet started or isn't yet responsive.
Implement a fallback page for when the static build of Cockpit is missing. When
embark is in the monorepo, give instructions for building Cockpit. Otherwise,
report that the distribution is broken.
Deprecate the environment variable `EMBARK_DEVELOPMENT` in favor of
`EMBARK_UI_STATIC`. Unless the latter is truthy at runtime, when embark is in
the monorepo the CRA dev server of Cockpit will be accessible at
`localhost:55555` via proxied requests to `localhost:3000`. The deprecation is
not a breaking change as `EMBARK_DEVELOPMENT` / `EMBARK_UI_STATIC` are not
relevant to normal users, but only to developers working on embark itself.
Bump `express-http-proxy` to the latest version.
If a transaction is sent and the proxy is enabled, but the function hash (identified in the data of the transaction) is not recognized as a function of the contract (ie does not match a function hash in the contract’s ABI), then embark would crash.
The fix was to introduce error handling in `transactionUtils.getTransactionParams` that defaults the contract name and params to `UNKNOWN`.
This can be replicated by
1. Clone https://github.com/mortimr/ethvtx_embark
2. `embark run` the dapp
3. Connect with Metamask
4. Ensure you have enough funds
5. In the “Tx calls” bubble, enter a new value, then click “Set Value”.
6. When the Metamask dialog appears, the error should have already happened. The console shows:
```
embark/src/lib/utils/transactionUtils.ts:58
const functionName = func.functionName;
^
TypeError: Cannot read property 'functionName' of undefined
at functionName (/Users/mortimr/Horyus/ethvtx_embark/node_modules/embark/src/lib/utils/transactionUtils.ts:58:29)
at ConsoleListener.getTransactionParams [as _onIpcLogRequest] (/Users/mortimr/Horyus/ethvtx_embark/node_modules/embark/src/lib/modules/console_listener/index.js:102:41)
at _onIpcLogRequest (/Users/mortimr/Horyus/ethvtx_embark/node_modules/embark/src/lib/modules/console_listener/index.js:76:12)
at Server._done (/Users/mortimr/Horyus/ethvtx_embark/node_modules/embark/src/lib/core/ipc.js:81:7)
at Server.emit (/Users/mortimr/Horyus/ethvtx_embark/node_modules/event-pubsub/es5.js:74:21)
at Server.gotData (/Users/mortimr/Horyus/ethvtx_embark/node_modules/node-ipc/dao/socketServer.js:194:14)
at Socket.emit (events.js:189:13)
at Socket.EventEmitter.emit (domain.js:441:20)
at addChunk (_stream_readable.js:284:12)
at readableAddChunk (_stream_readable.js:261:13)
at Socket.Readable.push (_stream_readable.js:220:10)
at Pipe.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
```
When a fallback function is encountered give its signature as `function()`,
disable row expansion, and omit the interaction form. Also label with a
`fallback` badge.
Create React App automatically determines the base path for links within
production build artifacts based on the project's `"homepage"` field in
`package.json`.
An [alternative][alt-setting] is to set the `PUBLIC_URL` environment variable
in `.env.production`. Take that approach so embark-ui's `"homepage"` can
continue to point to its home in the monorepo on GitHub.
Generate source maps in the production build of embark-ui. Doing so increases
the size of the package's tarball by a few MB (it was already large because of
the editor component), but the benefits of being able to much more easily debug
a production build (e.g. when interacting with users experiencing problems)
outweigh the size cost.
[alt-setting]: https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/config/paths.js#L36
`"rxjs"` is [preferable][rxjs-pkg-name] in a CommonJS context,
e.g. node. Existing embark code is `require`-ing from the unscoped package
name, which worked in the monorepo because some other dependency specifies
`"rxjs"` and yarn hoists it to the root of the workspace. In a production
install of embark, though, `require('rxjs')` was failing.
[rxjs-pkg-name]: https://github.com/ReactiveX/rxjs/issues/2577
When testing production installs of embark 4.0.0-beta.1 (local registry), the
`restrictPath` mechanism of `core/fs` was too restrictive, interfering with
template generation (cause not completely determined). Also, it's known that
`restrictPath` causes problems when resolving plugins, etc. from "higher up"
`node_modules` paths, e.g. in the monorepo.
Introduce `codeRunner/fs` which uses `restrictPath` as before, and in `core/fs`
remove `restrictPath`. Revise the other `codeRunner` modules to use
`codeRunner/fs`.
Don't implicitly rely on explorer overview having been loaded to initially
populate `entities.transactions`. Also, that container should watch for new
blocks/transactions same as the other explorer containers.
Restore `fetchTransactions` and related to TransactionsContainer. It's no
longer the basis of pagination (it didn't work as desired), but when navigating
through the transaction pages that action will ensure more transactions are
fetched so that the account page will list more of an account's transactions
over time. That was a side effect of `getTransactions` before it was removed in
favor of `getBlocksFull`, which is still the basis of revised pagination logic
in the transactions explorer.
Revise calculations related to transactions and pagination in the transactions
explorer and explorers overview.
Make the number of transactions to display per page configurable and set it to
3 in the explorers overview. Display a "No transactions..." message instead of
"0" when there are no transactions to display.
Introduce a `blocksFull` prop, action, api, etc. for calculating lists of
transactions relative to block objects that contain full transaction objects
instead of hash strings (the function backing the blocks endpoint already
supports that) and transaction receipts. In the future, the receipts can be
used to filter out constructor transactions for silent contracts.
Make pagination display conditional within the blocks explorer, same as in the
transactions explorer.
Filter silent contracts in the views that display contracts lists rather than
with `formatContractForDisplay` because the old approach prevents interaction
with a silent contract if a link to it is followed from the blocks or
transactions explorer, which is not desirable.
Rename contract "Transactions" tab to "Log". Display and allow filtering of all
contract methods. Disable debug button for pure/view functions and the
constructor.
Revise the filtering logic so that filters are combined together. Make the
status filter a drop down menu like the others.
Revise styling for consistent row height, alignment of text, and button sizes;
use a monospaced font in some cases to achieve the effect.
Handle enter/return correctly in forms within a contract's Interact tab.
Remove event rows from a contract's Interact tab.
Track pure/view calls in the blockchain proxy so they can be logged server-side
by console listener and reported in Cockpit within a contract's Log tab.
Eliminate double logging in the contracts manager. Ensure contracts deployed on
a fresh `embark run` have an `address` / `deployedAddress` property.
Revise calculations related to block numbers and pagination in the blocks
explorer and explorers overview.
Make the number of blocks to display per page configurable and set it to 5 in
the explorers overview.
Previously, storage providers in embarkjs were not waiting for their respective storage process (ipfs and swarm) to start before running `registerProvider` and `setProvider` in the console.
This PR forces the `registerProvider` and `setProviders` from running in the console until the storage processes have loaded. As a side effect, the code generation of `EmbarkJS` must wait for the storage module ot be fully initiated (ie once the processes have launched and the `registerProvider` and `setProviders` have been run) before generating the code.
This fixes errors pertaining to `Could not connect to a storage provider using any of the dappConnections in the storage config` as these errors were typically caused by `setProviders` being called before the storage processes had fully launched.
Make changes by running these commands in the root of the monorepo:
**bugs**
```shell
npx lerna exec --concurrency 1 --stream -- \
'DIRPATH=$(realpath $PWD --relative-to=$LERNA_ROOT_PATH); \
npx json -I -f package.json -e "this.bugs=\
\"https://github.com/embark-framework/embark/issues\""'
```
**homepage**
```shell
npx lerna exec --concurrency 1 --stream -- \
'DIRPATH=$(realpath $PWD --relative-to=$LERNA_ROOT_PATH); \
npx json -I -f package.json -e "this.homepage=\
\"https://github.com/embark-framework/embark/tree/master/${DIRPATH}#readme\""'
```
Don't commit changes to private packages, with the exceptions of embark-typings
and embark-reset because those may switch from private to public, and also
because the latter will be included in `node_modules` of embark even if it is
private since embark-reset is presently a bundled dependency of embark.
Don't include the homepage and bugs fields in dapps generated from the template
packages, except for the demo. Set those dapps' description field to an empty
string.
Ensure every package (inc. private packages) has a description.
Ensure every package (inc. private packages) has a README that begins with:
```markdown
`[pkgJson.name]`
================
> [pkgJson.description]
Visit [embark.status.im](https://embark.status.im/) to get started with
[Embark](https://github.com/embark-framework/embark).
```
Don't include the README in dapps generated from the template packages, except
for the demo.
Prevent embark from crashing when app assets are not specified in `embark.json`.
Previously, if the `app` property of `embark.json` was missing, embark would crash with the error `TypeError: Cannot convert undefined or null to object`.
With this PR, the missing property is null-checked.
Add an `enabled` property to the pipeline config. This lets developers disable the pipeline using the config file.
Updates to the enabled property will be reflected while embark is running. For example if embark is running with the pipeline, setting `enabled: false` in the pipeline config will build/deploy the contracts but not run the pipeline. Conversely, if embark is running with the pipeline disabled, enabling the pipeline in the config will build/deploy the contracts then build the dapp.
`package.json` allows for a [`"files"` whitelist][files] to be specified as an
alternative to a top-level `.npmignore` within a package root. Maintaining
whitelists is generally easier and less error-prone than maintaining
blacklists, so implement a `"files"` list for all non-private packages in the
monorepo and remove unneeded `.npmignore` files.
Switch `embark-reset` from being a private package to one that will be
published, adjust the workspace's `"nohoist"` setting accordingly, and no
longer specify `embark-reset` as a bundled dependency of `packages/embark`. I
originally thought there might be a good reason not to publish it, but I no
longer think so.
Remove unnecessary LICENSE files in `packages/{embark,embark-ui}` since Lerna
will automatically copy the root LICENSE into any packages lacking that file,
i.e. before tarballs are packed and published to the NPM registry.
Change the `"author"` field of `packages/embarkjs-connector-web3` to match the
other packages, i.e. such that it matches the copyright assignment in the root
LICENSE. If that's not a desirable thing to do, then instead that package can
have a separate LICENSE file that has a copyright assignment for `"Jonathan
Rainville"`.
Supply some missing `.npmrc` files in `packages/*`.
[files]: https://docs.npmjs.com/files/package.json#files
https://github.com/embark-framework/embark/pull/1367 introduced a change that prevented the `blockchain_listener` from listening to logs until the IPC server connected. However, the restriction went too far, and included restricting registration of console commands and API endpoints for the regular transactions feature.
This fix reverts the changes that affect registration of regular txs endpoints and console commands.
It's possible to pass a `--require` option to mocha to load a script that sets
up `process.env.DAPP_PATH` as needed for embark's tests; that approach is
preferable to running mocha in a child process because when running in a child
process there seemed to be problems with sources maps and with VS Code's
debugger.
After the changes in this PR, the following works as expected, i.e. when there
are runtime errors line/col numbers are reported per the files in `src/`:
```
$ yarn build:no-ui
$ cd packages/embark
$ npx mocha "dist/test/**/*.js" \
--exit \
--no-timeouts \
--require ./scripts/test.js \
--require source-map-support/register
```
And the following VS Code launch config works well for me:
```json
{
"type": "node",
"request": "launch",
"name": "test - packages/embark",
"cwd": "${workspaceFolder}/packages/embark",
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"args": [
"'dist/test/**/*.js'",
"--exit",
"--no-timeouts",
"--require",
"./scripts/test.js",
"--require",
"source-map-support/register"
],
"autoAttachChildProcesses": true,
"sourceMaps": true
}
```
NOTE for VS Code users: I found it's important to specify
`"'dist/test/**/*.js'"` in the launch config instead of
`"\"dist/test/**/*.js\""`, and that it's important to specify `"program":
"${workspaceFolder}/node_modules/mocha/bin/_mocha"` vs. `"program":
"${workspaceFolder}/packages/embark/node_modules/.bin/mocha"`.
KNOWN ISSUES: when there are runtime errors during `yarn test` in
`packages/embark`, line/col numbers reflect the sources in
`package/embark/dist` because `nyc` isn't setup correctly to use the
source-maps generated by babel. A solution has not yet been found.
See: https://github.com/npm/rfcs/blob/latest/implemented/0010-monorepo-subdirectory-declaration.md
Make changes by running this command in the root of the monorepo:
```shell
npx lerna exec --concurrency 1 --stream -- \
'DIRPATH=$(realpath $PWD --relative-to=$LERNA_ROOT_PATH); \
npx json -I -f package.json -e \
"this.repository=\
{\"directory\": \"$DIRPATH\", \
\"type\": \"git\", \
\"url\": \"https://github.com/embark-framework/embark.git\"}"'
```
Don't commit changes to private packages, with the exceptions of embark-typings
and embark-reset because those may switch from private to public, and also
because the latter will be included in `node_modules` of embark even if it is
private since embark-reset is presently a bundled dependency of embark.
Don't include the repository field in dapps generated from the template
packages, except for the demo.
Switching between the two tabs shown on the Dashboard for the cockpit was removing some of the logs that were previously displayed. This was due to an overlap in `id`’s being assigned to the logs from different processes.
To alleviate this, the reducers has been updated to not only check `id` but also `process.name`.
Additionally, the reducer was updated so that the number of logs for **each process** is set to `ELEMENTS_LIMIT`. For example, our `ELEMENT_LIMIT` is currently set to `200` and it would have meant that the total number of process logs across all processes would have been capped at 200. The current changes in this PR allow for 400 total logs, given that we have two processes being monitored for logs.
The services websocket was initiated in the AppContainer and causing all child components to continuously re-render every time there was a service check (which is effectively every second). In addition, the socket was never stopped when not needed (ie when the services component was unmounted).
Create a ServicesContainer that initiates the websocket as part of the container, and stops the socket when the container is unmounted.
Move the ContractsList to be part of the ContractsContainer with a `mode` switch.
Add Deployment page title and description.
Previous to this PR, `web3` was only made available to each test case, as it was put in to the global namespace after each test deploy. This was causing issues for tests that use `web3` in the test description (ie in `describe()` or `contract()` functions), as the deploy had not happened yet, and thus `web3` was not yet available. The error encountered in these cases was `web3 is not defined`.
This PR puts `web3` in the global namespace before setting up the tests, making it available to test descriptions.
Allow `embark upload` to upload to IPFS/Swarm even if the storage module is disabled in the storage config.
An easy way to test this is to set `config/storage.js` > `enabled` to `false` in the demo. Then run `embark upload`.
A console warning is meant to appear in the browser console when the dapp is connecting to web3 using metamask and the blockchain client is geth. The warning displays information telling the user they should enable regular transactions to prevent known issues regarding transactions getting stuck.
The issue fixed here pertained to `warnAboutMetamask` vs `warnIfMetamask` - maybe there was a change that introduced this issue upstream.
Additionally, enabling and disabling of regular transactions via an API endpoint did not
Add ability to stop regular txs via query string, and validate request parameters.
This issue was caused by a string to integer conversion. In JavaScript,
when converting a string that starts with `0` (which is the case for tx
hashes) to an integer using `parseInt` it will always yield 0. That,
combined with a block with number 0 would always return a block result
instead of the transaction.
```
> parseInt("0xluri", 10)
0
```
This PR checks if the resulting number equals the string that was
provided on top of checking for the block number.
Previously, templates were in a subdirectory of `packages/embark`. Reorganize
them so that they are member packages of the monorepo. This allows them to
cleanly depend on other members of the monorepo,
e.g. `embarkjs-connector-web3`.
It is desirable for the templates, in the context of the monorepo, to specify
embark as a dependency, to take advantage of `npx embark test` (and it's a
"forward looking" setup re: how we plan to evolve embark). However, if embark
were to specify the template packages as dependencies a circular relationship
would be introduced, which is [unsupported by Lerna][circular]. Therefore,
revise the template generator so that all templates are resolved / fetched at
runtime, i.e. `boilerplate`, `demo`, and `simple` are no longer
"built-ins" *per se*. This change won't be apparent to embark's users, but it
does mean that the template generator won't work (in a production install of
embark) if it can't connect to the npm registry, i.e. when the user runs
`embark demo` or `embark new [--simple]`. When embark is inside the monorepo,
templates are resolved and copied from the yarn workspace rather than being
fetched from the registry, which is convenient for development. Also, any
template dependencies that are members of the monorepo are linked into the
copied template's `node_modules` rather than being installed from the registry,
again for convenience. During template generation, remove scripts and
dependencies that pertain only to membership in the monorepo; for now, that
involves removing embark as a dependency since we're not quite ready for that
arrangement to be the default, i.e. outside of the monorepo.
Refactor the root scripts so that more of them can consistently be used with
Lerna's filter options, e.g. `--scope` and `--ignore`. "Combo" scripts that
don't support filtering generally have a `:full` postfix.
Flip `clean` and `reset` scripts at the root and in the member packages for
consistency re: Lerna's notion of `clean` and embark's notion of `reset`. Have
each package run its `reset` script when its `clean` script is invoked (and
that's all for now), relying on `lerna clean` to delete packages'
`node_modules` in view of how Lerna's topological sorting works.
Lift the implementation of `embark reset` into a private package in
`packages/embark-reset` and make it a bundled dependency of embark. Packages in
`dapps/*` depend on `embark-reset` directly and make use of it with `npx
embark-reset` (but only in monorepo context). This removes a "wart" where
reboots could show errors when embark's sources aren't already built in
`packages/embark/dist`. Users will not notice any difference since `embark
reset` works as before, transparently making use of the `embark-reset`
package. The only downside to having it be a bundled dependency of embark is
that bundled deps have all of their `node_modules` included in the tarball
built with `npm pack` (that's why having the templates as bundled dependencies
of embark isn't a viable approach). However, `embark-reset` only has one
dependency, `rimraf`, which is a tiny module, so the cost seems acceptable.
As part of the reorganization, move `test_dapps` into `dapps/tests` and
`packages/embark/templates` into `dapps/templates`. Keep the directory names
short but revise the package names to facilitate simple filtering with
`embark-dapp-*`. Consolidate `.yarnrc` and `.gitignore` and clean up some
redundant ignore listings.
Scripts run with `--scope embark-dapp-*` use `--concurrency=1` to avoid
conflicts that could arise over network ports. The `ci:full` and `qa:full`
scripts use `--concurrency=1` in all scopes, for two reasons: resource
limitations on Travis and AppVeyor result in slower runs with concurrency >1,
and if something fails in those contexts it's easier to see what went wrong
when Lerna's output isn't interleaved from a bunch of scripts in `packages/*`.
Bump the Lerna version.
[circular]: https://github.com/lerna/lerna/issues/1198#issuecomment-442278902
Reproduce:
1. Go to cockpit > transactions
2. Click a transaction
3. There will be a flicker of an error, then the decoded tx displays OK. Inspecting the network requests, there is a 500 error with a response of
```
AssertionError [ERR_ASSERTION]: invalid remainder
```
This error is also printed in the console.
The issue is that the transaction is not a raw transaction, so instead of trying to decode the non-raw transaction, the transaction can be decoded by web3.
**Cache suggestions**
Suggestions are cached for better performance on each request. When contracts are deployed, the suggestion cache is cleared, allowing for updated contract methods to be built in to the suggestions.
** Handle edge cases **
Handle cases when console command is parsed as an empty string, or possibly returns an empty object, which would cause `Object.getOwnPropertyNames` to throw an error (that is ultimately swallowed).
Swarm was not being registered as a service due to a recent change that introduced a bug. The previous change was meant to register “swarm” as a console command to provide output for the `swarm` console command when swarm had not been registered in the VM. The bug, however, returned too early in the cases when swarm was meant to be enabled, thus effectively not registering the entire process.
The fix simply returns only when swarm is in fact, disabled, and also alters slightly the way swarm is determined to be enabled (the changes of which have been copied over to `ipfs`).
Add the ability to pass an error in the callback of an event action.
Currently, event actions could either pass back a an error OR a result, but not both, and with no way to distinguish between the two parameters. This PR adds the ability to pass an error as the first parameter of the action callback.
An example of a use case that this fixed: errors on `deployIf` were silently swallowed, which has now been fixed.
All instances of `events.request(“deploy:contracts”)` were given an `error` parameter in their callback, and errors printed if it is not undefined.
All instances of `registerActionForEvent` were combed to ensure any callbacks were passing the expected error and result.
`web3.eth.getAccounts` was returning an empty array in the console due to a change, that I’m unsure of what the original intention was for.
@andremederios, could you please take a look, and let me know if this breaks the intention of the original changes?
Cockpit whisper messages were not being subscribed to due to a inocuous bug that would swallow errors and ultimately not be subscribed to the `rxjs` observer.
This PR fixes a number of issues relating to the cockpit console.
#### Console commands display in cockpit console
Fix cockpit console not displaying console usage commands that included “<usage option>”. For example “resolve <name>” would not display the “<name>” part, as it was attempting to write this in as HTML (ansi-to-html conversion).
This was fixed by replacing any instances of “<usage>” with “[usage]”. Please note that future usage strings should not contain text wrapped in “<>”.
#### Autosuggestions for “web.eth.” not appearing
Fix “web3.eth.” not suggesting members of `web3.eth`. This was due to a `Object.keys(web3.eth)` throwing `'getOwnPropertyDescriptor' on proxy: trap returned descriptor for property 'defaultAccount' that is incompatible with the existing property in the proxy target` in the console. Changing `Object.keys` to `Object.getOwnPropertyDescriptor` solved the problem.
#### Fix autosuggestion of known console commands (ie from plugins)
Fix known console commands (ie from plugins) not being autosuggested. For example, typing “web”, should autosuggest `webserver start/stop`, `log webserver on`, and `log webserver off`.
This PR adds in support for registered console commands (from plugins).
In addition to `EmbarkJS.Storage` not being available in the console (ie `await EmbarkJS.Storage.isAvailable() alway returned false), the error `Could not connect to a storage provider using any of the dappConnections in the storage config` would always appear in the console. The storage operations in the dapps were working OK.
The fix to this was three-fold:
1) Wait for the ipfs process to be started before attempting to run the `EmbarkJS.Storage.registerProvider/setProvider` in the console.
2) Wait for `EmbarkJS.Storage.registerProvider` to be called before `EmbarkJS.Storage.setProvider`. This was actually handled in the previous PR.
3) Remove any async operations from the `setProviders` method in the storage module. This was causing `callback is not defined` errors which were being swallowed and masqueraded as an unsuccessful attempt to connect to a `dappConnection` or `upload` config.
For every provider registered and set with EmbarkJS, auto generate events to inform other modules of the state of the provider.
Any provider that belongs to EmbarkJS (currently Blockchain, Names, Messages, and Storage) will have both a `runcode:<provider name>:providerRegistered` and a `runcode:<provider name>:providerSet` event created automatically when the `CodeRunner` is instantiated.
Once the `registerProvider` code is run through the VM, ie `EmbarkJS.Blockchain.registerProvider(…)`, the corresponding event will be fired, ie `runcode:blockchain:providerRegistered`.
Likewise, once the `setProvider` code is run through the VM, ie `EmbarkJS.Blockchain.setProvider(…)`, the corresponding event will be fired, ie `runcode:blockchain:providerSet`.
Additional updates/fixes with this PR:
* Move `CodeRunner` to TypeScript
* Fix console errors with ENS and Storage due to a recent PR that waits for `code-generator:ready`. The solution here was to ensure that `code-generator:ready` is requested, so that premature events can be handled.
Fix demo not running, by fixing the following issues:
This was due to the removal of `Web3` from the VM initialisation in a recent PR. The reasoning behind the removal was so that the modules that need Web3 could require it as needed, however, it is needed in 3 modules (ENS, Whisper, and web3Connector), all of which would define `const Web = …` in the code generated EmbarkJS, thus causing issues in itself. This needs to be rethought prior to removing it from the VM sandbox.
Because Web3 is back to being required in the global sandbox of the VM, it does not need to be registered in the `web3Connector` module, hence the removal of the `runcode:register`.
Module not found: Error: Can't resolve 'embarkArtifacts/contracts/SimpleStorage.js' in '/Users/emizzle/temp/embark_demo/app/components’`
This was fixed by replacing
```
import SimpleStorage from 'Embark/contracts/SimpleStorage';
```
with
```
import SimpleStorage from '../../embarkArtifacts/contracts/SimpleStorage';
```
revert changes changing __Web3 to Web3
The console was not working correctly with the latest VM2/monorepo updates. This PR addresses namely fixes this problem, but also adds a few more notable changes:
* SIGNIFICANT improvement in loading time for `embark console` with an already running `embark run`. This is due to removing unneeded services starting, and instead forwarding user input to the main `embark run` process.
* All user input commands are now forwarded to the `embark run` process via IPC insteaad of evaluating the command in the `embark console` process.
* Removed IPC console history as it's no longer needed due to the above. Side effects:
** The signature of the `runcode:eval` and `runcode:register` events was changed to remove the `toRecord` parameter.
** Old `runcode:eval` signature: `events.request("runcode:eval", "code to be evaluated", (err, result) => {}, isNotUserInput, tolerateError)`
** New `runcode:eval` signature: `events.request("runcode:eval", "code to be evaluated", (err, result) => {}, tolerateError)`
** Old `runcode:register` signature: `events.request("runcode:register", "varName", variableValue, toRecord, (err, result) => {})`
** New `runcode:register` signature: `events.request("runcode:register", "varName", variableValue, (err, result) => {})`
* Removed unneeded `forceRegister` flag.
* Removed the `VM.getWeb3Config` method as it's no longer being used (EmbarkJS contracts are pulled out from the VM instead).
* Updated `web3Connector` `blockchain:connector:ready` to allow for event requests or event emissions.
* In the tests, removed the initial `initWeb3Provider` in the `init` as it was being called twice.
* In the tests, removed the `web3Connector` check message as the tests are now using the Console, and the console does this check. This was causing duplicate messages to be displayed in the output.
* Fix `web3 is not defined` browser error
Add the ability to request an event before it’s command handler has been set. Also, add the ability to emit an event before a listener has been set.
The most useful use case for this is to allow modules/plugins to load asynchronously and without need to know their load order beforehand. This let’s us request events in advance of having the event command handler set by the module/plugin.
BEFORE:
```
this.events.request(“event:name”, () => {
// never fired
});
this.events.setCommandHandler(“event:name”, cb);
```
AFTER:
```
this.events.request(“event:name”, () => {
// YAY it fires!
});
this.events.setCommandHandler(“event:name”, cb);
```
Prior to this PR, typing `SimpleStorage.methods.` in to the cockpit console would not show autosuggestions for the contract methods.
Contract names are case sensitive in the VM (VM2). Update the `Suggestions.getSuggestions` method to be case-sensitive when evaluating `Object.keys(<contract class name>.methods)`.
`EmbarkJS.Blockchain.connectConsole` has a potential race condition with both `cb` and `doneCb` firing at the end of the method.
This PR is an attempt to fix that by first awaiting the `cb`, then finally calling `doneCb`, as suggested by @michaelsbradleyjr in https://github.com/embark-framework/embark/pull/1319#discussion_r256850820
This PR introduces a large number of changes (for that, I am very sorry). Breaking this up in to smaller PR's was causing tests to fail, and the likelihood of them getting merged diminished. There a couple of PRs this PR closes, and as such, I have kep the original commits to preserve the history. The first two (of three) commits are the close PRs, and the last is the glue bringin it all together.
The main goal of this PR is to fix the fragility of the tests with EmbarkJS, however in doing so, a number of recent features have been updated:
Remapping of imports still had a few edge cases that needed to be ironed out, as well as have unit tests created for them. More details of the changes an be seen in the closed PR (below).
The main issue with VM2 was running the code generated EmbarkJS code inside the VM, and getting EmbarkJS contracts out of the VM and available to the tests. This fixed issues where ENS may not have been available to the tests. Notable additions include adding `EmbarkJS.Blockchain.connectTests` to the tests lifecycle, and ensuring `EmbarkJS` is only every required in the console module and not used or passed around elsewhere.
As mentioned above, the main issue with the tests in the context of a monorepo and with embark running as module inside the dapp’s `node_modules`, there were issues getting the correct contract state available inside of the tests. For some reason, this particular case was causing the tests to fail, with ENS never being available (assuming this to be an issue with `EmbarkJS.Blockchain.connect()` never being called). The main fix for this came with passing `web3` as an option in to `EmbarkJS.Blockchain.setProvider()`.
---
1. https://github.com/embark-framework/embark/pull/1286
2. https://github.com/embark-framework/embark/pull/1275
Go to bottom for details
---
There are few known issues with this PR. Instead of trying to fix all of them with this PR, I was hoping to get these issues tackled in separate PRs.
1. `deployIf` directive on contracts defined in the config are not working, however the tests are passing. The issue is that if `ContractA` has a `deployIf` set to `!!ContractB.options.address`, it means that it will not deploy if `ContractB` is not deployed. However, it appears that `ContractA` is attempted to be deployed prior to `ContractB` being deployed, and therefore `ContractA` fails to deploy. Instead, because `ContractA` depends on `ContractB`, `ContractB` should be deployed before `ContractA`.
2. `embark test --node embark` does not seem to be functioning for reasons unknown.
3. Remix tests: Currently there is support for adding contract tests that get process by `remix-tests`, however, there is an error that I believe is not due to embark, but due to the Assert library. For example, if we add a `test/remix_test.sol` to the `test_app` with the following content:
```
pragma solidity ^0.4.24;
import "remix_tests.sol";
import "../app/contracts/simple_storage.sol";
contract SimpleStorageTest {
SimpleStorage simpleStorage;
function beforeAll() public {
simpleStorage = new SimpleStorage(100);
}
function initialValueShouldBeCorrect() public {
return Assert.equal(
100,
simpleStorage.storedData,
"stored data is not what I expected"
);
}
}
```
After compilation, we would get the error:
```
remix_test.sol:14:12: TypeError: Member "equal" not found or not visible after argument-dependent lookup in type(library Assert)
return Assert.equal(
^—————^
```
---
This branch is based off of ()`refactor/embarkjs-in-monorepo`)[https://github.com/embark-framework/embark/tree/refactor/embarkjs-in-monorepo], which does not have passing tests due to the `EmbarkJS` ENS issue mentioned above. However, you should (hopefully) see the tests passing in this branch, meaning if both branches are merged, the tests should be passing.
Related PRs: https://github.com/embark-framework/embark-solc/pull/24
---
Changes include:
1. Add unit tests for recursively remapping imports
2. Handle plugin contracts correctly
3. Allow `prepareForCompilation` to be called from `File`, allowing for external compilers, like `embark-solc` to call this function before compilation.
4. Add flattened remappings to `File` that gets prepared for compilation (ie has it's imports remapped)
5. Return remapped contract content when file type is http. Previously this was broken, as always freshly downloaded (original) content was returned.
6. Handle additional cases for `custom` and http file types.
This PR was tested with:
- `embark` unit tests
- `embark` test_app
- `embark` test_app with `embark-solc` plugin
- `embark` test_app with `embark-flattener` plugin
- `Giveth/lpp-campaign`
Related change to get `embark-solc` up-to-date` with these changes: https://github.com/embark-framework/embark-solc/pull/24
When embark was running as module inside the dapp’s `node_modules`, the tests were failing due to several issues:
1. `web3` was not being set in the global namespace of vm2. `EmbarkJS.Blockchain.setProvider` was therefore failing because it relies on `global.web3` to be set. I guess somehow this works when the test app was running in a child tree of the executing program. maybe this is a security feature of vm2, but i’m not sure.
2. `embarkjs` provider code being injected to the vm twice. This really was the initial point of failure, as this piece of code is requiring embarkjs, so i’m assuming, but again not sure, that maybe it was getting a second instance of `EmbarkJS` which did not have it’s providers set up correctly (hence the error with `ENS provider not set`).
Fixes for those issues in this PR:
1. To circumvent the web3 issue, we are now setting `global.web3` for tests only (the global web3 accessible in the tests), and `web3` is now explicitly passed in to `EmbarkJS.Blockchain.setProvider`
2. To fix the `embarkjs` code being called twice, we are not re-injecting this code to the VM during test initialisations
Changes include:
- Add unit tests for recursively remapping imports
- Handle plugin contracts
- Allow `prepareForCompilation` to be called from `File`. Allows external compilers, like `embark-solc` to call this.
- Add flattened remappings to file getting prepared for compilation
- Return remapped contract content when file type is http
- Add check allowing files to be remapped/prepared multiple times
When embark was running as module inside the dapp’s `node_modules`, the tests were failing due to several issues:
1. `web3` was not being set in the global namespace of vm2. `EmbarkJS.Blockchain.setProvider` was therefore failing because it relies on `global.web3` to be set. I guess somehow this works when the test app was running in a child tree of the executing program. maybe this is a security feature of vm2, but i’m not sure.
2. `embarkjs` provider code being injected to the vm twice. This really was the initial point of failure, as this piece of code is requiring embarkjs, so i’m assuming, but again not sure, that maybe it was getting a second instance of `EmbarkJS` which did not have it’s providers set up correctly (hence the error with `ENS provider not set`).
Fixes for those issues in this PR:
1. To circumvent the web3 issue, we are now setting `global.web3` for tests only (the global web3 accessible in the tests), and `web3` is now explicitly passed in to `EmbarkJS.Blockchain.setProvider`
2. To fix the `embarkjs` code being called twice, we are not re-injecting this code to the VM during test initialisations
Packages' `"clean"` scripts should run regardless of whether `node_modules` is
in place at the root and/or package levels, but the `embarkjs` package was
missing a needed `npx` in front of `rimraf` in its script.
Also, bump its devDeps version of rimraf to be in line with the rest of
`packages/*` and `test_dapps/*`.
If a function receives a callback argument then it should not return a promise
if the caller's callback will be invoked. Both invoking a callback and
returning a promise can lead to at best confusion (in code review and at
runtime) and at worst non-deterministic behavior, such as race
conditions. Also, a caller supplying a callback may not handle a returned
promise, leading to unhandled rejection errors.
Refactor all readily identified functions where a callback argument can be
supplied but the function returns a promise regardless. Make use of
`callbackify` and `promisify` where it made sense to do so during the
refactoring. Some callsites of the revised functions may have been accidentally
overlooked and still need to be updated. Some functions that take callback
arguments may execute them synchronously, at odds with control flow of a
returned promise (if a callback wasn't supplied). Such cases should be
identified and fixed so that asynchronous behavior is fully consistent whether
the caller supplies a callback or receives a promise.
Make sure promises that pass control flow to a callback ignore rejections,
since those should be handled by the callback.
Don't return promise instances unnecessarily from async functions (since they
always return promises) and change some functions that return promises to async
functions (where it's simple to do so).
Whisper was using an ad hoc promise-like `messageEvents` object. However, that
object behaved more like an observable, since promises either resolve or
reject, and only do so one time. `messageEvents` was also intertwined with
callbacks. Replace `messageEvents` with RxJS Observable. `listenTo` now returns
Observable instances and callers can subscribe to them.
`Blockchain.connect` of embarkjs could suffer from a race condition where tasks
associated with `execWhenReady` might be ongoing when `connect`'s returned
promise resolves/rejects (or a caller supplied callback fires). Attempt to
ensure that returned-promise / supplied-callback control flow proceeds only
after `execWhenReady` tasks have finished. The control flow involved
is... rather involved, and it could use some further review and refactoring.
Bump webpack and the hard-source-plugin for webpack.
[util]: https://www.npmjs.com/package/util
Prior to this commit Embark had a bug where, when running `$ embark run` inside
an Embark project that was freshly cloned or reset, it'd get stuck at loading
the Solidity compiler.
However, this only seemed to happen when Embark was used with its dashboard. When
running
```
$ embark run --nodashboard
```
instead, Embark loaded Solidity successfully and moved on with compilation.
This bug pretty much boiled down to `SolidityProcess` not receiving a valid `Logger`
dependency when instantiated via `SolcW`. The reason this was happening
is that we were sending the needed dependencies via `ProcessLauncher.send()`, which
serializes/deserializes its sent data.
```
solidityProcessLauncher.send({action: 'init', options: { logger: this.logger }});
```
And inside `SolidityProcess`
```
process.on('message', (msg) => {
if (msg.action === "init") {
solcProcess = new SolcProcess(msg.options);
}
...
}
```
`SolcProcess` passes its `logger` instance down to `longRunningProcessTimer` which
uses methods on `Logger`.
However, since the data had been serialized, all prototype methods on the data is
gone, resulting in an error, which made Embark stop.
**Why was this only a problem when using the dashboard?**
Turns out we've only relied on `Logger.info()` in case the dashboard is used.
refactor(@embark) add fs to plugin api; change (most) modules to use it instead of coupling them with require
refactor(@embark) add fs to plugin api; change (most) modules to use it instead of coupling them with require
refactor(@embark) add fs to plugin api; change (most) modules to use it instead of coupling them with require
refactor(@embark) add fs to plugin api; change (most) modules to use it instead of coupling them with require
refactor(@embark) add fs to plugin api; change (most) modules to use it instead of coupling them with require
refactor(@embark) add fs to plugin api; change (most) modules to use it instead of coupling them with require
Prior to this commits `this.contractsFiles` kept growing at run time
for every file change that was detected by Embark.
The reason for that was a bug in a condition that determines whether
a subset of contract files needed to be added to memory or not.
In addition to that we kept pushing externally loaded contract files into
memory, even if they already existed in memory.
Don't import git history of embark-framework/EmbarkJS, simply copy over the
sources. Modify `package.json`, etc. re: being situated in the monorepo.
Make use of the root babel config but extend with
`packages/embarkjs/.babelrc.js`.
Build `test/` scripts into `build-test/` and git-ignore `build-test/`.
Revise `Blockchain.connect()` so that if the caller supplies a callback then a
promise is not returned.
Revise tests to test `Blockchain.connect()` usage with and without a callback.
Relative `"include"` path/s in a `tsconfig.json` are relative to the directory
in which the config is located, so each monorepo package that uses typescript
needs its own `tsconfig.json` that `"extends"` the root config.
For now, disable the `"typecheck"` script in embark-graph and embark-vyper, but
leave the relevant pieces in place (devDeps, configs) so that when they're
converted to TypeScript the scripts can simply be re-enabled. The problem is
that if no `.ts` files are present in the path/s specified in `"include"` of
`tsconfig.json`, tsc will exit with error.
refactor(@embark/embark-compiler) move compiler to its own module
This is a combination of 2 commits.
refactor(@embark/embark-compiler) move compiler to its own module
refactor(@embark/embark-compiler) move compiler to its own module
Update packages/embark-compiler/package.json
Co-Authored-By: iurimatias <iuri.matias@gmail.com>
Update packages/embark-compiler/package.json
Co-Authored-By: iurimatias <iuri.matias@gmail.com>
Update packages/embark-compiler/package.json
Co-Authored-By: iurimatias <iuri.matias@gmail.com>
refactor(@embark/embark-compiler) move compiler to its own module
refactor(@embark/embark-compiler) move compiler to its own module
refactor(@embark/embark-compiler) move compiler to its own module
refactor(@embark/embark-compiler) move compiler to its own module
Move `packages/embark`'s eslint config into the monorepo root.
Remove `"plugin:react/recommended"` since it's not commonly needed.
Put a `"eslintConfig"` config key/object in `packages/embark`'s `package.json`
that directs eslint to extend the root config; other `packages/*` can do
likewise.
Setup a `babel.config.js` in the root of the monorepo to be used by
`packages/*`. It won't be used by some packages, e.g. `packages/embark-ui`, but
most of them should use it instead of rolling their own.
Allow for package-level modifications by specifying `babelrcRoots` in the root
`babel.config.js`
Use the babel `--root-mode upward` option in `packages/embark`'s `build`
script. Other packages intending to use the common config should do likewise.
Use a `.babelrc.js` in `packages/embark` to supply the package-specific
`ignore` settings.
Make packages used by the common config devDeps of the root.
Extract babel-related devDeps from `packages/embark`, but don't extract the
non-dev deps since those are used by embark's pipeline in a production
install. Normally, it should only be necessary to have `@babel/cli` and
`@babel/core` in devDeps, and possibly `@babel/runtime-corejs2` in deps, plus
any package-specific babel-related dev/deps. Once we deprecate the pipeline, we
can finish the extraction.
Use `ncu -f '/babel/' -u` to bump the versions of all babel-related deps in the
root and in `packages/embark`. We get better space/time savings from the yarn
workspace when versions match.
fix typings
WIP: refactor
WIP: just needed an annotation 🎉 thanks @emizzle!
WIP: don't pack a tarball since it's a private package
WIP: no need to list as a devDep
Put common patterns we expect to use across most `packages/*` into the
top-level `.gitignore`. If there are package-specific patterns they can go in
that package's `.gitignore`. For example, `packages/embark-ui` ignores its
`build/` directory while commonly we ignore the packages' `dist/` directories.
Yarn merges `.yarnrc` from the current working directory with `.yarnrc` files
higher in the directory tree, so that file isn't needed in each package.
Unfortunately, npm doesn't do the same for `.npmrc` files, so a similar cleanup
isn't possible.
Add version info to `test_app/extensions/embark-service/package.json` to that
`yarn install` can work correctly if manually invoked in `test_app`.
TL;DR
=====
`yarn install` in a fresh clone of the repo.
`yarn reboot` when switching branches.
When pulling in these changes, there may be untracked files at the root in
all/some of:
```
.embark/
.nyc_output/
coverage/
dist/
embark-ui/
test_apps/
```
They can be safely deleted since those paths are no longer in use at the root.
Many of the scripts in the top-level `package.json` support Lerna's [filter
options]. For example:
`yarn build --scope embark` build only `packages/embark`.
`yarn build --ignore embark-ui` build everything except `packages/embark-ui`.
Scoping scripts will be more useful when there are more packages in the
monorepo and, for example, `yarn start` doesn't need to be invoked for all of
them while working on just a few of them simultaneously, e.g `embark` and
`embarkjs`.
It's also possible to `cd` into a particular package and run its scripts
directly:
```
cd packages/embark && yarn watch
```
Hot Topics & Questions
======================
What should be done about the [README][embark-readme] for `packages/embark`?
Should the top-level README be duplicated in that package?
Lerna is setup to use [Fixed/Locked mode][fixed-locked], and accordingly
`packages/embark-ui` is set to `4.0.0-beta.0`. The same will be true when
adding embarkjs, swarm-api, etc. to the monorepo. Is this acceptable or do we
want to use [Independent mode][independent]?
Scripts
=======
If a package doesn't have a matching script, `lerna run` skips it
automatically. For example, `packages/embark-ui` doesn't have a `typecheck`
script.
`yarn build`
------------
Runs babel, webpack, etc. according to a package's `build` script.
`yarn build:no-ui` is a shortcut for `yarn build --ignore embark-ui`.
`yarn ci`
---------
Runs a series of scripts relevant in a CI context according to a package's `ci`
script. For `packages/embark` that's `lint typecheck build test package`.
Also runs the `ci` script of the embedded `test_dapps` monorepo.
`yarn clean`
------------
Runs rimraf, etc. according to a package's `clean` script.
`yarn globalize`
----------------
Makes the development embark available on the global PATH, either via
symlink (Linux, macOS) or a shim script (Windows).
`yarn lint`
-----------
Runs eslint, etc. according to a package's `lint` script.
`yarn package`
--------------
Invokes `npm pack` according to a package's `package` script.
`yarn qa`
---------
Very similar to `ci`, runs a series of scripts according to a package's `qa`
script. The big difference between `ci` and `qa` is that at the top-level `qa`
first kicks off `reboot:full`.
There is a `preqa` script ([invoked automatically][npm-scripts]), which is a
bit of a wart. It makes sure that `embark reset` can be run successfully in
`packages/embark/templates/*` when the `reboot` script invokes the `reset`
script.
The `qa` script is invoked by `yarn release` before the latter proceeds to
invoke `lerna publish`.
`yarn reboot`
-------------
Invokes the `reset` script and then does `yarn install`.
The `reboot:full` variant invokes `reset:full` and then does `yarn install`.
`yarn release`
--------------
Works in concert with [lerna publish], which will prompt to verify the version
before proceeding. Use `n` to cancel instead of `ctrl-c` as `lerna publish` has
been seen to occasionally misbehave when not exited cleanly (e.g. creating a
tag when it shouldn't have).
```
yarn release [bump] [--options]
```
* `[bump]` see [`publish` positionals][pub-pos] and [`version`
positionals][ver-pos]; an exact version can also be specified.
* `--preid` prerelease identifier, e.g. `beta`; when doing a prerelease bump
will default to whatever identifier is currently in use.
* `--dist-tag` registry distribution tag, defaults to `latest`.
* `--message` commit message format, defaults to `chore(release): %v`.
* `--sign` indicates that the git commit and tag should be signed; not signed
by default.
* `--release-branch` default is `master`; must match the current branch.
* `--git-remote` default is `origin`.
* `--registry` default is `https://registry.npmjs.org/` per the top-level
[`lerna.json`][lerna-json].
To release `4.0.0-beta.1` as `embark@next` (assuming version is currently at
`4.0.0-beta.0`) could do:
```
yarn release prerelease --dist-tag next
```
For *test releases* (there is no longer a `--dry-run` option) [verdaccio] and a
filesystem git remote can be used.
Condensend instructions:
```
mkdir -p ~/temp/clones && cd ~/temp/clones
git clone git@github.com:embark-framework/embark.git
cd ~/repos/embark
git remote add FAKEembark ~/temp/clones/embark
```
in another terminal:
```
npm i -g verdaccio && verdaccio
```
in the first terminal:
```
yarn release --git-remote FAKEembark --registry http://localhost:4873/
```
`yarn reset`
------------
Invokes cleaning and resetting steps according to a package's `reset`
script. The big difference between `clean` and `reset` is that `reset` is
intended to delete a package's `node_modules`.
The `reset:full` variant deletes the monorepo's top-level `node_modules` at the
end. That shouldn't be necessary too often, e.g. in day-to-day work when
switching branches, which is why there is `reboot` / `reset` vs. `reboot:full`
/ `reset:full`.
Errors may be seen related to invocation of `embark reset` if embark is not
built, but `reset` will still complete successfully.
`yarn start`
------------
Runs babel, webpack, tsc, etc. (in parallel, in watch mode) according to a
package's `start` script.
`yarn test`
-----------
Run mocha, etc. according to a package's `test` script.
The `test:full` variant runs a series of scripts: `lint typecheck test
test_dapps`.
`yarn test_dapps`
-----------------
Runs the `test` script of the embedded `test_dapps` monorepo.
The `test_dapps:ci` and `test_dapps:qa` variants run the `ci` and `qa` scripts
of the embedded `test_dapps` monorepo, respectively.
`yarn typecheck`
----------------
Runs tsc, etc. according to a package's `typecheck` script.
Notes
=====
`npx` is used in some of the top-level and package scripts to ensure the
scripts can run even if `node_modules` is missing.
[`"nohoist"`][nohoist] specifies a couple of embark packages because
[`restrictPath`][restrictpath] is interfering with access to modules that are
located in a higher-up `node_modules`.
All dependencies in `packages/embark-ui` have been made `devDependencies` since
its production build is self-contained.
`packages/embark`'s existing CHANGELOG's formatting has been slightly adjusted
to match the formatting that Lerna will use going forward (entries in the log
haven't been modified).
Lerna will generate a CHANGELOG at the top-level and in each package. Since
we're transitioning to a monorepo, things may look a little wonky with respect
to old entries in `packages/embark/CHANGELOG.md` and going forward we need to
consider how scoping our commits corresponds to member-packages of the
monorepo.
In `packages/embark`, `test` invokes `scripts/test`, which starts a child
process wherein `process.env.DAPP_PATH` is a temporary path that has all of
`packages/embark/dist/test` copied into it, so that paths to test
helpers/fixtures don't need to be prefixed with `dist/test/` and so that a
`.embark` directory doesn't get written into `packages/embark`.
The `"engines"` specified in top-level and packages' `package.json` reflect a
node and npm pair that match (a source of confusion in the past). The pair was
chosen according to the first post v5 npm that's bundled with node. A
`"runtime"` key/object has been introduced in `packages/embark/package.json`
which is used as the basis for specifying the minimum version of node that can
be used to run embark, and that's what is checked by `bin/embark`.
Some changes have been introduced, e.g. in `lib/core/config` and
`lib/utils/solidity/remapImports` so that it's *not* implicitly assumed that
`process.env.DAPP_PATH` / `fs.dappPath()` are the same as
`process.cwd()`. There are probably several++ places where that assumption is
still in effect, and we should work to identify and correct them.
`embark reset` now deletes `embarkArtifacts/` within a dapp root, and
`embarkArtifacts/` is git-ignored.
`lib/core/env` adds all `node_modules` relative to `process.env.EMBARK_PATH` to
`NODE_PATH` so that embark's modules can be resolved as expected whether
embark's `node_modules` have been deduped or are installed in npm's flat
"global style".
`checkDependencies` has been inlined (see `lib/utils/checkDependencies`) and
slightly modified to support dependencies that have been hoisted into a
higher-up `node_modules`, e.g. as part of a yarn workspace. eslint has been
disabled for that script to avoid more involved changes to it.
`test_apps` is not in `packages/embark`; rather, there is `test_dapps` at the
top-level of the monorepo. `test_dapps` is an embedded monorepo, and its `ci` /
`qa` scripts `npm install` embark from freshly built tarballs of the packages
in the outer monorepo and then use that installation to run `embark test` in
the dapps. This should allow us to rapidly detect breakage related to
auto-bumps in transitive dependencies.
[filter options]: https://github.com/lerna/lerna/tree/master/core/filter-options
[embark-readme]: https://github.com/embark-framework/embark/blob/build/lerna/packages/embark/README.md
[fixed-locked]: https://github.com/lerna/lerna#fixedlocked-mode-default
[independent]: https://github.com/lerna/lerna#independent-mode
[npm-scripts]: https://docs.npmjs.com/misc/scripts
[lerna publish]: https://github.com/lerna/lerna/tree/master/commands/publish
[pub-pos]: https://github.com/lerna/lerna/tree/master/commands/publish#positionals
[ver-pos]: https://github.com/lerna/lerna/tree/master/commands/version#positionals
[lerna-json]: https://github.com/embark-framework/embark/blob/build/lerna/lerna.json#L11
[verdaccio]: https://www.npmjs.com/package/verdaccio
[nohoist]: https://github.com/embark-framework/embark/blob/build/lerna/package.json#L52-L55
[restrictpath]: https://github.com/embark-framework/embark/blob/build/lerna/packages/embark/src/lib/core/fs.js#L9