cht-conf 3.9.0 → 3.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,31 @@
1
+ ## [3.9.4](https://github.com/medic/cht-conf/compare/v3.9.3...v3.9.4) (2022-01-05)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **#460:** log useful error messages when api connection fails ([#461](https://github.com/medic/cht-conf/issues/461)) ([095a55c](https://github.com/medic/cht-conf/commit/095a55c9254c6872696cbee2fe42f244fc1fc4a8)), closes [#460](https://github.com/medic/cht-conf/issues/460) [#460](https://github.com/medic/cht-conf/issues/460)
7
+
8
+ ## [3.9.3](https://github.com/medic/cht-conf/compare/v3.9.2...v3.9.3) (2021-12-16)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **#455:** allow empty translation constants ([ac170d7](https://github.com/medic/cht-conf/commit/ac170d7cce13a6a500d89884d4ca63801f06a969)), closes [#455](https://github.com/medic/cht-conf/issues/455)
14
+
15
+ ## [3.9.2](https://github.com/medic/cht-conf/compare/v3.9.1...v3.9.2) (2021-12-08)
16
+
17
+
18
+ ### Performance Improvements
19
+
20
+ * **#432:** refactor the moving of reports to use a recursive function to improve performance ([c17b43b](https://github.com/medic/cht-conf/commit/c17b43b4d89b29b813db4be6e0f2d2c0a1e6c94d)), closes [#432](https://github.com/medic/cht-conf/issues/432)
21
+
22
+ ## [3.9.1](https://github.com/medic/cht-conf/compare/v3.9.0...v3.9.1) (2021-11-16)
23
+
24
+
25
+ ### Bug Fixes
26
+
27
+ * **#448:** Bump Ubuntu version and Node version in container to fix docker usage. Updates to readme ([25cb955](https://github.com/medic/cht-conf/commit/25cb955377eea6c6a0a7cb3953d889b57c93884b))
28
+
1
29
  # [3.9.0](https://github.com/medic/cht-conf/compare/v3.8.0...v3.9.0) (2021-11-01)
2
30
 
3
31
 
package/Dockerfile CHANGED
@@ -1,4 +1,4 @@
1
- FROM ubuntu:16.04
1
+ FROM ubuntu:18.04
2
2
  MAINTAINER DevOps "devops@medicmobile.org"
3
3
 
4
4
 
@@ -14,7 +14,7 @@ RUN echo "==> Installing Python dependencies" && \
14
14
  RUN echo "====> Installing cht-conf python stuff" &&\
15
15
  python -m pip install git+https://github.com/medic/pyxform.git@medic-conf-1.17#egg=pyxform-medic
16
16
 
17
- RUN curl -sL https://deb.nodesource.com/setup_6.x -o nodesource_setup.sh
17
+ RUN curl -sL https://deb.nodesource.com/setup_12.x -o nodesource_setup.sh
18
18
  RUN bash nodesource_setup.sh
19
19
  RUN apt-get install -y nodejs
20
20
 
package/README.md CHANGED
@@ -11,29 +11,44 @@ CHT Conf is a command-line interface tool to manage and configure your apps buil
11
11
 
12
12
  # Installation
13
13
 
14
- ## Docker
14
+ ## Operating System Specific
15
15
 
16
- docker build -t cht-conf:v0 .
17
- docker run cht-conf:v0
18
- docker exec -it <container_name> /bin/bash
19
-
20
- ## Ubuntu
16
+ ### Ubuntu
21
17
 
22
18
  npm install -g cht-conf
23
19
  sudo python -m pip install git+https://github.com/medic/pyxform.git@medic-conf-1.17#egg=pyxform-medic
24
20
 
25
- ## OSX
21
+ ### OSX
26
22
 
27
23
  npm install -g cht-conf
28
24
  pip install git+https://github.com/medic/pyxform.git@medic-conf-1.17#egg=pyxform-medic
29
25
 
30
- ## Windows
26
+ ### Windows
31
27
 
32
28
  As Administrator:
33
29
 
34
30
  npm install -g cht-conf
35
31
  python -m pip install git+https://github.com/medic/pyxform.git@medic-conf-1.17#egg=pyxform-medic --upgrade
36
32
 
33
+ ### Docker
34
+
35
+ **NB** - `cht-conf` in a Docker container should only be used if you're familiar with running containers. You will have to copy or mount your config files into the container in order to be able to use the `cht` call to interact with a remote CHT instance.
36
+
37
+ Build and then run the `cht-conf` container:
38
+
39
+ docker build -t cht-conf:v0 .
40
+ docker run -d --name cht-conf cht-conf:v0
41
+
42
+ You now have a container running in the background called `cht-conf`. You can get a shell on this container with:
43
+
44
+ docker exec -it cht-conf /bin/bash
45
+
46
+ And then you can run the utility with `cht`.
47
+
48
+ When you are done with the container, you can stop it with:
49
+
50
+ docker stop cht-conf
51
+
37
52
  ## Bash completion
38
53
 
39
54
  To enable tab completion in bash, add the following to your `.bashrc`/`.bash_profile`:
@@ -46,7 +61,7 @@ To upgrade to the latest version
46
61
 
47
62
  npm install -g cht-conf
48
63
 
49
- # Usage
64
+ ## Usage
50
65
 
51
66
  `cht` will upload the configuration **from your current directory**.
52
67
 
@@ -60,9 +75,9 @@ For developers, this is the instance defined in your `COUCH_URL` environment var
60
75
 
61
76
  cht --local
62
77
 
63
- ### A specific Medic Mobile instance
78
+ ### A specific Medic-hosted instance
64
79
 
65
- For configuring against Medic Mobile-hosted instances.
80
+ For configuring Medic-hosted instances.
66
81
 
67
82
  cht --instance=instance-name.dev
68
83
 
@@ -80,7 +95,7 @@ If a different username is required, add the `--user` switch:
80
95
 
81
96
  cht --archive
82
97
 
83
- The resulting archive is consumable by Medic's API >v3.7 to create default configurations.
98
+ The resulting archive is consumable by CHT API >v3.7 to create default configurations.
84
99
 
85
100
  ## Perform specific action(s)
86
101
 
@@ -267,7 +282,7 @@ To develop a new action or improve an existing one, check the ["Actions" doc](sr
267
282
 
268
283
  ## Testing
269
284
 
270
- Execute `npm test` to run static analysis checks and the test suite.
285
+ Execute `npm test` to run static analysis checks and the test suite. Requires Docker to run integration tests against a CouchDB instance.
271
286
 
272
287
  ## Executing your local branch
273
288
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cht-conf",
3
- "version": "3.9.0",
3
+ "version": "3.9.4",
4
4
  "description": "Configure CHT deployments",
5
5
  "main": "./src/lib/main.js",
6
6
  "engines": {
@@ -9,7 +9,9 @@
9
9
  "scripts": {
10
10
  "clean": "rm -rf ./build/",
11
11
  "eslint": "eslint src/**/*.js test/*.js test/**/*.js",
12
- "test": "npm run eslint && npm run clean && mkdir -p build/test && cp -r test/data build/test/data && cd build/test && nyc --reporter=html mocha --forbid-only ../../test/**/*.spec.js && cd ../..",
12
+ "docker-start-couchdb": "npm run docker-stop-couchdb && docker run -d -p 6984:5984 --rm --name cht-conf-couchdb couchdb:2.3.1 && sh test/scripts/wait_for_response_code.sh 6984 200 CouchDB",
13
+ "docker-stop-couchdb": "docker stop cht-conf-couchdb || true",
14
+ "test": "npm run eslint && npm run docker-start-couchdb && npm run clean && mkdir -p build/test && cp -r test/data build/test/data && cd build/test && nyc --reporter=html mocha --forbid-only ../../test/**/*.spec.js && cd ../.. && npm run docker-stop-couchdb",
13
15
  "semantic-release": "semantic-release"
14
16
  },
15
17
  "bin": {
@@ -34,7 +36,7 @@
34
36
  "homepage": "https://github.com/medic/cht-conf#readme",
35
37
  "dependencies": {
36
38
  "@hapi/joi": "^16.1.8",
37
- "@medic/translation-checker": "1.0.0",
39
+ "@medic/translation-checker": "^1.0.1",
38
40
  "canonical-json": "0.0.4",
39
41
  "csv-parse": "^4.16.0",
40
42
  "dom-compare": "^0.6.0",
@@ -10,6 +10,7 @@ const pouch = require('../lib/db');
10
10
  const { warn, trace, info, error } = require('../lib/log');
11
11
 
12
12
  const HIERARCHY_ROOT = 'root';
13
+ const BATCH_SIZE = 10000;
13
14
 
14
15
  module.exports = {
15
16
  requiresInstance: true,
@@ -49,19 +50,15 @@ const updateLineagesAndStage = async (options, db) => {
49
50
  trace(`Considering primary contact updates to ${ancestors.length} ancestor(s) of contact ${prettyPrintDocument(contactDoc)}.`);
50
51
  const updatedAncestors = replaceLineageInAncestors(descendantsAndSelf, ancestors);
51
52
 
52
- const reportsCreatedByDescendants = await fetch.reportsCreatedBy(db, descendantsAndSelf.map(descendant => descendant._id));
53
- trace(`${reportsCreatedByDescendants.length} report(s) created by these affected contact(s) will update`);
54
- const updatedReports = replaceLineageInReports(reportsCreatedByDescendants, replacementLineage, contactId);
53
+ minifyLineageAndWriteToDisk([...updatedDescendants, ...updatedAncestors], options);
55
54
 
56
- [...updatedDescendants, ...updatedReports, ...updatedAncestors].forEach(updatedDoc => {
57
- lineageManipulation.minifyLineagesInDoc(updatedDoc);
58
- writeDocumentToDisk(options, updatedDoc);
59
- });
55
+ const movedReportsCount = await moveReports(db, descendantsAndSelf, options, replacementLineage, contactId);
56
+ trace(`${movedReportsCount} report(s) created by these affected contact(s) will be updated`);
60
57
 
61
58
  affectedContactCount += updatedDescendants.length + updatedAncestors.length;
62
- affectedReportCount += updatedReports.length;
59
+ affectedReportCount += movedReportsCount;
63
60
 
64
- info(`Staged updates to ${prettyPrintDocument(contactDoc)}. ${updatedDescendants.length} contact(s) and ${updatedReports.length} report(s).`);
61
+ info(`Staged updates to ${prettyPrintDocument(contactDoc)}. ${updatedDescendants.length} contact(s) and ${movedReportsCount} report(s).`);
65
62
  }
66
63
 
67
64
  info(`Staged changes to lineage information for ${affectedContactCount} contact(s) and ${affectedReportCount} report(s).`);
@@ -155,6 +152,31 @@ ${bold('OPTIONS')}
155
152
  `);
156
153
  };
157
154
 
155
+ const moveReports = async (db, descendantsAndSelf, writeOptions, replacementLineage, contactId) => {
156
+ const contactIds = descendantsAndSelf.map(contact => contact._id);
157
+
158
+ let skip = 0;
159
+ let reportDocsBatch;
160
+ do {
161
+ info(`Processing ${skip} to ${skip + BATCH_SIZE} report docs`);
162
+ reportDocsBatch = await fetch.reportsCreatedBy(db, contactIds, skip);
163
+
164
+ const updatedReports = replaceLineageInReports(reportDocsBatch, replacementLineage, contactId);
165
+ minifyLineageAndWriteToDisk(updatedReports, writeOptions);
166
+
167
+ skip += reportDocsBatch.length;
168
+ } while (reportDocsBatch.length >= BATCH_SIZE);
169
+
170
+ return skip;
171
+ };
172
+
173
+ const minifyLineageAndWriteToDisk = (docs, parsedArgs) => {
174
+ docs.forEach(doc => {
175
+ lineageManipulation.minifyLineagesInDoc(doc);
176
+ writeDocumentToDisk(parsedArgs, doc);
177
+ });
178
+ };
179
+
158
180
  const writeDocumentToDisk = ({ docDirectoryPath }, doc) => {
159
181
  const destinationPath = path.join(docDirectoryPath, `${doc._id}.doc.json`);
160
182
  if (fs.exists(destinationPath)) {
@@ -214,10 +236,12 @@ const fetch = {
214
236
  .filter(doc => doc && doc.type !== 'tombstone');
215
237
  },
216
238
 
217
- reportsCreatedBy: async (db, contactIds) => {
239
+ reportsCreatedBy: async (db, contactIds, skip) => {
218
240
  const reports = await db.query('medic-client/reports_by_freetext', {
219
241
  keys: contactIds.map(id => [`contact:${id}`]),
220
242
  include_docs: true,
243
+ limit: BATCH_SIZE,
244
+ skip: skip,
221
245
  });
222
246
 
223
247
  return reports.rows.map(row => row.doc);
package/src/lib/api.js CHANGED
@@ -99,8 +99,19 @@ const api = {
99
99
  await request.get(url);
100
100
  return true;
101
101
  } catch (err) {
102
- log.error(`Failed to get a response from ${url}. Maybe you entered the wrong URL, `
103
- + 'wrong port or the instance is not started? Please check and try again.');
102
+ if (err.statusCode === 401) {
103
+ log.error(`Authentication failed connecting to ${url}. `
104
+ + 'Check the supplied username and password and try again.');
105
+ } else if (err.statusCode === 403) {
106
+ log.error(`Insufficient permissions connecting to ${url}. `
107
+ + 'You need to use admin permissions to execute this command.');
108
+ } else if (err.statusCode) {
109
+ log.error(`Received error code ${err.statusCode} connecting to ${url}. `
110
+ + 'Check the server and and try again.');
111
+ } else {
112
+ log.error(`Failed to get a response from ${url}. Maybe you entered the wrong URL, `
113
+ + 'wrong port or the instance is not started. Please check and try again.');
114
+ }
104
115
  return false;
105
116
  }
106
117
  },