Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Leading directories unwantedly preserved with copy/move #23

Open
jgeorgeson opened this issue Sep 29, 2016 · 34 comments
Open

Leading directories unwantedly preserved with copy/move #23

jgeorgeson opened this issue Sep 29, 2016 · 34 comments

Comments

@jgeorgeson
Copy link
Contributor

Am using CLI 1.5.0 with server 3.9.4. Probably easiest to illustrate with pictures.

Before:

leading-directories-before

Effectively I want test/base**#-sub#** to become test/base**#/sub#**, so I start with a copy

$ jfrog rt copy test-deploy-snapshots/test/base1-sub1/ test-deploy-snapshots/test/base1/sub1/
[Info:] Pinging Artifactory...
[Info:] Done pinging Artifactory.
[Info:] Searching Artifactory using AQL query: items.find({"repo": "test-deploy-snapshots","$or": [{"$and": [{"path": {"$match":"test/base1-sub1"},"name":{"$match":"*"}}]},{"$and": [{"path": {"$match":"test/base1-sub1/*"},"name":{"$match":"*"}}]}]}).include("name","repo","path","actual_md5","actual_sha1","size")
[Info:] Artifactory response: 200 OK
[Info:] Found 1 artifact.
[Info:] Copying artifact: test-deploy-snapshots/test/base1-sub1/file to test-deploy-snapshots/test/base1/sub1/test/base1-sub1/file
[Info:] Artifactory response: 200 OK
[Info:] Copied 1 artifacts in Artifactory

And as indicated in the Copying artifact line of the output, I end up like this

leading-directories-after

As circled in the after pic, the whole leading path is preserved under the to path.

@TamirHadad
Copy link
Contributor

@jgeorgeson,
By using the --flat=true flag artifacts are copied to the exact target path specified and their hierarchy in the source path is ignored.
I think that in you case it will be even easier to use placeholders.
jfrog rt cp test-deploy-snapshots/test/(base*)-(*)/ test-deploy-snapshots/test/{1}/{2}/ --flat=true

@jgeorgeson
Copy link
Contributor Author

I don't actually want to flatten as I have Eclipse P2 repositories under the base#-sub# folders. Each base#-sub# will have a number of CI builds plus the P2 composite index files. I want the equivalent to a regular local filesystem copy/move.

The placeholders option is awesome, have they always been there?

@eyalbe4
Copy link
Contributor

eyalbe4 commented Sep 29, 2016

Yes @jgeorgeson, placeholders are supposed from version 1.0.0 and the new File Specs introduced in 1.5.0 also support placeholders.

@eyalbe4
Copy link
Contributor

eyalbe4 commented Oct 9, 2016

@jgeorgeson, with your permission, I'm closing this issue.

@eyalbe4 eyalbe4 closed this as completed Oct 9, 2016
@jgeorgeson
Copy link
Contributor Author

So the type of copy/move operation I'm trying to perform is not possible? I want this

Moving artifact: test-deploy-snapshots/test/base2-sub3/file to test-deploy-snapshots/test/base2/sub3/test/base2-sub3/file

To instead be this

Moving artifact: test-deploy-snapshots/test/base2-sub3/file to test-deploy-snapshots/test/base2/sub3/file

without using flat, as I want to preserve the full recursive structure of the contents of the from path.

@eyalbe4
Copy link
Contributor

eyalbe4 commented Oct 10, 2016

@jgeorgeson, the nicel thing about placeholders is that they can capture a complete hierarchy of directories in the source path, allowing you to use this hierarchy in the target path. You can also capture two sections of a path, even when one section is inside the other one. For example, this pattern;
a/(b_(c_))
with this path:
a/b/1/2/3/c/d
with get c/d into {2}
and b/1/2/3/c/d into {1}

In your senario , you are actually trying to change the path structure and do it recursively. Your scenario might be a bit trickier to achieve with one command, and you might need to use multiple copy commands, each one for a slightly different path. Please let know what you ended up using eventually.

@jgeorgeson
Copy link
Contributor Author

I can't find anything that works other than not using the CLI at all, and directly making REST API calls instead. For example

curl -u jgeorgeson -X POST "http://server.example.com/artifactory/api/copy/test-deploy-snapshots/test/base1-sub1?to=/test-deploy-snapshots/test/base1/sub1"

Works just as a local OS cp -a /test/base1-sub1 /test/base1/sub1 would work. Why is the behavior different between the CLI and the REST API?

@eyalbe4
Copy link
Contributor

eyalbe4 commented Nov 8, 2016

@jgeorgeson, we want to help you achieve what you need and are open to suggestions and improvements.
To make the communication easier, can you please send an email to [email protected] with all the details?

@jgeorgeson
Copy link
Contributor Author

I have contacted support and the response there was basically the same as here. However they asked why I believed the CLI and REST API exhibit different behavior. Which indicates to me that the nature of what I'm asking for isn't understood. So I did some more local testing. It turns out that the CLI handles the copy and move commands differently depending on if you have a trailing slash or not.

No trailing slash, does exactly what I've been asking for

$ jfrog rt move test-deploy-snapshots/base1/sub1 test-deploy-snapshots/test/base1-sub1
[Info:] Moving artifact: test-deploy-snapshots/base1/sub1 to test-deploy-snapshots/test/base1-sub1
[Info:] Artifactory response: 200 OK

Trailing slash, preserves the leading path at the destination (what I'm asking how to avoid)

$ jfrog rt move test-deploy-snapshots/test/base1-sub1/ test-deploy-snapshots/base1/sub1/
[Info:] Searching Artifactory using AQL query: items.find({"repo": "test-deploy-snapshots","$or": [{"$and": [{"path": {"$match":"test/base1-sub1"},"name":{"$match":"*"}}]},{"$and": [{"path": {"$match":"test/base1-sub1/*"},"name":{"$match":"*"}}]}]}).include("name","repo","path","actual_md5","actual_sha1","size")
[Info:] Artifactory response: 200 OK
[Info:] Found 3 artifacts.
[Info:] Moving artifact: test-deploy-snapshots/test/base1-sub1/index.xml to test-deploy-snapshots/base1/sub1/test/base1-sub1/index.xml
[Info:] Artifactory response: 200 OK
[Info:] Moving artifact: test-deploy-snapshots/test/base1-sub1/plugins/plugin1.jar to test-deploy-snapshots/base1/sub1/test/base1-sub1/plugins/plugin1.jar
[Info:] Artifactory response: 200 OK
[Info:] Moving artifact: test-deploy-snapshots/test/base1-sub1/plugins/plugin2.jar to test-deploy-snapshots/base1/sub1/test/base1-sub1/plugins/plugin2.jar
[Info:] Artifactory response: 200 OK
[Info:] Moved 3 artifacts in Artifactory

Unfortunately, using placeholders causes the no-trailing-slash command to do nothing.

$ jfrog rt move "test-deploy-snapshots/test/(base*)-(sub*)" "test-deploy-snapshots/{1}/{2}"
[Info:] Searching Artifactory using AQL query: items.find({"repo": "test-deploy-snapshots","$or": [{"$and": [{"path": {"$match":"test"},"name":{"$match":"base*-sub*"}}]},{"$and": [{"path": {"$match":"test/base*"},"name":{"$match":"*-sub*"}}]},{"$and": [{"path": {"$match":"test//base*-sub*"},"name":{"$match":"*"}}]}]}).include("name","repo","path","actual_md5","actual_sha1","size")                            
[Info:] Artifactory response: 200 OK                                                                                                     
[Info:] Found 0 artifacts.                                                                                                               
[Info:] Moved 0 artifacts in Artifactory                                                                                                 
$ jfrog rt search test-deploy-snapshots/test/
[Info:] Searching Artifactory using AQL query: items.find({"repo": "test-deploy-snapshots","$or": [{"$and": [{"path": {"$match":"test"},"name":{"$match":"*"}}]},{"$and": [{"path": {"$match":"test/*"},"name":{"$match":"*"}}]}]}).include("name","repo","path","actual_md5","actual_sha1","size")                                                                                                                        
[Info:] Artifactory response: 200 OK                                                                                                     
[Info:] Found 15 artifacts.                                                                                                              
[                                                                                                                                        
  {                                                                                                                                      
    "path": "test-deploy-snapshots/test/base1-sub1/base1-sub1/index.xml"                                                                 
  },                                                                                                                                     
  {                                                                                                                                      
    "path": "test-deploy-snapshots/test/base1-sub1/base1-sub1/plugins/plugin1.jar"                                                       
  },                                                                                                                                     
  {
    "path": "test-deploy-snapshots/test/base1-sub1/base1-sub1/plugins/plugin2.jar"
  },
  {
    "path": "test-deploy-snapshots/test/base1-sub2/index.xml"
  },
  {
    "path": "test-deploy-snapshots/test/base1-sub2/plugins/plugin1.jar"
  },
  {
    "path": "test-deploy-snapshots/test/base1-sub2/plugins/plugin2.jar"
  },
  {
    "path": "test-deploy-snapshots/test/base2-sub1/index.xml"
  },
  {
    "path": "test-deploy-snapshots/test/base2-sub1/plugins/plugin1.jar"
  },
  {
    "path": "test-deploy-snapshots/test/base2-sub1/plugins/plugin2.jar"
  },
  {
    "path": "test-deploy-snapshots/test/base2-sub2/index.xml"
  },
  {
    "path": "test-deploy-snapshots/test/base2-sub2/plugins/plugin1.jar"
  },
  {
    "path": "test-deploy-snapshots/test/base2-sub2/plugins/plugin2.jar"
  },
  {
    "path": "test-deploy-snapshots/test/base2-sub3/index.xml"
  },
  {
    "path": "test-deploy-snapshots/test/base2-sub3/plugins/plugin1.jar"
  },
  {
    "path": "test-deploy-snapshots/test/base2-sub3/plugins/plugin2.jar"
  }
]

@thashepherd
Copy link

thashepherd commented Apr 28, 2017

Please re-open this issue. I am experiencing the same behavior as @jgeorgeson.

The below is only lightly sanitized (Org is a placeholder). The objective with this move command is to

  1. Move an artifact from our staging repository to our production repository
  2. Strip the branch name off of the end of the artifact
  jfrog rt move --server-id=prod-datacenter "nuget-org-dev/(Org)/(Org.Common.Configuration)/(Org.Common.Configuration.0.1.0)-master(.nupkg)" "nuget-org/{1}/{2}/{3}{4}"
  [Info] Searching artifacts...
  [Info] Found 1 artifact.
  [Info] Moving artifact: nuget-org-dev/Org/Org.Common.Configuration/Org.Common.Configuration.0.1.0-master.nupkg to: nuget-org/Org/Org.Common.Configuration/Org/Org.Common.Configuration/Org.Common.Configuration.0.1.0.nupkg
  [Info] Moved 1 artifacts.

Notice how rather than moving between repositories and retaining the same path in each (as I would expect to happen given how the placeholders are being used), the path is "doubled" - we go from Org/Org.Common.Configuration to Org/Org.Common.Configuration/Org/Org.Common.Configuration.

Is jfrog rt move operating as designed - is it really supposed to alter the target path this way?

@thashepherd
Copy link

This may be a regression introduced in 1.8.0 as we did not experience this behavior in 1.7.2.

@eyalbe4
Copy link
Contributor

eyalbe4 commented Apr 29, 2017

Thanks for reporting this @thashepherd. We will investigate this soon and reply back.

@TamirHadad
Copy link
Contributor

@thashepherd , we did a comparison of the move command between 1.8.0 and version 1.7.1, as far as we can see they are both working as expected.
Adding the --flat=true flag to the command you are executing should solve the problem.

@thashepherd
Copy link

@TamirHadad and @eyalbe4, thank you for the rapid response! I can verify that --flat=true solved my problem.

Are you sure there wasn't a change in default behavior? I did not need to pass that flag until after I upgraded to the 1.8.0 executable; in other words, the old behavior without --flat=true was the same as the current behavior with --flat=true.

@eyalbe4
Copy link
Contributor

eyalbe4 commented May 1, 2017

Hi @thashepherd,
We tested this functionality with 1.7.1 and 1.8.0 and got the same result. In case you can make the same test, please let us know if you see a behavior change and we'll investigate this further.

@thashepherd
Copy link

thashepherd commented May 1, 2017

@eyalbe4 thanks again for giving this your consideration. I've freshly downloaded versions 1.7.1 and 1.8.0 of the jfrog CLI and conducted a test. I think I've isolated what changed: we use the --server-id command option with the 1.8.0 CLI, whereas that didn't exist back in 1.7.1 (in fact it's why we updated). Here is the respective output; again, it has been lightly sanitized.

1.7.1

  jfrog_1.7.1 rt move "nuget-org-dev/(Org)/(Org.Common.Configuration)/(Org.Common.Configuration.0.3.4)-
  (.nupkg)" "nuget-org/{1}/{2}/{3}{4}"
  [Info] Moving artifact: nuget-org-dev/Org/Org.Common.Configuration/Org.Common.Configuration.0.3.4-.nu
  pkg to: nuget-org/Org/Org.Common.Configuration/Org.Common.Configuration.0.3.4.nupkg
  [Info] Moved 1 artifacts.

1.8.0

  jfrog_1.8.0 rt move --server-id=prod-datacenter "nuget-org-dev/(Org)/(Org.Common.Configuration)/(Org.Common.
  Configuration.0.3.4)-(.nupkg)" "nuget-org/{1}/{2}/{3}{4}"
  [Info] Searching artifacts...
  [Info] Found 1 artifact.
  [Info] Moving artifact: nuget-org-dev/Org/Org.Common.Configuration/Org.Common.Configuration.0.3.4-.nu
  pkg to: nuget-org/Org/Org.Common.Configuration/Org/Org.Common.Configuration/Org.Common.Config
  uration.0.3.4.nupkg
  [Info] Moved 1 artifacts.

(If you're wondering about the hanging hyphen at the end of the artifact's name, that's due to some of the changes elsewhere in our infrastructure since version 0.3.4 of that package was published, and shouldn't materially affect the results of the test)

@eyalbe4
Copy link
Contributor

eyalbe4 commented May 2, 2017

Thanks for isolating this @thashepherd!
We'll use this to replicate this behavior change and let you know what we found.

@jgeorgeson
Copy link
Contributor Author

jgeorgeson commented May 2, 2017

I'm also seeing 1.8.0 as having lost the desired functionality which worked when leaving the trailing slash off the source path (detailed in my previous comment on Nov 16).

[jgeorgeson@alfred: /d01/sandboxes/jgeorgeson/git/releng/svn-to-git (master *)]
$ ~/Downloads/jfrog-cli-1.7.1-linux-amd64 rt mv --dry-run=true test-deploy-snapshots/subgit-3.2.4/lib/licenses test-deploy-snapshots/subgit-3.2.4/
[Info] [Dry run]  Moving artifact: test-deploy-snapshots/subgit-3.2.4/lib/licenses to: test-deploy-snapshots/subgit-3.2.4/licenses
[Info] Moved 1 artifacts.
[jgeorgeson@alfred: /d01/sandboxes/jgeorgeson/git/releng/svn-to-git (master *)]
$ cp ~/.jfrog/jfrog-cli.conf ~/.jfrog/jfrog-cli.conf-pre18
[jgeorgeson@alfred: /d01/sandboxes/jgeorgeson/git/releng/svn-to-git (master *)]
$ mv ~/.jfrog/jfrog-cli.conf.save ~/.jfrog/jfrog-cli.conf
[jgeorgeson@alfred: /d01/sandboxes/jgeorgeson/git/releng/svn-to-git (master *)]
$ ~/Downloads/jfrog-cli-1.8.0-linux-amd64 rt mv --dry-run=true test-deploy-snapshots/subgit-3.2.4/lib/licenses test-deploy-snapshots/subgit-3.2.4/
[Info] Searching artifacts...
[Info] Found 0 artifacts.
[Info] Moved 0 artifacts.

@eyalbe4
Copy link
Contributor

eyalbe4 commented May 14, 2017

@thashepherd and @jgeorgeson,

After thoroughly testing this, we indeed see behavior change in version 1.8.0.
We truly apologize for this! The APIs are not supposed to change between releases, and we added more tests to help prevent such unintended changes.
We pushed this commit to the dev branch. This commit aligns the path conventions between all Artifactory commands. Our intention is that these conventions will not change. Thanks again for bringing this to our attention.
If you build the the code of the dev branch, you can try it our before it is released. Your feedback is greatly appreciated.

Here are the new conventions enforced by the new committed code:

  • mv a/b/c ... moves file/directory c.
  • mv a/b/c/ ... moves content of the directory c.
  • mv a/b/c d/ --flat=true ...moves file/directory c under directory d, to this new path d/c
  • mv a/b/c d/ --flat=false ...moves file/directory c under directory d, to this new path d/a/b/c
  • The above conventions apply to cp command as well.
  • del a/b/c ...deletes file/directory c.
  • del a/b/c/ ...deletes the content of directory c.

@eyalbe4 eyalbe4 reopened this May 14, 2017
@jgeorgeson
Copy link
Contributor Author

Thanks @eyalbe4 Do you have anything like a beta channel on bintray that we could download/test with?

@eyalbe4
Copy link
Contributor

eyalbe4 commented May 24, 2017

@jgeorgeson,
Version 1.9. 0 has been released with the above changes.
I believe that as a result of the bug fix, some edge cases may behave differently since 1.9.0.
Our goal thought is to keep the APIs as stable as possible. We added more tests to help verify this.

@jgeorgeson
Copy link
Contributor Author

Thanks. I will try and grab it tomorrow. So no beta channels on Bintray? Might be a good feature to add there.

@eyalbe4
Copy link
Contributor

eyalbe4 commented May 26, 2017

Hi @jgeorgeson,
I think that releasing beta version for getting feedback from the community could be helpful. We'll do it in cases where the feedback could be helpful before the release.

@jgeorgeson
Copy link
Contributor Author

Sorry to drag this out some more, but I don't think 1.9.0 is doing what we had in <= 1.7.x. With the older version the move command below would have created test-deploy-snapshots/subgit-3.2.4/licenses/ with the recursive structure and contents (ie --flat=false) of `test-deploy-snapshots/subgit-3.2.4/lib/licenses/' moved into it.

[jgeorgeson@alfred: /d01/sandboxes/jgeorgeson/git/releng/svn-to-git (master)]
$ jfrog -v
jfrog version 1.9.0
[jgeorgeson@alfred: /d01/sandboxes/jgeorgeson/git/releng/svn-to-git (master)]
$ jfrog rt mv --dry-run=true test-deploy-snapshots/subgit-3.2.4/lib/licenses test-deploy-snapshots/subgit-3.2.4/
[Info] Searching artifacts...
[Info] Found 1 artifact.
[Info] [Dry run]  Create path: test-deploy-snapshots/subgit-3.2.4/subgit-3.2.4/lib/
[Info] [Dry run]  Moving artifact: test-deploy-snapshots/subgit-3.2.4/lib/licenses/ to: test-deploy-snapshots/subgit-3.2.4/subgit-3.2.4/lib/
[Info] Moved 1 artifacts.

I can go in via the GUI, right-click on test-deploy-snapshots/subgit-3.2.4/lib/licenses, select Move, and specify as follows

jfrog-cli-issue23

And it does what I want to be able to do with the CLI. Leaving the trailing slash off both source and destination seems take an even more bizarre approach

[jgeorgeson@alfred: /d01/sandboxes/jgeorgeson/git/releng/svn-to-git (master)]
$ jfrog rt mv test-deploy-snapshots/subgit-3.2.4/lib/licenses test-deploy-snapshots/subgit-3.2.4
[Info] Searching artifacts...
[Info] Found 1 artifact.
[Info] Moving artifact: test-deploy-snapshots/subgit-3.2.4/lib/licenses/ to: test-deploy-snapshots/subgit-3.2.4/lib/subgit-3.2.4
[Info] Moved 1 artifacts.

@eyalbe4
Copy link
Contributor

eyalbe4 commented Jun 5, 2017

You're right @jgeorgeson,
The mv, cp and del commands indeed behave differently in version 1.9.0. We had to make these changes in order to support operations on folders in Artifactory (before that, the CLI supported only files) and also to maintain consistency between all commands. Meaning - have a trailing slash achieve the same goal for all commands.
See above the new conventions the CLI enforces from version 1.9.0 (from 22 days ago).
We would like stay aligned with these conventions in future release and avoid further changes, unless bugs are found.
Please accept our apologies if the changes made trigger changes in your scripts. We want to avoid this in the future.

@jgeorgeson
Copy link
Contributor Author

I guess I'm misreading the new conventions then, I read

mv a/b/c ... moves file/directory c.

As being the old behavior but my testing and your reply confirm it is not. So if I'm seeing it correctly now I need to use --flat with a directory to not preserve the leasing folders. Correct?

@eyalbe4
Copy link
Contributor

eyalbe4 commented Jun 6, 2017

You're correct @jgeorgeson.
--flat=true will not preserve the leading folders.

@thashepherd
Copy link

@eyalbe4 Apologies in the delay in responding to you. We've recently upgraded all the way to 1.10.2 (to resolve some checksum calculation issues) and I can confirm that the original behavior has been restored; we were able to remove the --flat=true.

For posterity, here's the change we made:
image

@eyalbe4
Copy link
Contributor

eyalbe4 commented Oct 8, 2017

@jgeorgeson and @thashepherd,
Do you think we can close this issue?

@jgeorgeson
Copy link
Contributor Author

I will test again. The last time I tried I still couldn't get it straight and modified my scripts to use REST API directly.

@thashepherd
Copy link

thashepherd commented Oct 10, 2017 via email

@eyalbe4
Copy link
Contributor

eyalbe4 commented Oct 11, 2017

Happy to hear this @thashepherd!
Sure, please share the changes.
From the sample you shared a few weeks ago, it looks like you're using JFrog CLI with MSbuild. This is very interesting. I'd be happy to hear more about how you use the two together.

@thashepherd
Copy link

Absolutely!

To provide some context, my company executes builds using Gitlab CI pipelines; 'pipelines' - builds - are defined by a .gitlab-ci.yml file at the root of the repository. Common functionality used to run pipelines for .NET projects is encapsulated in a NuGet package which is published on its own pipeline in a separate repository; this allows us to keep our pipeline definitions simple while re-using common functionality from that versioned package:

before_script:
  - nuget install 'Wayfair.Infra.Pipeline' -Version '0.9.0' -OutputDirectory '.\packages' -NonInteractive -NoCache -ExcludeVersion
  - . .\packages\Wayfair.Infra.Pipeline\Unpack-PipelineInfrastructure.ps1
  - . .\Scripts\Test-PipelinePrerequisites -Commands @('git', 'MSBuild', 'nuget', 'jfrog') -Modules @('ChatBotUtils')

The pipeline is separated into stages, which are fairly standard: restore, build, pack, publish, notify. Jobs in each stage are typically just calls out to customized MSBuild targets:

  script:
    - >
      MSBuild .\targets\artifactory.targets
      /p:EnableIncrementalBuild=True
      /p:TargetArtifactoryInstance=$($env:TARGET_ARTIFACTORY_INSTANCE)
      /p:TargetRepository=$($env:TARGET_REPOSITORY)

...etcetera. Now since we're using NuGet, you'd think we'd be using NuGet's built-in functionality to publish our packages to Artifactory. However, we make extensive use of repository sub-paths to organize our published artifacts, and due to the way NuGet works this is just seriously inconvenient to accomplish. So we call out to jFrog's CLI instead:

  <!-- This target publishes @NuGetPackageFiles to Artifactory -->
  <!-- Target instance is selected by $TargetArtifactoryInstance and repository by $TargetRepository -->
  <Target Name="Publish">
    <Error
      Text="No NuGet packages (*.nupkg) detected!"
      Condition="'@(NuGetPackageFiles)' == '' And '$(EnableIncrementalBuild)' != 'True'" />
    <Message
      Text="No NuGet packages (*.nupkg) detected. Since this is an incremental build this may mean that no deployable projects needed to be re-built for this commit. If you believe that this is in error, rerunning the pipeline will build, package, and publish all projects."
      Importance="High"
      Condition="'@(NuGetPackageFiles)' == '' And '$(EnableIncrementalBuild)' == 'True'" />
    <Message
      Text="Identified the following packages:%0a%09@(NuGetPackageFiles->'%(Filename)%(Extension)', '%0a%09')"
      Importance="High"
      Condition="'@(NuGetPackageFiles)' != ''" />

    <ItemGroup>
      <Properties Include="--server-id=$(TargetArtifactoryInstance)" Condition="$(TargetArtifactoryInstance) != ''" />
    </ItemGroup>

    <Message
      Text="Publishing %(NuGetPackageFiles.Filename) to $(TargetRepository)/$(Organization)/@(NuGetPackageFiles->'%(RecursiveDir)'->Replace('\', '/'))%(NuGetPackageFiles.Filename)%(NuGetPackageFiles.Extension)"
      Importance="High" />
    <Exec
      Command="jfrog rt upload @(Properties, ' ') %(NuGetPackageFiles.FullPath) $(TargetRepository)/$(Organization)/@(NuGetPackageFiles->'%(RecursiveDir)'->Replace('\', '/'))%(NuGetPackageFiles.Filename)%(NuGetPackageFiles.Extension)"
      EchoOff="True"
      Condition="'@(NuGetPackageFiles)' != ''" />
  </Target>

That's the 'publish' target. The issue in this thread is relevant to our 'promote' target. Before this fix was implemented, we used the following target to 'promote' artifacts from a staging repository to a production repository:

  <!-- This target promotes packages from nuget-wayfair-dev to nuget-wayfair in Artifactory -->
  <Target Name="Promote">
    <Error
      Text="No NuGet packages (*.nupkg) detected!"
      Importance="High"
      Condition="'@(NuGetPackageFiles)' == ''"/>

    <ItemGroup>
      <Properties Include="--flat=true" />
      <Properties Include="--server-id=$(TargetArtifactoryInstance)" Condition="$(TargetArtifactoryInstance) != ''" />
    </ItemGroup>

    <Message Text="Promoting %(NuGetPackageFiles.Identity) to production repository" Importance="High" />
    <Exec
      Command="jfrog rt move @(Properties, ' ') &quot;nuget-wayfair-dev/(Wayfair)/(@(NuGetPackageFiles->'%(RecursiveDir)'->Replace('\', '/')))(%(NuGetPackageFiles.Filename))(%(NuGetPackageFiles.Extension))&quot; &quot;nuget-wayfair/{1}/{2}/{3}{4}&quot;"
      EchoOff="True"
      Condition="'@(NuGetPackageFiles)' != ''" />
  </Target>

After the fix, we were able to simplify to the following:

  <!-- This target promotes packages from nuget-wayfair-dev to nuget-wayfair in Artifactory -->
  <Target Name="Promote">
    <Error
      Text="No NuGet packages (*.nupkg) detected!"
      Importance="High"
      Condition="'@(NuGetPackageFiles)' == ''"/>

    <ItemGroup>
      <Properties Include="--server-id=$(TargetArtifactoryInstance)" Condition="$(TargetArtifactoryInstance) != ''" />
    </ItemGroup>

    <Message Text="Promoting %(NuGetPackageFiles.Identity) to production repository" Importance="High" />
    <Exec
      Command="jfrog rt move @(Properties, ' ') &quot;$(SourceRepository)/$(Organization)/@(NuGetPackageFiles->'%(RecursiveDir)'->Replace('\', '/'))(%(NuGetPackageFiles.Filename))(%(NuGetPackageFiles.Extension))&quot; &quot;$(TargetRepository)/{1}{2}&quot;"
      EchoOff="True"
      Condition="'@(NuGetPackageFiles)' != ''" />
  </Target>

If you're curious about any of the moves we made here, or you're curious about how we're leveraging your CLI tooling and Artifactory itself at my organization, feel free to email me at my corporate account (malioto@ wayfair.com).

@felipecrs
Copy link

The leading directories are still preserved using CLI version 1.37.1. The --flat=true resolves the behavior. Is this intended? If yes, then I think the help description of jfrog rt cp should be updated.

target Pattern
    Specifies the target path in Artifactory, to which the artifacts should be copied, in the following format: <repository name>/<repository path>.
    If the pattern ends with a slash, the target path is assumed to be a folder. For example, if you specify the target as "repo-name/a/b/",
    then "b" is assumed to be a folder in Artifactory into which files should be copied.
    If there is no terminal slash, the target path is assumed to be a file to which the copied file should be renamed.
    For example, if you specify the target as "repo-name/a/b", the copied file is renamed to "b" in Artifactory.
    For flexibility in specifying the upload path, you can include placeholders in the form of {1}, {2} which are replaced by corresponding
    tokens in the source path that are enclosed in parenthesis.

It currently points nothing regarding to this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants