<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>emre şahin's digital garden 🍃 - feature-flags</title>
    <link>https://emresahin.net/tags/feature-flags/</link>
    <description>Posts in the feature-flags tag</description>
    <language>en</language>
    <managingEditor>contact@emresahin.net (Emre Şahin)</managingEditor>
    <lastBuildDate>Tue, 15 Sep 2026 19:46:32 +0000</lastBuildDate>
    <atom:link href="https://emresahin.net/tags/feature-flags/rss.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title>devlog 15</title>
      <published>2025-01-20T12:51:56+00:00</published>
      <updated>2025-01-20T12:51:56+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Mon, 20 Jan 2025 12:51:56 +0000</pubDate>
      <link>https://emresahin.net/devlog-15/</link>
      <guid isPermaLink="true">https://emresahin.net/devlog-15/</guid>
      <description>🐢 Should we go into completions directly, or do we have anything to update in the working scripts? 🐇 Starting with completions is better. One question I have is whether the completions work for subcommands as usual, like in the static completions. 🐢 Yes, they work. We need to add: source &lt;(COMPLE...</description>
      <category>xvc</category>
      <category>clap</category>
      <category>clap-complete</category>
      <category>zsh</category>
      <category>git</category>
      <category>xvc-file</category>
      <category>xvc-pipeline</category>
      <category>Rust</category>
      <category>refactoring</category>
      <category>CLI design</category>
      <category>feature flags</category>
      <content:encoded><![CDATA[<p>🐢 Should we go into completions directly, or do we have anything to update in the working scripts?</p>
<p>🐇 Starting with completions is better. One question I have is whether the completions work for subcommands as usual, like in the static completions.</p>
<p>🐢 Yes, they work. We need to add:</p>
<pre><code class="language-sh">source &lt;(COMPLETE=zsh xvc)
</code></pre>
<p>to <code>.zshrc</code>, though.</p>
<p>🐇 It looks like we can drop the <code>xvc completions</code> command. We’re just checking the <code>COMPLETE</code> environment variable, and there’s no need for a separate command in this case.</p>
<p>🐢 Yes, let’s remove that.</p>
<p>🐇 Maybe we can employ a <code>completions</code> module for all completion-related functionality. It’s a separate thing, you know.</p>
<p>🐢 Which completions do we need?</p>
<p>🐇 We can just mark them with TODOs now.</p>
<p>🐢 Yes, let’s check where we need completions and what.</p>
<p>🐇 I noticed we’re repeating options in <code>XvcFileCLI</code>, and some of the options are missing, e.g., <code>--from-ref</code> and <code>--to-branch</code>.</p>
<p>🐢 Because it can compile into a different binary, and <code>global</code> options don’t work that way. Maybe we can move all these binaries into different files under <code>lib</code>. We can have feature flags to turn off certain features and compile different binaries.</p>
<p>🦊 Let’s search for it; I haven’t seen it before: building different binaries with feature flags using <code>cargo</code>.</p>
<p>🐢 There is no clear-cut solution, but it looks like we can move all binaries to the root with the <a href="https://rustwiki.org/en/cargo/reference/cargo-targets.html#the-required-features-field"><code>required-features</code></a> field.</p>
<p>🐲 We can postpone this to another release.</p>
<p>🐇 Yes, let’s not spend time on this now.</p>
<p>🐢 Should we try making <code>pipeline_name</code> a global option? It’s repeating everywhere.</p>
<p>🐇 That will make it easier to maintain.</p>
<p>🐢 We’ll have to pass <code>pipeline_name</code> to subcommands, though.</p>
<p>🐇 I think we can have a set of global options that we can pass. For the time being, that’s only the <code>pipeline_name</code>.</p>
<p>🐢 Okay. Let’s do this.</p>
<p>🐇 A similar option is the step name for pipeline steps.</p>
<p>🐢 Dependencies will need a revamp in the next version anyway. So let’s keep it for now.</p>
<p>🐲 Also, the semantics of <code>step-name</code> are different for these commands. <code>step new</code> interprets it as a new name, while <code>step dependency</code> interprets it as an existing name. The first can be renamed to <code>--name</code>, and the second can be <code>--to</code>, as one of its aliases suggests.</p>
<p>🐢 Yes, let’s keep it for now, and we’ll continue to work on others.</p>
<p>🦊 I want to post a comment in the <code>clap</code> discussions.</p>
<p>🐢 Wrote it. Now let’s build it after changing the <code>pipeline_name</code>.</p>
<p>🐇 It compiles. Should we test it?</p>
<p>🐢 I think we’ll test after all this completion work is done.</p>
<p>🐇 We did most of the <code>strum</code>-related completion.</p>
<p>🐢 Didn’t test them yet, though.</p>
<p>🐇 This is Rust. It will work if it compiles, and it compiles.</p>]]></content:encoded>
    </item>
    <item>
      <title>Xvc Devlog - 221109</title>
      <published>2022-11-10T09:26:00+00:00</published>
      <updated>2022-11-10T09:26:00+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Thu, 10 Nov 2022 09:26:00 +0000</pubDate>
      <link>https://emresahin.net/xvc-devlog---221109/</link>
      <guid isPermaLink="true">https://emresahin.net/xvc-devlog---221109/</guid>
      <description>🐇 How do you want to proceed from here, Mr. 🐢? 🐢 I think I can implement Rsync today. Looking at ssh2-rs , though, I think we can implement file transfer without relying on rsync . It might be easier to implement everything within the code. 🐇 Then you should rename the issue to new ssh . 🐢 Fair. ...</description>
      <category>devlog</category>
      <category>development</category>
      <category>xvc</category>
      <category>ssh</category>
      <category>rsync</category>
      <category>storage</category>
      <category>feature-flags</category>
      <category>rust</category>
      <category>libssh2</category>
      <content:encoded><![CDATA[<p>🐇 How do you want to proceed from here, Mr. 🐢?</p>
<p>🐢 I think I can implement Rsync today. Looking at <a href="https://docs.rs/ssh2/latest/ssh2/">ssh2-rs</a>, though, I think we can implement file transfer without relying on <code>rsync</code>. It might be easier to implement everything within the code.</p>
<p>🐇 Then you should rename the issue to <code>new ssh</code>.</p>
<p>🐢 Fair. There is also the <a href="https://docs.rs/ssh-rs/0.2.2/ssh_rs/">ssh_rs</a> crate, but it doesn’t have full support for the protocol. Instead, we can have another command, like <code>xvc storage new ssh</code>, that uses <code>libssh2</code> via the crate mentioned above. It has some limitations with OpenSSH on macOS.</p>
<p>🐇 From the <a href="https://github.com/alexcrichton/ssh2-rs">crate’s README</a>, it looks like you can enable the <code>vendored-openssl</code> feature to compile it statically.</p>
<p>🐢 Let’s go ahead then. It’s better to compile it behind a feature flag, though.</p>
<p>🐇 Yup. Rsync can be separate. I think for now you can implement rsync via <code>Exec::cmd</code> and make <code>new ssh</code> a new issue.</p>
<p>🐢 I’ll copy this conversation there.</p>
<hr>
<p>🐇 Now, let’s start implementing <code>rsync</code>.</p>
<p>🐢 Do we really want to hide it behind a feature flag? It doesn’t bring any extra complexity to <code>generic</code>, for example—just using the commands and returning the errors.</p>
<p>🐇 I think so. If the user doesn’t have <code>rsync</code> on their system, they’ll just get errors. We don’t need to make the implementation optional, but the tests might be.</p>
<p>🐢 OK.</p>]]></content:encoded>
    </item>
    <item>
      <title>Feature flags in Rust</title>
      <published>2022-10-01T14:09:00+00:00</published>
      <updated>2022-10-01T14:09:00+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Sat, 01 Oct 2022 14:09:00 +0000</pubDate>
      <link>https://emresahin.net/Feature-flags-in-Rust/</link>
      <guid isPermaLink="true">https://emresahin.net/Feature-flags-in-Rust/</guid>
      <description>Rust allows you to define feature flags to compile certain parts of a binary conditionally. The Cargo Book has an extensive section on them. The Cargo.toml file can have a [features] section. In this section, features can be defined, and they can enable other features. [features] my-feature = [] ...</description>
      <category>Rust</category>
      <category>Software Development</category>
      <category>Rust</category>
      <category>Cargo</category>
      <category>Feature Flags</category>
      <category>Conditional Compilation</category>
      <category>Configuration</category>
      <content:encoded><![CDATA[<p>Rust allows you to define feature flags to compile certain parts of a binary conditionally.
The Cargo Book has an extensive <a href="https://doc.rust-lang.org/cargo/reference/features.html">section</a> on them.</p>
<p>The <code>Cargo.toml</code> file can have a <code>[features]</code> section.
In this section, features can be defined, and they can enable other features.</p>
<pre><code class="language-toml">[features]
my-feature = []
another-feature = ["my-feature"]
</code></pre>
<p>These markers are used in the code as follows:</p>
<pre><code class="language-rust">
#[cfg(feature = "my-feature")]
pub mod my_module;
</code></pre>
<p>The default features are listed under the <code>default</code> key of the <code>[features]</code> section.
If it’s not defined, it’s considered empty, so <code>cargo build</code> supplies no features to the build system by default.</p>
<p>If you don’t want <code>default</code> features added automatically, you can use the <code>--no-default-features</code> option with <code>cargo</code>.</p>
<p>Starting from Rust 1.60, dependencies can be tied to features.
When you define a dependency in the <code>[dependencies]</code> section, add <code>optional = true</code> to its options. Then, in <code>[features]</code>, use the <code>dep:package</code> syntax.</p>
<pre><code class="language-toml">
[dependencies]

pack = { version = "1.0", optional = true }

[features]

my-feature = ["dep:pack"]
</code></pre>
<p>This way, Cargo doesn’t compile <code>pack</code> if <code>my-feature</code> is not enabled.</p>
<p>A caveat to using features is that they should be additive.
There shouldn’t be a <code>no-std</code> feature to remove the standard library dependency; instead, you should define a <code>std</code> feature and enable it by default.
The reason behind this is that Cargo ensures there is a single copy of a package with <em>all</em> the requested features enabled for the entire dependency graph.
If you have a <code>no-x</code> feature that removes functionality, it breaks the additive logic of Cargo’s feature resolution.</p>]]></content:encoded>
    </item>
  </channel>
</rss>
