accordproject / template-archive

Smart Legal Contracts & Templating System
https://accordproject.org/projects/cicero/
Apache License 2.0
280 stars 119 forks source link

Cicero DRAFT error when executed against compressed .CTA archive templates. #778

Closed martinhalford closed 1 year ago

martinhalford commented 1 year ago

Bug Report 🐛

The Cicero Draft command fails for compressed .CTA archived templates.
The Cicero DRAFT command works fine for templates in uncompressed folders.

FYI: This bug is a blocker when using cicero-core lib, as can only use compressed .CTA archives in code.

Expected Behavior

Expect archived .CTA templates to perform identically to uncompressed templates. This error is only occurring in Cicero 0.24 - works as expected in 0.22.

Compressed .CTA Archive

$ cicero draft --template hello-world-state.cta --data data.json
9:15:47 pm - INFO: Name of the person to greet: "Fred Blogs".
Thank you!

Uncompressed Archive

$ cicero draft --template hello-world-state --data data.json
9:15:47 pm - INFO: Name of the person to greet: "Fred Blogs".
Thank you!

Current Behaviour

There are two ways to archive the template folder on a Mac:

1. At the template folder level.

2. Within the template folder.

For compressed archive #1, we observe the following:

$ cicero draft --template hello-world-state-folder.cta --data data.json 
9:48:45 pm - ERROR: Failed to find package.json in archive file.

For compressed archive #2, we observe the following:

$ cicero draft --template hello-world-state-no-folder.cta --data data.json 
9:50:50 pm - ERROR: Failed to find an asset that extends org.accordproject.contract.Clause. The model for the template must contain a single asset that extends org.accordproject.contract.Clause.
/Users/martin/.nvm/versions/node/v19.9.0/lib/node_modules/@accordproject/cicero-cli/node_modules/@accordproject/ergo-compiler/extracted/compilercore.js:998
throw a}function
^
ParseException: Expected "concerto", "namespace", comment, end of line, or whitespace but "\0" found. File __MACOSX/model/._@models.accordproject.org.time@0.2.0.cto line 1 column 1
    at Object.parse (/Users/martin/.nvm/versions/node/v19.9.0/lib/node_modules/@accordproject/cicero-cli/node_modules/@accordproject/ergo-compiler/node_modules/@accordproject/concerto-cto/lib/parserMain.js:31:19)
    at APModelManager.addAPModelFile (/Users/martin/.nvm/versions/node/v19.9.0/lib/node_modules/@accordproject/cicero-cli/node_modules/@accordproject/ergo-compiler/lib/apmodelmanager.js:80:28)
    at /Users/martin/.nvm/versions/node/v19.9.0/lib/node_modules/@accordproject/cicero-cli/node_modules/@accordproject/ergo-compiler/lib/apmodelmanager.js:98:18
    at Array.map (<anonymous>)
    at APModelManager.addAPModelFiles (/Users/martin/.nvm/versions/node/v19.9.0/lib/node_modules/@accordproject/cicero-cli/node_modules/@accordproject/ergo-compiler/lib/apmodelmanager.js:96:20)
    at /Users/martin/.nvm/versions/node/v19.9.0/lib/node_modules/@accordproject/cicero-cli/node_modules/@accordproject/cicero-core/lib/templateloader.js:96:34
    at Generator.next (<anonymous>)
    at asyncGeneratorStep (/Users/martin/.nvm/versions/node/v19.9.0/lib/node_modules/@accordproject/cicero-cli/node_modules/@accordproject/cicero-core/lib/templateloader.js:17:103)
    at _next (/Users/martin/.nvm/versions/node/v19.9.0/lib/node_modules/@accordproject/cicero-cli/node_modules/@accordproject/cicero-core/lib/templateloader.js:18:194) {
  component: '@accordproject/concerto-util',
  fileLocation: {
    source: undefined,
    start: { offset: 0, line: 1, column: 1 },
    end: { offset: 1, line: 1, column: 2 }
  },
  shortMessage: 'Expected "concerto", "namespace", comment, end of line, or whitespace but "\\0" found.',
  fileName: '__MACOSX/model/._@models.accordproject.org.time@0.2.0.cto'
}

Node.js v19.9.0

The following .CTA archives were used for the above examples.

hello-world-state-folder.cta.zip hello-world-state-no-folder.cta.zip

martinhalford commented 1 year ago

@mttrbrts @dselman

OK... This is odd.

I have cloned the cicero repo - specifically the branch ap-publish-v0.24.0 - and I ran the draft command locally.

One of the two issues above was not reproducible but the other one was.

Uncompressed Archive. - SUCCESS!

$ node index.js draft --template ~/Test/hello-world-state --data ~/Test/data.json
2:55:00 pm - INFO: Name of the person to greet: "Fred Blogs".
Thank you!

Compressed Archive (.CTA) with no folder. - SUCCESS!

$ node index.js draft --template ~/Test/hello-world-state-no-folder.cta --data ~/Test/data.json
2:55:16 pm - INFO: Name of the person to greet: "Fred Blogs".
Thank you!

Compressed Archive (.CTA) with folder. - FAILED!

$ node index.js draft --template ~/Test/hello-world-state-folder.cta --data ~/Test/data.json 
2:57:20 pm - ERROR: Failed to find package.json in archive file.

Using the cloned branch of cicero ap-publish-v0.24.0 the uncompressed template archive works, as does the template archive compressed with no folder, whereas the compressed archive with the folder still fails.

Am I testing against the correct branch? Is there an issue with our publishing process? Something else?

Is anyone else able to reproduce this behaviour?

mttrbrts commented 1 year ago

@martinhalford I can replicate this behaviour with the current contents of main. Although I believe it is working as expected.

Cicero will only look for files in the root directory of an archive. So compressing with an additional nested directory is not supported. Furthermore, I see that by using MacOS's built in compression tool there are duplicate file names (e.g. __MACOSX/model/._@models.accordproject.org.time@0.2.0.cto) which are used for Resource Forks. Cicero assumes that there are valid CTO files because of the extension and then fails to parse them.

I recommend using cicero archive to generate .cta files rather than relying on ZIP tools.

One way to verify the structure of a CTA archive is to use the unzip command. for example.

Bad Archive

$ unzip -v hello-world-state-folder.cta
Archive:  hello-world-state-folder.cta
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
       0  Stored        0   0% 06-23-2023 11:04 00000000  hello-world-state-v-0-24-a/
      81  Defl:N       75   7% 06-22-2023 23:50 12bc2ed0  hello-world-state-v-0-24-a/request.json
     187  Defl:N      110  41% 06-22-2023 23:50 15e5ddce  __MACOSX/hello-world-state-v-0-24-a/._request.json
       0  Stored        0   0% 06-22-2023 23:50 00000000  hello-world-state-v-0-24-a/logic/
     187  Defl:N      110  41% 06-22-2023 23:50 15e5ddce  __MACOSX/hello-world-state-v-0-24-a/._logic
     278  Defl:N      179  36% 06-22-2023 23:50 dcc0a3b4  hello-world-state-v-0-24-a/README.md
     187  Defl:N      110  41% 06-22-2023 23:50 15e5ddce  __MACOSX/hello-world-state-v-0-24-a/._README.md
     607  Defl:N      353  42% 06-23-2023 09:51 dd51cf38  hello-world-state-v-0-24-a/package.json
     542  Defl:N      364  33% 06-23-2023 09:51 4f1576a1  __MACOSX/hello-world-state-v-0-24-a/._package.json
     887  Defl:N      892  -1% 06-22-2023 23:50 1197e073  hello-world-state-v-0-24-a/logo.png
     187  Defl:N      110  41% 06-22-2023 23:50 15e5ddce  __MACOSX/hello-world-state-v-0-24-a/._logo.png
       0  Stored        0   0% 06-22-2023 23:50 00000000  hello-world-state-v-0-24-a/model/
     187  Defl:N      110  41% 06-22-2023 23:50 15e5ddce  __MACOSX/hello-world-state-v-0-24-a/._model
       0  Stored        0   0% 06-22-2023 23:50 00000000  hello-world-state-v-0-24-a/text/
     187  Defl:N      110  41% 06-22-2023 23:50 15e5ddce  __MACOSX/hello-world-state-v-0-24-a/._text
    1167  Defl:N      582  50% 06-22-2023 23:50 0dd576bc  hello-world-state-v-0-24-a/logic/logic.ergo

Good Archive

$ unzip -v helloworldstate@0.15.0.cta     
Archive:  helloworldstate@0.15.0.cta
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
     607  Stored      607   0% 06-27-2023 11:52 dd51cf38  package.json
       0  Stored        0   0% 06-27-2023 11:52 00000000  text/
      49  Stored       49   0% 06-27-2023 11:52 15ffcb3c  text/grammar.tem.md
     278  Stored      278   0% 06-27-2023 11:52 dcc0a3b4  README.md
     887  Stored      887   0% 06-27-2023 11:52 1197e073  logo.png
      53  Stored       53   0% 06-27-2023 11:52 a386966c  text/sample.md
      81  Stored       81   0% 06-27-2023 11:52 12bc2ed0  request.json
       0  Stored        0   0% 06-27-2023 11:52 00000000  model/
    1328  Stored     1328   0% 06-27-2023 11:52 143d37ef  model/@models.accordproject.org.time@0.2.0.cto
    2507  Stored     2507   0% 06-27-2023 11:52 7e6618c9  model/@models.accordproject.org.accordproject.money@0.2.0.cto
     975  Stored      975   0% 06-27-2023 11:52 9dd5c847  model/@models.accordproject.org.accordproject.contract.cto
    1495  Stored     1495   0% 06-27-2023 11:52 0f5e3842  model/@models.accordproject.org.accordproject.runtime.cto
     668  Stored      668   0% 06-27-2023 11:52 762122c3  model/@org.accordproject.ergo.options.cto
     557  Stored      557   0% 06-27-2023 11:52 b8357a32  model/model.cto
       0  Stored        0   0% 06-27-2023 11:52 00000000  logic/
    1167  Stored     1167   0% 06-27-2023 11:52 0dd576bc  logic/logic.ergo
--------          -------  ---                            -------
   10652            10652   0%                            16 files
martinhalford commented 1 year ago

Thanks @mttrbrts - That's awesome feedback. Much appreciated.