<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="278121" data-post-id="278121">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="type1fool" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/type1fool/120/26216_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  type1fool
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hey <a class="mention" href="/u/mward-sudo" rel="nofollow">@mward-sudo</a>! Thank you for the feedback.</p>
<p>Getting the session hooks right is a challenge since a refresh will load the page before the socket is connected. In the demo app, I can register, redirect to the login page, save changes, and refresh the page without error.</p>
<p>I think the key is to use <code>assign_new/3</code> to ensure <code>@current_user</code> exists in the session hooks (<a href="https://github.com/liveshowy/webauthn_components_demo/blob/b84af5a217b138aa4d53d73af01b08a2947ef00d/lib/demo_web/hooks/user.ex#L22-L24" rel="noopener nofollow ugc">example</a>). If you’re already doing this, I suspect there is a pattern match somewhere which expects a <code>%User{}</code> struct, and may need to handle the initial <code>nil</code> value.</p>
<p>For what it’s worth, I’ve pulled back on pattern matches in LiveView code, especially matching on <em>types of data</em>. There are exceptions when the code is <a href="https://github.com/liveshowy/webauthn_components_demo/blob/b84af5a217b138aa4d53d73af01b08a2947ef00d/lib/demo_web/hooks/user.ex#L18-L20" rel="noopener nofollow ugc">simple and compact</a>. I started doing this to keep line length down since I typically fold LOC that I’m not working on, and it’s helped avoid some issues like this. Instead, I’ve started to prefer <a href="https://github.com/liveshowy/webauthn_components_demo/blob/b84af5a217b138aa4d53d73af01b08a2947ef00d/lib/demo_web/hooks/user.ex#L53-L59" rel="noopener nofollow ugc">this approach</a> where an assign may exist and the value may be nil or a struct.</p>
<p>Hope that helps.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="278121" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/webauthnlivecomponent-passwordless-auth-for-liveview-apps/49941/22">Post #21</a>
	                </div>
	            </div>
              <div id="likers-container-278121" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="278121"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #21"></div>
  </section>
</div>
    <div class="postbit" id="278403" data-post-id="278403">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="mward-sudo" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mward-sudo/120/26932_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  mward-sudo
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thanks for the reply. I’ll take a detailed look at your suggestion and will let you know what I find.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="278403" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/webauthnlivecomponent-passwordless-auth-for-liveview-apps/49941/23">Post #22</a>
	                </div>
	            </div>
              <div id="likers-container-278403" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="278403"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #22"></div>
  </section>
</div>
    <div class="postbit" id="287268" data-post-id="287268">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="type1fool" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/type1fool/120/26216_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  type1fool
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<h1><a name="p-287268-v040-released-1" class="anchor" href="#p-287268-v040-released-1" aria-label="Heading link" rel="nofollow"></a>v0.4.0 Released</h1>
<p>The latest release of <code>WebauthnComponents</code> adds a new <strong>required</strong> <code>WebauthnUser</code> struct during registration. This allows the parent LiveView to set the id, name, and display name used by the WebAuthn API.</p>
<p>For end users, the experience is greatly improved. Previously, the <code>RegistrationComponent</code> would display the app name (or whatever was passed as an <code>@app</code> assign. If multiple accounts were registered to the same device for an origin, each credential would have the same name, making it impossible to know which one should be selected.</p>
<p>Now, the parent LiveView must pass the new <code>%WebauthnComponents.WebauthnUser{}</code> struct to the <code>RegistrationComponent</code> before registering a user. <strong>You may choose to identify users by email, username, or whatever makes sense for the application.</strong></p>
<p><strong>Registration</strong></p>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/8/8/888fcb7751d676d26951dbf5094e25c27b22fd85.jpeg" data-download-href="https://forum.elixirforum.com/uploads/default/888fcb7751d676d26951dbf5094e25c27b22fd85" title="image" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/original/3X/8/8/888fcb7751d676d26951dbf5094e25c27b22fd85.jpeg" alt="image" data-base62-sha1="ju50VggG6lkE1NTbkpGc3HeCXiJ" width="690" height="241" data-dominant-color="A19D9E"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">1200×420 20.8 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p>
<p>As a result of this new requirement, multiple accounts registered on the same device will have clearer names displayed. During authentication, users will more easily be able to select the correct credential. If a user wants to remove credentials from their preferred manager, it will also be more straightforward to do so thanks to the updated naming requirement.</p>
<p><strong>Authentication</strong></p>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/5/e/5eed9838e7602f306f01f7b36f34c49c80643a61.jpeg" data-download-href="https://forum.elixirforum.com/uploads/default/5eed9838e7602f306f01f7b36f34c49c80643a61" title="image" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/original/3X/5/e/5eed9838e7602f306f01f7b36f34c49c80643a61.jpeg" alt="image" data-base62-sha1="dxLVqRL6bKs3gVyFfWKG7UO8Jxf" width="690" height="277" data-dominant-color="A29E9F"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">1200×483 21.3 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p>
<h2><a name="p-287268-prs-2" class="anchor" href="#p-287268-prs-2" aria-label="Heading link" rel="nofollow"></a>PRs</h2>
<ul>
<li><a href="https://github.com/liveshowy/webauthn_components_demo/pull/16" class="inline-onebox" rel="noopener nofollow ugc">Accept email at sign in by type1fool · Pull Request #16 · liveshowy/webauthn_components_demo · GitHub</a></li>
<li><a href="https://github.com/liveshowy/webauthn_components_demo/pull/16" class="inline-onebox" rel="noopener nofollow ugc">Accept email at sign in by type1fool · Pull Request #16 · liveshowy/webauthn_components_demo · GitHub</a></li>
</ul>
<h2><a name="p-287268-todos-3" class="anchor" href="#p-287268-todos-3" aria-label="Heading link" rel="nofollow"></a>TODOs</h2>
<ul>
<li>Review/improve email validation in the demo app</li>
<li>Update the <code>UserProfile</code> LiveView in the demo app to handle email updates separately now that email is part of the <code>User</code> schema</li>
<li>Clarify that email is only required for registration in the demo app</li>
</ul>
<p>As always, feedback is welcome!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="287268" data-batch-url="/posts/batch_likers">
                        5
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/webauthnlivecomponent-passwordless-auth-for-liveview-apps/49941/24">Post #23</a>
	                </div>
	            </div>
              <div id="likers-container-287268" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="287268"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #23"></div>
  </section>
</div>
    <div class="postbit" id="287275" data-post-id="287275">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Eiji" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Eiji/120/36743_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Eiji
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Looks like <code>1Password</code> would add support for <code>passkeys</code> in <code>June</code>. I did not found any estimates for <code>Bitwarden</code>.</p>
<p>Do anybody know if there is any browser or browser extension that have <code>passkey</code> support? I would like to test it on <code>Linux</code>.</p>
<p><strong>Edit</strong>: I got such (translated) message on <code>Chrome</code>:</p>
<blockquote>
<p>this device does not support the type of security key this website is asking for</p>
</blockquote> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="287275" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/webauthnlivecomponent-passwordless-auth-for-liveview-apps/49941/25">Post #24</a>
	                </div>
	            </div>
              <div id="likers-container-287275" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="287275"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #24"></div>
  </section>
</div>
    <div class="postbit" id="287412" data-post-id="287412">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="type1fool" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/type1fool/120/26216_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  type1fool
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Apparently Chrome on Linux <a href="https://developers.google.com/identity/passkeys/supported-environments#:~:text=browsers%20and%20apps.-,Linux,by%20scanning%20a%20QR%20code" rel="noopener nofollow ugc">doesn’t support Passkeys</a> directly. You’d need to register with another device, then use the QR code in Linux Chrome in order to authenticate that device.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="287412" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/webauthnlivecomponent-passwordless-auth-for-liveview-apps/49941/26">Post #25</a>
	                </div>
	            </div>
              <div id="likers-container-287412" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="287412"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #25"></div>
  </section>
</div>
    <div class="postbit" id="287423" data-post-id="287423">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Eiji" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Eiji/120/36743_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Eiji
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Ehhh … yet another <code>Linux</code> phobia … <img src="https://forum.elixirforum.com/images/emoji/apple/scream.png?v=15" title=":scream:" class="emoji" alt=":scream:" loading="lazy" width="20" height="20"> They <strong>support</strong> or <strong>plan</strong> to support every platform except <code>Linux</code>. <img src="https://forum.elixirforum.com/images/emoji/apple/no_entry_sign.png?v=15" title=":no_entry_sign:" class="emoji" alt=":no_entry_sign:" loading="lazy" width="20" height="20"> What I really don’t understand is when they add support for <code>Mac</code> then <code>Linux</code> is much closer to it than <code>Windows</code>, but somehow magically everyone always have a problem with it. <img src="https://forum.elixirforum.com/images/emoji/apple/magic_wand.png?v=15" title=":magic_wand:" class="emoji" alt=":magic_wand:" loading="lazy" width="20" height="20"> I would really understand if they would not have a client on <code>Linux</code> or if they would not have <code>ChromeOS</code> and <code>Android</code> (which are in fact <code>Linux</code>), but this is some kind of bad joke. <img src="https://forum.elixirforum.com/images/emoji/apple/sweat.png?v=15" title=":sweat:" class="emoji" alt=":sweat:" loading="lazy" width="20" height="20"> btw. If they do not plan to work on <code>Linux</code> and there is no <code>ChromeOS</code> ever mentioned then they favor other operating systems over their own? <img src="https://forum.elixirforum.com/images/emoji/apple/person_facepalming.png?v=15" title=":person_facepalming:" class="emoji" alt=":person_facepalming:" loading="lazy" width="20" height="20">  I understand that <img src="https://forum.elixirforum.com/images/emoji/apple/moneybag.png?v=15" title=":moneybag:" class="emoji" alt=":moneybag:" loading="lazy" width="20" height="20"> changes a lot, but it’s also not so easy to answer with it for every such ridiculous decision. <img src="https://forum.elixirforum.com/images/emoji/apple/exploding_head.png?v=15" title=":exploding_head:" class="emoji" alt=":exploding_head:" loading="lazy" width="20" height="20"></p>
<p>I really like the idea behind <code>passkeys</code> <img src="https://forum.elixirforum.com/images/emoji/apple/key.png?v=15" title=":key:" class="emoji" alt=":key:" loading="lazy" width="20" height="20"> , so I was waiting <img src="https://forum.elixirforum.com/images/emoji/apple/alarm_clock.png?v=15" title=":alarm_clock:" class="emoji" alt=":alarm_clock:" loading="lazy" width="20" height="20"> for at least a basic support for development tests even in some <code>nightly</code> browser releases, but when once again corporations shows this kind of attitude I see that it would not be a real authentication alternative in at least next years regardless of how stable this library is. <img src="https://forum.elixirforum.com/images/emoji/apple/slightly_frowning_face.png?v=15" title=":slightly_frowning_face:" class="emoji" alt=":slightly_frowning_face:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="287423" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/webauthnlivecomponent-passwordless-auth-for-liveview-apps/49941/27">Post #26</a>
	                </div>
	            </div>
              <div id="likers-container-287423" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="287423"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #26"></div>
  </section>
</div>
    <div class="postbit" id="287477" data-post-id="287477">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="type1fool" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/type1fool/120/26216_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  type1fool
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I suspect it has more to do with OS support, which is more complicated in Linux due to the variety of distros. As a web-only dev, I could be wrong on that point.</p>
<p>There’s a <a href="https://discourse.gnome.org/t/passkeys-in-gnome/14648/2" rel="noopener nofollow ugc">thread</a> on the Gnome forum asking about this, fwiw.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="287477" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/webauthnlivecomponent-passwordless-auth-for-liveview-apps/49941/28">Post #27</a>
	                </div>
	            </div>
              <div id="likers-container-287477" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="287477"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #27"></div>
  </section>
</div>
    <div class="postbit" id="287480" data-post-id="287480">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="type1fool" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/type1fool/120/26216_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  type1fool
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<h1><a name="p-287480-v041-1" class="anchor" href="#p-287480-v041-1" aria-label="Heading link" rel="nofollow"></a>v0.4.1</h1>
<p>Dependencies have been updated in the latest release. Thank you <a href="https://github.com/ken-kost" rel="noopener nofollow ugc">Kenneth Kostrešević</a>!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="287480" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/webauthnlivecomponent-passwordless-auth-for-liveview-apps/49941/29">Post #28</a>
	                </div>
	            </div>
              <div id="likers-container-287480" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="287480"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #28"></div>
  </section>
</div>
    <div class="postbit" id="287509" data-post-id="287509">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Eiji" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Eiji/120/36743_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Eiji
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Yeah and that’s why <strong>their own</strong> <code>ChromeOS</code> is not even <strong>mentioned</strong> … This argument died years ago since advanced <code>Linux</code> users have no problem with for example unpacking <code>deb</code> packages and installing apps for a specific user or <strong>simply</strong> compile from source.</p>
<p><strong>TLDR</strong>; Below is more descriptive answer about packages in <code>Linux</code>.</p>
<p>Do you know how hard is to create a package? I didn’t liked that in selected by user packages to install are dependencies required to compile many apps using <code>asdf</code> version manager. I decided to make a quick research checking how hard is to create a meta package. It was <strong>so simple</strong> that I have created few <code>meta</code> packages each for different <code>asdf</code> install and one <code>meta</code> package to install all of them. Now when I want to install software needed on any <code>deb</code>-based distribution I copy-paste my files and run <strong>just one command</strong> to install <code>meta</code> package.</p>
<p>Here is all I need to do:</p>
<pre data-code-wrap="bash"><code class="lang-bash"># create a parent directory for meta packages
mkdir my-packages
# enter parent directory
cd my-packages
# create at once all directories each for one meta package
mkdir meta-a meta-b meta-c …
# in simple loop enter every directory, generate ns-control file and enter parent directory
for dir in `ls`; do cd $dir &amp;&amp; equivs-control ns-control &amp;&amp; cd ..; done
# once all packages are generated I open directory using my text editor
subl .
</code></pre>
<p>Example <code>ns-control</code> file:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">$ cat /usr/local/asdf-meta/asdf-erlang/ns-control
# important for package manager copy-paste data for all ns-control files
# package belongs to development group
Section: devel
# mark package as not necessary for OS
Priority: optional
# declare which standard we use when building package
Standards-Version: 3.9.2

# other copy-pate data for all ns-control files i.e. package name and maintainer
Package: asdf-erlang
Maintainer: Tomasz Sulima &lt;email&gt;

# all our hard work goes here …
# the biggest thing we need to do is copy-paste packages from documentation
# and separate their names using comma (,) character
Depends: autoconf,build-essential,libgl1-mesa-dev,libglu1-mesa-dev,libncurses-dev,libncurses5-dev,libpng-dev,libxml2-utils,m4
Recommends: fop,libssh-dev,libwxgtk-webview3.0-gtk3-dev,libwxgtk3.0-gtk3-dev,openjdk-11-jdk,unixodbc-dev,xsltproc
# a simple word or two …
Description: meta package for Erlang dependencies installed using asdf version manager

# you can also add more information, but those are completely optional and not needed in our case
</code></pre>
<p>Without comments it’s <code>8</code> terribly hard to maintain lines. Only 5 of them were copy-pasted for all packages. That’s inhuman. <img src="https://forum.elixirforum.com/images/emoji/apple/joy.png?v=15" title=":joy:" class="emoji" alt=":joy:" loading="lazy" width="20" height="20"></p>
<blockquote>
<p>But those are not <code>dev</code> files, right?</p>
</blockquote>
<p>Right, I forgot about another <code>loop</code>. Here it goes:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir"># just one word have changed: equivs-control -&gt; equivs-build
for dir in `ls`; do cd $dir &amp;&amp; equivs-build ns-control &amp;&amp; cd ..; done
</code></pre>
<p>ok, so those <code>deb</code> files can be used in some custom repository like for example <code>sublime-text</code> or <code>vivaldi</code> have, but how hard is to add them locally and what about updating them?</p>
<p>That’s also simple:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir"># let's go back to parent directory of the one containing all meta packages
cd ..
# copy this directory where you like
sudo cp my-packages /usr/local
# instruct apt about your custom repository
# trusted=yes is required unless you add extra file with repo information
# which is not needed in our case
echo "deb [trusted=yes] file:/usr/local/my-packages ./" | sudo tee /etc/apt/sources.list.d/my-packages.list
# create a new script available in `PATH` environment variable
subl ~/.local/bin/update-my-packages
# finally mark script as executable
chmod +x ~/.local/bin/update-my-packages
</code></pre>
<p>Finally here is our update script:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">$ cat ~/.local/bin/update-my-packages 
#! /bin/bash
# enter directory we have just copied
cd /usr/local/my-packages
# remove old generated packages
rm Packages.gz
# this line we already well known …
for package in `ls`; do cd $package &amp;&amp; equivs-build ns-control &amp;&amp; cd ..; done
# all you have to do is to generate a Packages.gz
dpkg-scanpackages . /dev/null | gzip -9c &gt; Packages.gz
# we can safely remove unnecessary buildinfo and changes files
# generated using equivs-build command
rm */*.buildinfo */*.changes

# check if the script is runned with root rights or using `sudo` command
if [[ "$EUID" = 0 ]]; then
  # just update
  apt-get update
else
  # make sure to ask for password on next sudo
  sudo -k

  # update with sudo
  if sudo true; then
    sudo apt-get update
  fi
fi
</code></pre>
<p>Now every time you change any <code>ns-control</code> file all you have to do is to call <code>update-my-packages</code> script and the updated <code>deb</code> is available to install using <code>apt</code>. All you have to remember is to update package <code>version</code>. <img src="https://forum.elixirforum.com/images/emoji/apple/wink.png?v=15" title=":wink:" class="emoji" alt=":wink:" loading="lazy" width="20" height="20"></p>
<p>Both research and copy-paste took me “5 min”. Not sure, maybe it’s too much for corporations, but for me that is yet another way to save lots of time especially when filtering out all that <code>build-essentials</code> staff when reading a list of install by user packages. It changed dozens dependency entries in just one entry which remains me that on next installation I need to copy said <code>meta</code> packages.</p>
<hr>
<p>But wait - I still didn’t said the best thing …Regarding the magic complexity … I have followed <code>Ubuntu</code> documentation on <code>MX Linux</code> which is <code>Debian</code> (stable) and not <code>Ubuntu</code>-based distribution. I guess that it would work without problem on all <code>Debian</code>-based distributions.</p>
<p>Now let’s take a look at package types used in most distributions:</p>
<ol>
<li><code>deb</code> (Debian based) - binary</li>
<li><code>ebuild</code> (Gentoo based) - compiles from source</li>
<li><code>pkg.tar.zst</code> (Arch Linux based) - compiles from source</li>
<li><code>rpm</code> (Fedora/SUSE based) - binary</li>
</ol>
<p>Except above there are 3 “portable” formats: <code>AppImage</code>, <code>flatpak</code> and <code>snap</code>.</p>
<p>Most of packages are created by community, some of them are compiling apps from source. The most noticeable problem when changing distribution is <code>glibc</code> version change. You need to recompile (or install binary compiled for your <code>glibc</code> version) all of the software you have copied (I did so when tested copying <code>asdf</code> directory).</p>
<p>Most of work you have to do if you want to support lots of distributions:</p>
<ol>
<li>Check <code>distrowatch</code> for most popular distributions</li>
<li>Collect package type (like <code>deb</code>) and <code>glibc</code> version data</li>
<li>Compile your app from source for each <code>glibc</code> version</li>
<li>Package to <code>deb</code>, <code>pkg.tar.zst</code> and <code>rpm</code> for each <code>glibc</code> + package type combination</li>
<li>Create <code>ebuild</code> for new version, if you did not added dependencies it’s basically copy-paste with changing one number</li>
<li>Optionally also package compiled binaries with <code>AppImage</code>, <code>flatpak</code> and <code>snap</code></li>
<li>Upload all packages you have generated to your repositories</li>
</ol>
<p>So almost whole process you can automate using <code>CI</code>. The other things left is to first create said repositories which you do only once and update <code>package</code> dependencies if needed.</p>
<hr>
<p>If you want to know more simply create a new topic and feel free to ping me. You can also take a look how simple documentation is. For example in case of <code>meta</code> packages you can see:</p><aside class="onebox allowlistedgeneric" data-onebox-src="https://help.ubuntu.com/community/Repositories/Personal">
  <header class="source">

      <a href="https://help.ubuntu.com/community/Repositories/Personal" target="_blank" rel="noopener nofollow ugc">help.ubuntu.com</a>
  </header>

  <article class="onebox-body">
    

<h3><a href="https://help.ubuntu.com/community/Repositories/Personal" target="_blank" rel="noopener nofollow ugc">Repositories/Personal - Community Help Wiki</a></h3>



  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>

<aside class="onebox stackexchange" data-onebox-src="https://askubuntu.com/questions/33413/how-to-create-a-meta-package-that-automatically-installs-other-packages/33417#33417">
  <header class="source">

      <a href="https://askubuntu.com/questions/33413/how-to-create-a-meta-package-that-automatically-installs-other-packages/33417#33417" target="_blank" rel="noopener nofollow ugc">askubuntu.com</a>
  </header>

  <article class="onebox-body">
      <a href="https://askubuntu.com/users/129/ajmitch" target="_blank" rel="noopener nofollow ugc">
    <img alt="ajmitch" src="https://www.gravatar.com/avatar/12203d36db051b320009c86a22a91141?s=256&amp;d=identicon&amp;r=PG" class="thumbnail onebox-avatar" width="256" height="256">
  </a>

<h4>
  <a href="https://askubuntu.com/questions/33413/how-to-create-a-meta-package-that-automatically-installs-other-packages/33417#33417" target="_blank" rel="noopener nofollow ugc">How to create a meta-package that automatically installs other packages?</a>
</h4>

<div class="tags">
  <strong>package-management, dpkg, packaging, metapackages</strong>
</div>

<div class="date">
  
  answered by
  <a href="https://askubuntu.com/users/129/ajmitch" target="_blank" rel="noopener nofollow ugc">
    ajmitch
  </a>
  on <a href="https://askubuntu.com/questions/33413/how-to-create-a-meta-package-that-automatically-installs-other-packages/33417#33417" target="_blank" rel="noopener nofollow ugc">03:46AM - 04 Apr 11 UTC</a>
</div>

  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>
 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="287509" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/webauthnlivecomponent-passwordless-auth-for-liveview-apps/49941/30">Post #29</a>
	                </div>
	            </div>
              <div id="likers-container-287509" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="287509"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #29"></div>
  </section>
</div>
    <div class="postbit" id="288174" data-post-id="288174">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="type1fool" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/type1fool/120/26216_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  type1fool
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thank you for spending the time to share your thoughts. <img src="https://forum.elixirforum.com/images/emoji/apple/pray.png?v=15" title=":pray:" class="emoji" alt=":pray:" loading="lazy" width="20" height="20"> This feels a bit off-topic in the context of this thread, so I’d ask that the discussion of Linux package management find a better home. That writeup would be a great blog post for anyone who’s interested. <img src="https://forum.elixirforum.com/images/emoji/apple/wink.png?v=15" title=":wink:" class="emoji" alt=":wink:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="288174" data-batch-url="/posts/batch_likers">
                        4
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/webauthnlivecomponent-passwordless-auth-for-liveview-apps/49941/31">Post #30</a>
	                </div>
	            </div>
              <div id="likers-container-288174" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="288174"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #30"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/49941/load_more?page=4">Load more posts</a>
</div></template></turbo-stream>