Hacker Newsnew | past | comments | ask | show | jobs | submit | lihaoyi's commentslogin

I've had a pretty good experience offering bounties on my own projects:

- https://github.com/orgs/com-lihaoyi/discussions/6

If you look at that thread, you'll see I've paid out quite a lot in bounties, somewhere around 50-60kUSD (the amount is not quite precise, because some bounties I completed myself without paying, and others I paid extra when the work turned out to be more than expected). In exchange, I did manage to get quite a lot of work done for that cost

You do get some trash, it does take significant work to review, and not everything is amenable to bounties. But for projects that already have interested users and potential collaborators, sometimes 500-1000USD in cash is enough motivation for someone to go from curious to engaged. And if I can pay someone 500-1000USD to save me a week of work (and associated context switching) it can definitely be worth the cost.

The bounties are certainly not a living wage for people, especially compared to my peers making 1mUSD/yr at some big tech FAANG. It's just a token of appreciation that somehow feels qualitatively different from the money that comes in your twice-monthly paycheck


Is this the standard way to do bounties, where you take applications and then choose someone to attempt the bounty? I always thought you'd just state the requirements and the bounty and then screen the submissions and chose a winner.

Granted this does feel a bit less like asking for spec work so I can see why they might have chosen to go this way instead of generically accepting bounties.


It's not a standard way to do it. Different projects adopt different approaches.

I posted a list of projects offering bounties elsewhere [1] in the thread.

[1] https://news.ycombinator.com/item?id=45278787


I only briefly glanced at your project, but it doesn’t look like a commercial offering or a component of one… what is your motivation for paying people to do this work? I would think bounties would be used more often by companies who need some open source feature for interoperability or integration purposes…


Having more money than free time but still wanting a thing to get done. Lots of folks pay good money for hobbies (video games, golf fees, bicycle purchases, etc.).


Can you deduct these expenditures fully in income tax?


You could deduct them if you have a corporation with some reasonable claim to the IP behind the projects, or a clear business reason for needing the features. There’s probably no clear settled tax law on the specific topic, but I’m sure it would pass an audit as long as there isn’t some egregiously obvious non-business related work being bountied.


That's basically what my MainArgs Scala library does: take either a method definition or class structure and use it's structure to parse your command line arguments. You get the final fields you want immediately without needing to imperatively walk to args array (and probably getting it wrong!)

https://github.com/com-lihaoyi/mainargs


I wrote this, hope everyone finds it as interesting reading this as I did figuring this out for the first time!


Thanks for sharing! I hope to incorporate your bash completion ideas into my CLIs (I've already got zsh completions).

Instead of sourcing the zsh completion script on every startup, you can install it into somewhere on $fpath and zsh will "compile" and cache the completions. This can really speed up shell startup time, but of course is harder to set up. Users have to understand $fpath to put the completions there.

I distribute my CLIs via Homebrew which can install completions automatically.


It's a good first dive into zsh completion. The whole thing is quite the large system to wrap ones head around it and I'm still somewhat struggling.

But at work, I've been slowly adding auto completion to our ansible wrapper scripts, like explanations which playbooks to use when, smart `-l` completion based off a possibly selected playbook (so, if the playbook is postgres.yml, it doesn't suggest mariadb groups), tag autocompletion (with a few, admittedly, hardcoded explanations how these tags should be used) and such.

It's somewhat of a friday-afternoon struggle project, but it's making the big ansible project pretty approachable to use.


Could you share how you do it? Ansible playbooks are ran via command `ansible-playbook` command and it surely has its own tab auto completion script.


It kinda does, but I've added a few bells and whistles to it. Mind you, this is zsh code I haven't really cleaned up, so it's kinda messy and most likely buggy in edge cases.

This needs to be in a directory in your FPATH.

At the core, it uses _arguments to dissect the command line. This both suggests that "-t" exists, is called "tags" and later on sets a state variable to "tags" or "limits" if we're completing these arguments.

    #compdef corp-ansible-wrapper
    _arguments  '-t[tags]:tags:->tags' '-l[limit]:limit:->limits' '-D[diffmode]' '-C[checkmode]' '::optional arg:_files'
    detect_playbook
    case "$state" in
        tags)
        ...
        ;;
        limits)
        ...
        ;;

Given this, the limits autocompletion goes one step further. `detect_playbook` mainly goes through $words and looks for a singular argument looking like "*.yml" and sets that as $PLAYBOOK. Then, based on "$PLAYBOOK", it selects a filter-expression for the groups. This ensures that a `./wrapper mariadb.yml -l<TAB>` only sees mariadb-groups, and not postgres-groups.

All of that is shoved into `_values`, and then the usual zsh completion works, so with something like `./wrapper mariadb.yml -l prj4<TAB>`, zsh tries to filter the values based on the word, so this finds stuff like `prj4`, `prj49`, `dc2_prj45`, and so on, but not `prj5`.

    detect_playbook

    # should be an array.
    case $PLAYBOOK in
        postgres.yml)
            FILTER="pg_\|postgres_\|pgbackrest_"
        ;;
        mariadb.yml)
            FILTER="db_\|mariadb_"
        ;;
        # quite a few more
        *)
            FILTER=""
        ;;
    esac

    # probably overly complex
    ANSIBLE_GROUPS_RAW=$( cat $ANSIBLE_INVENTORY/groups | grep -E "$FILTER" | sort | uniq | tr '\n' ',')
    IFS=',' read -r -A ANSIBLE_GROUPS <<< "$ANSIBLE_GROUPS_RAW"
    _values -s: 'groups' "${ANSIBLE_GROUPS[@]}"
For the tags I'm working on a similar thing, but this contains enough ugly shell-script already. However, the key parts there are:

- You can run `ansible-playbook "$WORD" --list-tags` to get all tags a playbook references in the current inventory.

- One can give `_values` descriptions. If `_values` sees 'foo[bar]' as an option, it will show the user something like: "foo: bar" and only auto-completes to foo.

- This means, we can give standard or well-established tags short descriptions in a directory or an array or whatever, and instead of offering just "postgres_client_tls_certs" as possible auto-completions for `-t`, we can give the user a prompt like "postgres_client_tls_certs: Ensures the postgres cluster has valid and up-to-date TLS certificates for mutual TLS with applications".

It took a bit of time to understand all of this. But now documenting a tag in a place that people actually look at is very easy and straightforward.


Oh, I thought you didn't hardcore those as if conditions, but rather parsed inventory files to get suggestions for -t and parsed tasks in playbook's roles to get suggestions for -l.

Still cool though, thanks for sharing!


Thanks, for the interesting read.


Author here. Mill also helps with running tests. Apart from all tests running parallel by default with heuristics to try and maximize performance (https://mill-build.org/blog/11-jvm-test-parallelism.html), Mill also can selectively execute tests in CI based on code changes (https://mill-build.org/mill/large/selective-execution.html), and provide performance profiles so you can see what is taking up time and improve it (https://mill-build.org/mill/depth/parallelism.html#_mill_chr...). All this is built in and comes for free, with the end result that even tests can take much less time in Mill than they do in other build tools


Thanks for jumping in, that’s actually really helpful context. Parallelism and selective test execution built-in sounds like a huge win, especially for CI and larger teams. I’ll admit the Scala dependency still makes me hesitate a bit for pure Java projects, but clearly Mill’s design is tackling real pain points head-on. Definitely tempted to try it out on a greenfield project.


Author here. Mill definitely works pretty well for monorepos. Within a single module Mill incrementally compiles the Java files, between modules Mill caches and parallelizes things much more aggressively, and when running tests Mill can take your PR's `git diff` and selectively execute only tests downstream of your changes.

This all comes built-in without any plugins or anything, and serves to help speed up dev and CI workflows even on pretty large codebases.


Does Mill have the capability to enforce dependency constraints on transitive versions without declaring them explicitly? I find this to be quite a useful feature for dealing with automated security review and gradle can do that:

https://docs.gradle.org/current/userguide/dependency_constra...


Yes, that's handled by Mill's bill-of-materials (BOM) support https://mill-build.org/mill/fundamentals/library-deps.html#_...


My experience with Bazel (7 years rolling it out and maintaining it in a large company) is that it provides huge value for larger teams/codebases, but at a huge cost in complexity. e.g. the three I rollouts I was closest to each took ~2 person-decades to happen; might be easier now than it was in 2016/2017, but Bazel hasn't really gotten simpler over the years

Mill is intended to be much easier than Bazel. Most people would not use Bazel for a 1-person project, or even a 5-person project, and it only starts pencilling out once you have 50-100 engineers on the team. Mill in contrast works great for small projects and medium projects as well.

One way I'd look at it is that Mill works great for 1-500 person projects, while Bazel works great for 100-5000 person projects. There's some overlap in the middle, but fundamentally they target different kinds of users who have very different constraints and requirements


Please try out Mill! We have a lot of Maven/Gradle/SBT refugees in the community who are quite happy with Mill, so perhaps if you give it a try you'll find a build tool you can be happy with as well


Mill is in many ways trying to be `uv` for the JVM. 3-6x faster than the existing tools, bundling everything necessary builtin without plugin-hell, superior IDE support and toolability than existing tools. If you want a `uv` for Java, you should try out Mill!


> I eschew frameworks in this custom build tool, because the build code should look conventional for whatever language it's written in.

That's really the case with Mill as well, at a deeper more-meaningful level. Mill builds are all built around objects, classes, methods, and overrides.

Maven is XML. Do you write large codebases in XML? Gradle is Groovy/Kotlin, but it's an odd Groovy/Kotlin dialect or DSL that looks totally unlike application codebases, and your IDE is unable to understand and navigate effectively.

Mill is Scala, sure, but what's important is that it is architected around objects, classes, methods, and overrides. Those are the core abstractions when working with Mill, which are the same core abstractions as any Java/Scala/Kotlin application. Thus IDEs are able to navigate Mill builds, profilers like JProfiler or Yourkit can work on Mill builds, and humans who learned Java 101 in college are immediately familiar with the structure and fundamental abstractions of Mill.


Author here. What most people don't realize is that "I hate programming my build." is a symptom of your existing build tools making programming your build dangerous and risky endeavor.

For example, in Maven you typically extend your build in Bash scripts + maven-exec-plugin, Ant script + maven-antrun-plugin, or custom Maven plugins entirely. None of these are "nice" programming environments, with proper IDE support, typechecking, introspectability, and so on. Writing lots of logic in Bash or Ant is risky, so you would be right to minimize writing code in it

Similarly, in Gradle you extend your build in Groovy/Kotlin, but it's a kind of "weird" Groovy/Kotlin unlike anything you'd write in application code. For example, your IDE support in Gradle-Kotlin is much worse than what you get in normal-Kotlin. Despite Gradle-Kotlin being the same language and same IDE, it's a much worse experience writing it, it's much easier to make mistakes, and so you are right to minimize the code you write in it.

In Mill, the build scripts are in Scala, but that's not the important part. The important part is you write normal code using classes, methods, and overrides. IDEs are very good at navigating classes, methods and overrides, and developers are very familiar with working with classes, methods, and overrides. And so build code in Mill feels as comfortable as your application code in Java/Scala/Kotlin: same quality of IDE experience, same typechecking, even can use the same Java third-party libraries (if you wish).

So it's understandable you hate programming your build. In Maven or Gradle or SBT, I'd hate programming my build as well. What Mill offers is that you can program your build where necessary without the hate that comes with doing so in other build tools!


I am old. I used ant, ported to maven when I discovered it (yes Maven 1). Always stuck with it. Maven has been a really nice consistent build tool. I never had to build something so complex it did not know what to do. And no I never used the ant plugin; it's an anti-pattern for Maven. Custom maven plugin's is perfectly fine (I never needed it) but if you need them you probably are doing it wrong (IMHO). My build are never that complex as I mainly write reasonably standard software for businesses.

Nice how you say "your IDE support in...", to refer to IntelliJ. I avoid that. I use Visual Studio Code and Netbeans.

BTW: writing something in bash means it will work for at least a decade. All people on my team will know how it works and understand it and maintain it. Introducing something new mean we all need to learn it. Yesterday my build for a simple website failed because gulp was updated and I ported the entire build to a bash script. It was faster and way simpler.

Let me make it clear here: I hate Grails. I think you have the same gripe as I do. They keep changing the DSL so you need to rewrite your scripts. Since it is a programming language each project has a different build even though most projects are the same. Because people do the same stuff differently.

When I have an issue with maven I will try Mill. Promised.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: