AEM File Transfers for Developers
Tags: aem, jcr
Published: 2020-01-28 02:33:17

There are several different ways to handle file transfers between AEM and your local file system. In this post, I'm going to go over a couple command line tools to transfers files between my local file system and AEM 6.5: [AEM repo tool](#aem-repo-tool) and [FileVault VLT](#filevault-vlt).

### AEM repo tool

Follow the instructions at [Adobe-Marketing-Cloud / tools / repo](https://github.com/Adobe-Marketing-Cloud/tools/tree/master/repo) to install on your system. For Linux, I used curl to install the `repo` bash script since it is just a single file. e.g.,

```
curl -L https://raw.githubusercontent.com/Adobe-Marketing-Cloud/tools/master/repo/repo -o $HOME/bin/repo

chmod +x $HOME/bin/repo
```

Add the `repo` script to your environment PATH as needed.

#### Config

Defaults

| Property    | Value                 |
|:------------|:----------------------|
| server      | http://localhost:4502 |
| credentials | admin:admin           |

If your server and/or credentials differ from the defaults, in your project folder, create a `.repo` file with your AEM server location and credentials. e.g.,

##### .repo
```
server=http://192.168.1.10:4502
credentials=gilfoyle:secret
```

#### Checkout

Specify the AEM JCR path to transfer from. Unlike `vlt`, you can only perform an action on a single path. There is not an option for a batch transfer that can use a filter.

```
cd myproject

repo checkout /apps/weretail
```

This will create a `jcr_root` folder containing the checked out folders and files.

<ul class="tree">
  <li><i class="icon-folder-open"></i> myproject
    <ul>
      <li><i class="icon-folder-open"></i> jcr_root
        <ul>
          <li><i class="icon-folder-open"></i> apps
            <ul>
              <li><i class="icon-folder"></i> weretail</li>
            </ul>
          </li>
        </ul>
      </li>
      <li>.repo</li>
    </ul>
  </li>
</ul>

Use the `put` command to transfer updated files into the AEM JCR.

```
cd jcr_root/apps/weretail/components/content/heroimage

repo put heroimage.html
```

Use the `-s` option with a command to specify a different server to interact with. For example, transfer to the publish instance on port 4503.

```
repo put -s http://localhost:4503 heroimage.html
```

#### Commands

| Command    | Alias  | Description                                           |
|:-----------|:-------|:------------------------------------------------------|
| checkout   |        | Intial checkout of server content on file system      |
| diff       |        | Show differences, same as 'localdiff'                 |
| get        |        | Download server content to local file system          |
| localdiff  |        | Show differences done locally compared to server      |
| put        |        | Upload local file system content to server            |
| serverdiff |        | Show differences done on the server compared to local |
| status     | st     | list status of modified/added/deleted files           |

>   For help on a command, use `repo <command> -h`. e.g., `repo -h get`. For the entire help contents, `repo -h`.


### IDE Integration

[Adobe-Marketing-Cloud / 
tools / repo / README](https://github.com/Adobe-Marketing-Cloud/tools/blob/master/repo/README.md) contains a good bit of information on how to integrate the commands into various IDE's including Visual Studio Code and IntelliJ. These integration methods should also work for the FileVault VLT commands.


#### VS Code

Create a `tasks.json` for the curent workspace. e.g., `.vscode/tasks.json`

Select Terminal > Configure Tasks > Create `tasks.json` file from template > Others.

Folder actions will be performed on the folder of the currently opened file.

##### tasks.json
```javascript
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "put file",
            "type": "shell",
            "command": "repo put -f ${file}",
            "problemMatcher": []
        },
        {
            "label": "put folder",
            "type": "shell",
            "command": "repo put -f ${fileDirname}",
            "problemMatcher": []
        },
        {
            "label": "get file",
            "type": "shell",
            "command": "repo get -f ${file}",
            "problemMatcher": []
        },
        {
            "label": "get folder",
            "type": "shell",
            "command": "repo get -f ${fileDirname}",
            "problemMatcher": []
        }
    ]
}
```

For more information on Visual Studio Code integration, refer to the [VS Code Task](https://code.visualstudio.com/docs/editor/tasks) documentation.

### FileVault VLT

The Apache Jackrabbit FileVault VLT command line tool maps the contents of an AEM Java Content Repository (JCR) to your file system.

To get the latest [FileVault](https://jackrabbit.apache.org/filevault/), clone or download the [jackrabbit-filevault](https://github.com/apache/jackrabbit-filevault) repo from github.

In AEM versions 6.3 and earlier, you could install FileVault from its archive in the `crx-quickstart/opt/filevault/` folder of your AEM instance. For example, AEM 6.3, includes both `filevault-3.1.38.tgz` and `filevault-3.1.38.zip`.

Next, build FileVault using Maven. e.g.,

```
cd jackrabbit-filevault

mvn clean install
```

>   Check the documentation for build requirements. At the time of this writing, Maven 3.3.9 (or higher) with Java 8 (or higher) required. I used openjdk version 1.8.0_232 and Maven 3.6.2 when building.


The initial build will take a few minutes, for example:
```
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for Apache Jackrabbit FileVault (Reactor Project) 3.4.1-SNAPSHOT:
[INFO]
[INFO] Apache Jackrabbit FileVault (Parent Project) ....... SUCCESS [  9.574 s]
[INFO] Apache Jackrabbit FileVault Core Bundle ............ SUCCESS [02:31 min]
[INFO] Apache Jackrabbit FileVault Diff (Diff utilities) .. SUCCESS [  1.549 s]
[INFO] Apache Jackrabbit FileVault JCR Remoting Service ... SUCCESS [  1.658 s]
[INFO] Apache Jackrabbit FileVault RCP Server Bundle ...... SUCCESS [  1.224 s]
[INFO] Apache Jackrabbit FileVault Documentation .......... SUCCESS [  0.066 s]
[INFO] Apache Jackrabbit FileVault Sync Service ........... SUCCESS [  1.611 s]
[INFO] Apache Jackrabbit FileVault Platform Interaction ... SUCCESS [  0.947 s]
[INFO] Apache Jackrabbit FileVault Command Line Interface . SUCCESS [  2.600 s]
[INFO] Apache Jackrabbit FileVault Package Hook Example ... SUCCESS [  2.040 s]
[INFO] Apache Jackrabbit FileVault Package Hook Sling Example SUCCESS [  0.350 s]
[INFO] Apache Jackrabbit FileVault Validation ............. SUCCESS [  3.375 s]
[INFO] Apache Jackrabbit FileVault (Reactor Project) ...... SUCCESS [ 13.789 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  03:15 min
[INFO] Finished at: 2019-12-06T18:42:47-05:00
[INFO] ------------------------------------------------------------------------
```

#### Installation

Extract the archive from the `vault-cli/target` directory in the build.

For example,
```
cd vault-cli/target

tar xfz vault-cli-3.4.1-SNAPSHOT-bin.tar.gz
```

If you like, rename the directory for the PATH so it does not contain `-SNAPSHOT`. e.g.,
```
mv vault-cli-3.4.1-SNAPSHOT vault-cli-3.4.1
```

Add the `bin` directory which contains `vlt` and `vlt.bat` to your environment PATH. For example, in Linux, this can be done in the users `.profile`.

```
export PATH=$PATH:$HOME/aem/jackrabbit-filevault/vault-cli/target/vault-cli-3.4.1/bin
```

Once you've updated your environment PATH to include the `bin` directory, verify using the `vlt` command (you may have to logout for your PATH changes to take effect).

```
vlt --help
```

#### Checkout

Using `vlt co`, you can checkout files from the AEM JCR.

Note: this example will checkout all of the files. *In a default AEM 6.5 author instance, there are over 2 GB's of files.*

```
cd jcr_root

vlt --credentials admin:admin co --force http://localhost:4502/crx
```

>   The credentials only need to be specified on the initial checkout and are added to `~/.vault/auth.xml` for subsequent operations.


#### Checkout Filter

A `META-INF` manifest folder exists alongside the `jcr_root`. Create this folder if needed and add a `vault/filter.xml` file. Now you can checkout just the directories you specify in this filter instead of the entire JCR.

<ul class="tree">
  <li><i class="icon-folder-open"></i> myproject
    <ul>
      <li><i class="icon-folder"></i> jcr_root</li>
      <li><i class="icon-folder-open"></i> META-INF
        <ul>
          <li><i class="icon-folder-open"></i> vault
            <ul>
              <li>filter.xml</li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>


##### filter.xml

```xml
<?xml version="1.0" encoding="UTF-8"?>
<workspaceFilter version="1.0">
  <filter root="/apps/weretail"/>
  <filter root="/apps/we-retail-communities"/>
  <filter root="/apps/we-retail-screens"/>
  <filter root="/content/we-retail"/>
</workspaceFilter>
```

Save the filter and run `vlt checkout`. Use `--force` to overwrite the previous checkout as needed. e.g.,

```
cd jcr_root

vlt co --force http://localhost:4502/crx
```

#### Commit

Update and commit a file back into the AEM JCR to test the operation. For example,

`apps/weretail/components/content/heroimage/heroimage.html`

```
<sly data-sly-use.heroImage="we.retail.core.model.HeroImage">
  <div class="${heroImage.classList} jumbotron"
     style="background-image: url('${(properties.fileReference || properties.fileName) ? heroImage.image.src : '' @ context='uri'}');">
    <div class="container cq-dd-image">
      <div class="we-HeroImage-wrapper">
        <p class="h3">${properties.heading}</p>
        <strong class="we-HeroImage-title h1">${properties.title || currentPage.title}</strong>

        <h3 style="font-weight:bold;text-shadow: 2px 2px 4px #000000;">
          VLT TESTING
        </h3>

        <p data-sly-test="${properties.buttonLabel && properties.buttonLinkTo}">
          <a class="btn btn-primary btn-action" href="${properties.buttonLinkTo @ extension = 'html'}" role="button">${properties.buttonLabel}</a>
        </p>
      </div>
    </div>
  </div>
</sly>
```

Commit the change with the `-v` option (verbose output) to see what is being transferred. e.g.,

```
vlt ci -v apps/weretail/components/content/heroimage/heroimage.html
```

Verify the update, e.g.,

View a page that has the `heroimage` component as published, <a href="http://localhost:4502/content/we-retail/us/en.html?wcmmode=disabled" rel="nofollow">http://localhost:4502/content/we-retail/us/en.html?wcmmode=disabled</a>


#### VLT Commands

| Command  | Alias   | Description                                                    |
|:---------|:--------|:---------------------------------------------------------------|
| add      |         | Puts files and directories under version control               |
| checkout | co      | Checkout a Vault file system                                   |
| commit   | ci      | Send changes from your working copy to the repository          |
| console  |         | Run an interactive console                                     |
| delete   | del, rm | Remove files and directories from version control              |
| diff     | di      | Display the differences between two paths                      |
| export   |         | Export the Vault filesystem                                    |
| format   |         | Formats vault docview files                                    |
| import   |         | Import a Vault filesystem                                      |
| info     |         | Displays information about a local file                        |
| propget  | pg      | Print the value of a property on files or directories          |
| proplist | pl      | Print the properties on files or directories                   |
| propset  | ps      | Set the value of a property on files or directories            |
| rcp      |         | Remote copy of repository content                              |
| resolved | res     | Remove 'conflicted' state on working copy files or directories |
| revert   | rev     | Restore pristine working copy file (undo most local edits)     |
| status   | st      | Print the status of working copy files and directories         |
| sync     |         | Control vault sync service                                     |
| update   | up      | Bring changes from the repository into the working copy        |

>   For help on a command, use `vlt --help` plus the name of the command. e.g., `vlt --help commit`


* * * 

Originally posted at [jimfrenette.com/.../aem-developer-file-transfers](https://jimfrenette.com/2019/12/aem-developer-file-transfers/) | [AEM Developer Resources](https://jimfrenette.com/aem/)