
Show HN: Xcnotary – a Mac app notarization helper made with Rust - davidvartan
https://github.com/akeru-inc/xcnotary/blob/master/README.md
======
davidvartan
(The author.) I had originally written a version of this in Python for my own
use, and recently thought of rewriting it in Rust as a learning experience.

What I found is that writing a CLI in Rust is a absolute breeze, in part due
to excellent documentation and the tooling, and also thanks to various well-
maintained crates, such as StructOpt [1] to parse command line arguments of
any complexity, or indicatif [2] to show animated progress.

[1] [https://github.com/akeru-
inc/xcnotary/blob/11649e49892d81754...](https://github.com/akeru-
inc/xcnotary/blob/11649e49892d8175470bf992661d6410cd9ead1d/src/main.rs#L11-L26)

[2] [https://github.com/akeru-
inc/xcnotary/blob/11649e49892d81754...](https://github.com/akeru-
inc/xcnotary/blob/11649e49892d8175470bf992661d6410cd9ead1d/src/notarize/run.rs#L182-L192)

~~~
tedmielczarek
Very cool! Tangentially related, I looked into reimplementing `codesign` in
Rust while I was at Mozilla. We wanted to see if we could take Apple hardware
out of the loop for our release process after we had switched Mac Firefox
builds to cross-compile from Linux. I got a bunch of code written and I'm
pretty sure I could have made it work if I had gotten the go-ahead to spend
time on it but then we heard about notarization and decided it wasn't worth
the effort since Apple was going to require us to use their service anyway.

~~~
detaro
> _after we had switched Mac Firefox builds to cross-compile from Linux_

Do you happen to have a link with more details about how that's done?

~~~
tedmielczarek
It's not really written down anywhere but you can see the gory history of how
we got it together in bugzilla:
[https://bugzilla.mozilla.org/show_bug.cgi?id=921040](https://bugzilla.mozilla.org/show_bug.cgi?id=921040)

We used the MacOSX SDK from Xcode, packaged up into our internal file store
for build machines to use and passed a bunch of compiler options that clang
sets by default when you're compiling on macOS:
[https://searchfox.org/mozilla-
central/rev/72e3388f74458d369a...](https://searchfox.org/mozilla-
central/rev/72e3388f74458d369af4f6cdbaeaacb719523b8c/build/macosx/cross-
mozconfig.common)

Getting DMG creation working was a bit of a hassle but we managed to get it
done with some dmg/hfsplus tools from the iPhone jailbreak scene.

------
robenkleene
There’s also a nice GUI app called “SD Notary” from a well-respected, long-
time Mac app developer (Late Night Software, developer of Script Debugger)
[https://latenightsw.com/sd-notary-notarizing-made-
easy/](https://latenightsw.com/sd-notary-notarizing-made-easy/)

------
ridiculous_fish
Thank you for building this. The notarization process is navigable but
baroque, especially from the command line.

fish shell's notarization script: [https://github.com/fish-shell/fish-
shell/blob/master/build_t...](https://github.com/fish-shell/fish-
shell/blob/master/build_tools/mac_notarize.sh)

~~~
robin_reala
Strange that it’s written in Bash!

~~~
faho
This is necessary for _building_ fish. If we wrote it in fish script, we'd run
into the bootstrapping problem, where you'd need fish to build fish.

------
_bxg1
Very cool utility. Rust seems like an odd choice since there's little
processing work to be done other than the zipping - which could be outsourced
to the "zip" tool - but I guess a learning exercise is a learning exercise.

~~~
cjbassi
Rust is actually great for cli applications regardless of performance benefits
because of its good ergonomics and package management once you get over the
hump of learning it.

~~~
jfkebwjsbx
The comparison is against Python, which definitely has better ergonomics and
includes everything needed for scripts like this (but does have package
management too if the huge standard library is not enough).

~~~
nicoburns
I disagree that Python has better ergonomics than Rust for scripts like this.
For example, IMO python doesn't have anything as nice as Rust's structopt
library for argument parsing
([https://github.com/TeXitoi/structopt](https://github.com/TeXitoi/structopt)).
Python does have package management, but it's a pain to use compared to Rust
or JavaScript (have to setup virtual envs, etc - not very ergonomic!).

You also mostly don't hit into the tricky ownership issues that can make Rust
less ergonomic in CLI apps. Because the code flow is usually quite linear, so
you don't have multiple bits of code trying to access the same variables at
once.

Note: Although Rust has static types, it has very good type inference such
that you don't often have to explicitly state the types. IMO this brings Rust
pretty close to dynamic language ergonomics for simple things like this.

~~~
jfkebwjsbx
Python has argparse _in the standard library_ which does everything you may
need and more. You can even make Git-like interfaces with it.

For most CLI tools you do not even need third-party packages in Python to
begin with. You cannot beat that. And if you do, you don't need virtualenvs,
because your system package manager can do the job just fine for most cases,
or you can use pip or you can locally deploy.

Python has no ownership issues to think about. You cannot beat that either.

Type inference is nowhere close to dynamic typing.

Then there are other things like no compile-edit cycle in Python. No binary
distribution. No shenanigans like issues with missing libraries and dynamic
linking.

So you may disagree, but your points are not valid. The actual advantage for
going for a compiled low-level language is _performance_ , so unless you need
that, there is no point on using Rust or any other compiled language for the
majority of the boilerplate code for small scripts and CLI tools.

------
filmgirlcw
I love this. Amazing work — thanks for making this process easier.

~~~
davidvartan
Thank you!

------
cmyr
Neat! I was just about to need something like this, for building native app
bundles for druid[1]. I'll open an issue, but do you have any interest in
exposing this as a library?

[1] [https://github.com/xi-editor/druid](https://github.com/xi-editor/druid)

------
leecb
Very cool work! I just manually implemented this in a python script.

Does it support other platforms? Will it run on Linux?

~~~
davidvartan
The notarization service is opaque (uses Xcode's "xcrun altool" to submit/read
status, instead of something like a REST API...) so unfortunately Mac-only at
the moment.

~~~
baszalmstra
That's too bad, I would've loved to do this from a docker container.

------
saagarjha
Aside: GitHub seems to dislike your animated SVG for some reason, since it
won't play unless I open it manually. I think sanitize=true does that; try
hosting it somewhere else?

~~~
davidvartan
Thanks for the heads up! May I ask what browser you are using? If there are
compatibility issues I may just re-render these as GIFs.

~~~
Sephr
How did you generate this animated SVG terminal screen capture?

~~~
davidvartan
asciinema to generate a raw json file, then svg-term to convert it to svg

[https://github.com/asciinema/asciinema](https://github.com/asciinema/asciinema)

[https://github.com/marionebl/svg-term-cli](https://github.com/marionebl/svg-
term-cli)

(I ended up moving the SVG assets to GitHub Pages which hopefully fixes the
issue others were seeing.)

