{"id":2983,"date":"2019-09-25T19:10:13","date_gmt":"2019-09-25T07:10:13","guid":{"rendered":"https:\/\/www.deltics.co.nz\/blog\/?p=2983"},"modified":"2019-09-25T19:10:21","modified_gmt":"2019-09-25T07:10:21","slug":"duget-push-ing-packages","status":"publish","type":"post","link":"https:\/\/www.deltics.co.nz\/blog\/posts\/2983\/","title":{"rendered":"Duget &#8211; PUSH-ing Packages"},"content":{"rendered":"<span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">3<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span>\n<p><a href=\"https:\/\/www.deltics.co.nz\/blog\/posts\/2979\">We now know a little more about this <\/a><strong><a href=\"https:\/\/www.deltics.co.nz\/blog\/posts\/2979\">duget<\/a><\/strong><a href=\"https:\/\/www.deltics.co.nz\/blog\/posts\/2979\"> thing, and have seen how to create a package<\/a>.  But a package cannot be consumed &#8216;in situ&#8217; &#8211; it must be made available via a feed.  Which brings us to the <strong>PUSH<\/strong> command.<br><br><strong><em>NOTE: <\/em><\/strong><em>Don\u2019t worry, I have my priorities straight.  This post was written before <a href=\"https:\/\/www.deltics.co.nz\/blog\/posts\/2915\">Liev arrived<\/a>. \ud83d\ude42<\/em><\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">The PUSH Command<\/h2>\n\n\n\n<p>To make a package available for consumption by other projects, it must be <strong>push<\/strong>ed to a feed.  The feeds available are identified in a <strong>duget<\/strong> configuration file named <strong>duget.config<\/strong>.  Actually, <em>multiple<\/em> <strong>duget.config<\/strong> files may be involved.<\/p>\n\n\n\n<p>The first is the &#8216;global&#8217; configuration, which is not strictly global but actually specific to the current user account.  Here&#8217;s mine:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-json\">{\n    packagesFolder: &quot;packages&quot;,\n    feeds: [\n        { name: &quot;alpha&quot;, folder: &quot;\\\\\\\\nuc\\\\duget\\\\alpha&quot; },\n        { name: &quot;release&quot;, folder: &quot;\\\\\\\\nuc\\\\duget\\\\feed&quot; },\n        { name: &quot;duget.org&quot;, url: &quot;https:\/\/api.duget.org\/v1\/index.json&quot; }\n    ],\n    disabledFeeds: [\u201cduget.org\u201d]\n}<\/code><\/pre>\n\n\n\n<p><strong>duget<\/strong> will load this configuration first and then look \u2019up\u2019 the folder hierarchy from the working location, looking for additional <strong>duget.config<\/strong> files.  If found these are then applied, furthest first.  This allows &#8220;local&#8221; configuration changes to be based on the &#8220;inherited&#8221; configuration to that point.  So for example I might introduce an additional <strong>feed<\/strong> to be used by projects in a certain folder, but projects in <em>another<\/em> folder won&#8217;t be aware of that additional feed (unless they are in a sub-folder).<\/p>\n\n\n\n<p class=\"has-background has-pale-cyan-blue-background-color\">There are other variations that can be accomplished with local configs which I won&#8217;t go into here.  But if you&#8217;re familiar with <strong>nuget<\/strong> configuration, you will find this all very familiar.  \ud83d\ude09<\/p>\n\n\n\n<p>The <strong>packagesFolder<\/strong> property identifies a folder to act as the package cache.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The Package Cache<\/h3>\n\n\n\n<p>This is the first place that <strong>duget<\/strong> looks for packages when resolving dependencies.  Obviously when <strong>duget<\/strong> encounters a dependency on a package for the first time (either a new package <strong>id<\/strong> or a new version of a known package) it will not be in the cache and so <strong>duget<\/strong> will attempt to fetch that package from one of the configured feeds.  If successful, the package is stashed in the cache for future reference.<\/p>\n\n\n\n<p>The <strong>feeds<\/strong> property then identifies the feeds that <strong>duget<\/strong> will use to try to find those packages that aren&#8217;t in the cache.<\/p>\n\n\n\n<p>In the example above you can see that I have multiple feeds configured.  The first two are the only two that are actually of any use currently.  The <strong>duget.org<\/strong> http feed is non-functional &#8211; <strong>duget<\/strong> ignores (or rejects) all <em>http<\/em> feeds for now.  In this case I have simply disabled the feed.<\/p>\n\n\n\n<p>Local configuration files can enable\/disable \u201cinherited\u201d feeds in the configuration as well as introducing new feeds.<\/p>\n\n\n\n<p>The two file system feeds configured identify two folders that are shared by my build machine, each representing two feeds &#8211; an alpha feed or \u201cpre-release channel\u201d and a regular feed.  A similar configuration exists on that build machine.  So when a successful build produces an updated package, my dev machines can immediately consume both pre-release and release packages directly from the build machine.<\/p>\n\n\n\n<p>I can of course also push new packages from my dev machine as well, as long as I have the necessary permissions to the file share in question (this is the extent of any security in <strong>duget<\/strong> currently).<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p class=\"has-drop-cap\">Pushing a new or updated package is the same whether from a build machine and uses the <strong>push<\/strong> command.  Again, to push <em>all<\/em> packages from the current folder to the default push feed you would simply:<\/p>\n\n\n\n<p><code>duget push<\/code><\/p>\n\n\n\n<p>With the configuration above this would fail since there is no default push feed configured and so one must be specified on the command line, e.g.:<\/p>\n\n\n\n<p><code>duget push --feed:alpha<\/code><\/p>\n\n\n\n<p>If there are multiple package files in the folder, specific packages may be selected for pushing by specifying those as arguments to the command (just the package id is needed):<\/p>\n\n\n\n<p><code>duget push deltics.smoketest --feed:alpha<\/code><\/p>\n\n\n\n<p class=\"has-background has-luminous-vivid-amber-background-color\">By default the package file will delete any pushed packages from the original folder.  This can be prevented by adding a <code>&lt;strong&gt;--noDelete&lt;\/strong&gt;<\/code> switch.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p class=\"has-text-color has-background has-very-light-gray-color has-very-dark-gray-background-color\">Thus far we&#8217;ve seen how <strong>duget<\/strong> can be used to create packages and make them available for use via one or more feeds.  Tomorrow we&#8217;ll look at how projects consume packages from those feeds with the <strong>restore<\/strong> and <strong>update<\/strong> commands.<\/p>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">3<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span> We now know a little more about this duget thing, and have seen how to create a package. But a package cannot be consumed &#8216;in situ&#8217; &#8211; it must be made available via a feed. Which brings us to the PUSH command. NOTE: Don\u2019t worry, I have my priorities straight. This post was written before [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":2981,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"jetpack_publicize_message":"Duget - how to publish packages to make them available for consumption in projects.","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":[]},"categories":[324,323,4,321,346],"tags":[292,344,345],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/duget-warriors.png?fit=929%2C256&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/p1TKYv-M7","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":2985,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2985\/","url_meta":{"origin":2983,"position":0},"title":"Duget &#8211; RESTORE, UPDATE and What&#8217;s Next ?","date":"26 Sep 2019","format":false,"excerpt":"Wrapping up this short series on duget, discussing RESTORE and UPDATE, arguably most important and useful commands in the duget repertoire.","rel":"","context":"In &quot;automation&quot;","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/duget-warriors.png?fit=929%2C256&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":2979,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2979\/","url_meta":{"origin":2983,"position":1},"title":"Duget Package Manager for Delphi","date":"24 Sep 2019","format":false,"excerpt":"An overview of the the duget package manager, outlining the current state of this project and the first in a quick-fire series to explore the key features.","rel":"","context":"In &quot;automation&quot;","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/duget-warriors.png?fit=929%2C256&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":3000,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/3000\/","url_meta":{"origin":2983,"position":2},"title":"VersionInfo and Semantic Versioning","date":"08 Oct 2019","format":false,"excerpt":"How to make Semantic Version make sense in a VERSIONINFO world without Semantic Versioning.","rel":"","context":"In &quot;automation&quot;","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/bart-simpson-generator-1.png?fit=1024%2C343&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":2936,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2936\/","url_meta":{"origin":2983,"position":3},"title":"Azure DevOps &#8211; Iterative Insertion Fixed!","date":"19 Sep 2019","format":false,"excerpt":"I figured out the iterative insertion problem and my build pipeline is now TIGHT! Fixing it was super-easy in fact, barely an inconvenience.","rel":"","context":"In &quot;automation&quot;","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/pipelines-hero-code-1024x256.jpg?fit=1024%2C256&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":2919,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2919\/","url_meta":{"origin":2983,"position":4},"title":"Azure DevOps &#8211; Now You Too Can Use My Template(s)","date":"14 Sep 2019","format":false,"excerpt":"Learn how you too can use my Delphi build template in your own Azure DevOps pipelines, and a sneak preview of something special coming soon...","rel":"","context":"In &quot;automation&quot;","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/github-512.png?fit=512%2C512&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":2931,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2931\/","url_meta":{"origin":2983,"position":5},"title":"&#8216;Sorry, this script is too long&#8230;&#8217;","date":"18 Sep 2019","format":false,"excerpt":"An object lesson on the importance of defensive programming and providing helpful error messages to your users.","rel":"","context":"In &quot;Azure DevOps&quot;","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Mark_Twain_life_1900s.jpg?fit=883%2C331&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/2983"}],"collection":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/comments?post=2983"}],"version-history":[{"count":4,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/2983\/revisions"}],"predecessor-version":[{"id":2996,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/2983\/revisions\/2996"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/media\/2981"}],"wp:attachment":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/media?parent=2983"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/categories?post=2983"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/tags?post=2983"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}