Skip to content
This repository was archived by the owner on Oct 1, 2021. It is now read-only.

Commit b186b5a

Browse files
committed
chore: merged implemented feedback (#3)
Implemented feedback
2 parents bc88612 + cf2409a commit b186b5a

File tree

19 files changed

+155
-139
lines changed

19 files changed

+155
-139
lines changed

.travis.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ jobs:
3636
firefox: latest
3737
script: npx aegir test -t browser -- --browsers FirefoxHeadless
3838

39+
- stage: test
40+
name: sharness
41+
os:
42+
- linux
43+
- osx
44+
script: cd ./test/sharness && make
45+
3946
notifications:
4047
email: false
4148

README.md

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -77,30 +77,30 @@ Example:
7777

7878
```js
7979
const migrations = require('ipfs-repo-migrations')
80-
const getVersion = require('ipfs-repo-migrations/repo/version')
8180

8281
const repoPath = 'some/repo/path'
83-
const repoVersion = await getVersion(repoPath)
82+
const currentRepoVersion = 7
83+
const latestVersion = migrations.getLatestMigrationVersion()
8484

85-
if(repoVersion < migrations.getLatestMigrationVersion()){
85+
if(currentRepoVersion < latestVersion){
8686
// Old repo! Lets migrate to latest version!
87-
await migrations.migrate(repoPath)
87+
await migrations.migrate(repoPath, latestVersion)
8888
}
8989
```
9090

9191
To migrate your repository using the CLI, see the [how to run migrations](./run.md) tutorial.
9292

9393
## API
9494

95-
### `.migrate(path, {toVersion, ignoreLock, repoOptions, onProgress, isDryRun}) -> Promise<void>`
95+
### `.migrate(path, toVersion, {ignoreLock, repoOptions, onProgress, isDryRun}) -> Promise<void>`
9696

9797
Executes a forward migration to a specific version, or to the latest version if a specific version is not specified.
9898

9999
**Arguments:**
100100

101101
* `path` (string, mandatory) - path to the repo to be migrated
102+
* `toVersion` (int, mandatory) - version to which the repo should be migrated.
102103
* `options` (object, optional) - options for the migration
103-
* `options.toVersion` (int, optional) - version to which the repo should be migrated. Defaults to the latest migration version.
104104
* `options.ignoreLock` (bool, optional) - if true will not lock the repo when applying migrations. Use with caution.
105105
* `options.repoOptions` (object, optional) - options that are passed to migrations, that use them to construct the datastore. (options are the same as for IPFSRepo).
106106
* `options.onProgress` (function, optional) - callback that is called after finishing execution of each migration to report progress.
@@ -115,7 +115,7 @@ Signature of the progress callback.
115115
* `counter` (int) - index of current migration.
116116
* `totalMigrations` (int) - total count of migrations that will be run.
117117

118-
### `.revert(path, toVersion, {ignoreLock, options, onProgress, isDryRun}) -> Promise<void>`
118+
### `.revert(path, toVersion, {ignoreLock, repoOptions, onProgress, isDryRun}) -> Promise<void>`
119119

120120
Executes backward migration to a specific version.
121121

@@ -125,7 +125,7 @@ Executes backward migration to a specific version.
125125
* `toVersion` (int, mandatory) - version to which the repo should be reverted to.
126126
* `options` (object, optional) - options for the reversion
127127
* `options.ignoreLock` (bool, optional) - if true will not lock the repo when applying migrations. Use with caution.
128-
* `options.options` (object, optional) - options that are passed to migrations, that use them to construct the datastore. (options are the same as for IPFSRepo).
128+
* `options.repoOptions` (object, optional) - options that are passed to migrations, that use them to construct the datastore. (options are the same as for IPFSRepo).
129129
* `options.onProgress` (function, optional) - callback that is called after finishing execution of each migration to report progress.
130130
* `options.isDryRun` (bool, optional) - flag that indicates if it is a dry run that should give the same output as running a migration but without making any actual changes.
131131

@@ -168,33 +168,40 @@ every run of `jsipfs-migrations add` (manual changes should follow the same styl
168168

169169
Each migration must follow this API. It must export an object in its `index.js` that has following properties:
170170

171-
* `version` (int) - Number that represents the version which the repo will migrate to (eg. `migration-8` will move the repo to version 8).
171+
* `version` (int) - Number that represents the version which the repo will migrate to (eg. `8` will move the repo to version 8).
172172
* `description` (string) - Brief description of what the migrations does.
173173
* `migrate` (function) - Function that performs the migration (see signature of this function below)
174174
* `revert` (function) - If defined then this function will revert the migration to the previous version. Otherwise it is assumed that it is not possible to revert this migration.
175175

176-
#### `.migrate(repoPath, isBrowser)`
176+
#### `.migrate(repoPath, repoOptions)`
177177

178178
_Do not confuse this function with the `require('ipfs-repo-migrations').migrate()` function that drives the whole migration process!_
179179

180180
Arguments:
181181
* `repoPath` (string) - absolute path to the root of the repo
182-
* `options` (object, optional) - object containing `IPFSRepo` options, that should be used to construct a datastore instance.
183-
* `isBrowser` (bool) - indicates if the migration is run in a browser environment (as opposed to NodeJS)
182+
* `repoOptions` (object, optional) - object containing `IPFSRepo` options, that should be used to construct a datastore instance.
184183

185-
#### `.revert(repoPath, isBrowser)`
184+
#### `.revert(repoPath, repoOptions)`
186185

187186
_Do not confuse this function with the `require('ipfs-repo-migrations').revert()` function that drives the whole backward migration process!_
188187

189188
Arguments:
190189
* `repoPath` (string) - path to the root of the repo
191-
* `options` (object, optional) - object containing `IPFSRepo` options, that should be used to construct the datastore instance.
192-
* `isBrowser` (bool) - indicates if the migration is run in a browser environment (as opposed to NodeJS)
190+
* `repoOptions` (object, optional) - object containing `IPFSRepo` options, that should be used to construct the datastore instance.
193191

194192
### Browser vs. NodeJS environments
195193

196-
The migration might need to distinguish in which environment it runs (browser vs. NodeJS). For this reason there is an argument
197-
`isBrowser` passed to migrations functions. But with simple migrations it should not be necessary to distinguish between
194+
The migration might need to perform specific tasks in browser or NodeJS environment. In such a case create
195+
migration file `/migrations/migration-<number>/index_browser.js` which have to follow the same API is described before.
196+
Then add entry in `package.json` to the `browser` field as follow:
197+
198+
```
199+
'./migrations/migration-<number>/index.js': './migrations/migration-<number>/index_browser.js'
200+
```
201+
202+
In browser environments then `index.js` will be replaced with `index_browser.js`.
203+
204+
Simple migrations should not need to distinguish between
198205
these environments as the datastore implementation will handle the main differences.
199206

200207
There are currently two main datastore implementations:
@@ -221,8 +228,8 @@ write the rest of the migration!
221228

222229
### Integration with js-ipfs
223230

224-
When a new migration is created, the repo version in [`js-ipfs-repo`](https://github.com/ipfs/js-ipfs-repo) should be updated with the new version,
225-
together with updated version of this package. Then the updated version should be propagated to `js-ipfs`.
231+
When a new migration is created, new version of this package have to be released. Afterwards version of this package in [`js-ipfs-repo`](https://github.com/ipfs/js-ipfs-repo) have to be updated
232+
together with the repo version that `IPFSRepo` expects. Then the updated version of `js-ipfs-repo` should be propagated to `js-ipfs`.
226233

227234
### Tests
228235

@@ -259,7 +266,9 @@ This will create an empty migration with the next version.
259266

260267
### Module versioning notes
261268

262-
In order to have good overview of what version of package contains what kind of migrations, this package follows this versioning schema: `0.<versionOfLastMigration>.<patches>`.
269+
In order to have good overview of what version of package contains what kind of migration, to every release there
270+
should be appended version's metadata in format `migr-<versionOfLatestMigration>`. If for releasing is used `aegir`
271+
you can use the `release --metadata` option.
263272

264273
## Contribute
265274

maintainer.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"repoLeadMaintainer": {
3+
"name": "Adam Uhlíř",
4+
"email": "[email protected]",
5+
"username": "auhau"
6+
},
7+
"workingGroup": {
8+
"name": "JS IPFS",
9+
"entryPoint": "https://github.com/ipfs/js-core"
10+
}
11+
}

package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,13 @@
1212
"url": "https://github.com/ipfs/js-ipfs-repo-migrations/issues/"
1313
},
1414
"license": "MIT",
15-
"leadMaintainer": "Adam Uhlir <[email protected]>",
1615
"files": [
1716
"migrations",
1817
"src",
1918
"dist"
2019
],
2120
"main": "src/index.js",
2221
"browser": {
23-
"./src/option-node.js": "./src/option-browser.js",
2422
"./src/repo/lock.js": "./src/repo/lock-memory.js",
2523
"datastore-fs": "datastore-level"
2624
},

run.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ If you run into any trouble, please feel free to [open an issue in this reposito
1313
The migration tool is safe -- it should not delete any data. If you have important data stored _only_ in your ipfs node, and want to be extra safe, you can back up the whole repo with:
1414

1515
```sh
16-
cp -r ~/.js-ipfs ~/.js-ipfs.bak
16+
cp -r ~/.jsipfs ~/.jsipfs.backup
1717
```
1818

1919
## Step 1. Downloading the Migration
@@ -26,16 +26,16 @@ To run the migration tool:
2626

2727
```sh
2828
# to check if there are migrations that need to be applied
29-
js-ipfs-repo-migrations status
29+
jsipfs-repo-migrations status
3030

3131
# if so, migrate to the latest version
32-
js-ipfs-repo-migrations migrate
32+
jsipfs-repo-migrations migrate
3333
```
3434

3535
## Step 3. Done! Run IPFS.
3636

3737
If the migration completed without error, then you're done! Try running the new ipfs:
3838

3939
```
40-
js-ipfs daemon
40+
jsipfs daemon
4141
```

src/commands.js

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,33 @@ const path = require('path')
55
const fs = require('fs')
66
const process = require('process')
77
const util = require('util')
8+
const readline = require('readline')
89

910
const writeFile = util.promisify(fs.writeFile)
1011
const mkdir = util.promisify(fs.mkdir)
1112

1213
const chalk = require('chalk')
1314

1415
const repoVersion = require('./repo/version')
16+
const migratorUtils = require('./utils')
1517
const migrator = require('./index')
1618
const templates = require('./migration-templates')
1719
const migrations = require('../migrations')
1820

21+
function shouldContinueWithIrreversibleMigration () {
22+
return new Promise((resolve, reject) => {
23+
const rl = readline.createInterface({
24+
input: process.stdin,
25+
output: process.stdout
26+
})
27+
28+
rl.question(chalk.yellow('There is irreversible migration in the migrations plan. Do you want to continue? [y/N]'), (answer) => {
29+
rl.close()
30+
resolve(answer === 'y')
31+
})
32+
})
33+
}
34+
1935
function asyncClosure (fnc) {
2036
return function asyncWrapper ({ resolve, ...options }) {
2137
resolve(fnc(options))
@@ -29,14 +45,10 @@ function reportingClosure (action) {
2945

3046
async function migrate ({ repoPath, migrations, to, dry, revertOk }) {
3147
repoPath = repoPath || process.env.IPFS_PATH || path.join(os.homedir(), '.jsipfs')
32-
33-
// Import migrations if set
34-
if (migrations) {
35-
migrations = require(migrations)
36-
}
48+
migrations = migrations === undefined ? require('../migrations') : require(migrations)
3749

3850
if (!to) {
39-
to = migrator.getLatestMigrationVersion()
51+
to = migrator.getLatestMigrationVersion(migrations)
4052
}
4153

4254
const version = await repoVersion.getVersion(repoPath)
@@ -63,7 +75,13 @@ async function migrate ({ repoPath, migrations, to, dry, revertOk }) {
6375
if (version === to) {
6476
return chalk.yellow('Nothing to migrate! Versions matches')
6577
} else if (version < to) {
66-
await migrator.migrate(repoPath, options)
78+
if (migratorUtils.containsIrreversibleMigration(version, to, migrations)) {
79+
if (!(await shouldContinueWithIrreversibleMigration())) {
80+
return 'Migration aborted'
81+
}
82+
}
83+
84+
await migrator.migrate(repoPath, to, options)
6785
} else if (revertOk) {
6886
await migrator.revert(repoPath, to, options)
6987
} else {

src/errors.js

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,6 @@ class NonReversibleMigrationError extends Error {
1616
NonReversibleMigrationError.code = 'ERR_NON_REVERSIBLE_MIGRATION'
1717
exports.NonReversibleMigrationError = NonReversibleMigrationError
1818

19-
/**
20-
* Exception raised when structure of a repo is not as expected.
21-
*/
22-
class UnknownRepoStructureError extends Error {
23-
constructor (message) {
24-
super(message)
25-
this.name = 'UnknownRepoStructureError'
26-
this.code = 'ERR_UNKNOWN_REPO_STRUCTURE'
27-
this.message = message
28-
}
29-
}
30-
31-
UnknownRepoStructureError.code = 'ERR_UNKNOWN_REPO_STRUCTURE'
32-
exports.UnknownRepoStructureError = UnknownRepoStructureError
33-
3419
/**
3520
* Exception raised when repo is not initialized.
3621
*/

0 commit comments

Comments
 (0)