hisham hm

🔗 String interpolation in Lua

Lua is known for having a very lean standard library, and for providing mechanisms to do things instead of a ton of features.

String interpolation isn’t available out of the box, but doing it in Lua isn’t a new trick. In fact, the manual includes it as an example of string.gsub:

local t = {name="lua", version="5.3"}
x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
--> x="lua-5.3.tar.gz"

This applies to members of a table only, though. Python is introducing a general string-interpolation syntax:

a = "Hello"
b = "World"
f"{a} {b}"
f"{a + ' ' + b}"

Given that Lua supports the f"str" syntax for functions with a single string argument, I thought it would be nice to put its Lua-provides-the-mechanisms ethos to test by trying to write my own Python-like f-string formatter.

And here it is, in all its 28-line glory (and I went for readability, and not to write it as short as possible):

function f(str)
   local outer_env = _ENV
   return (str:gsub("%b{}", function(block)
      local code = block:match("{(.*)}")
      local exp_env = {}
      setmetatable(exp_env, { __index = function(_, k)
         local stack_level = 5
         while debug.getinfo(stack_level, "") ~= nil do
            local i = 1
               local name, value = debug.getlocal(stack_level, i)
               if name == k then
                  return value
               i = i + 1
            until name == nil
            stack_level = stack_level + 1
         return rawget(outer_env, k)
      end })
      local fn, err = load("return "..code, "expression `"..code.."`", "t", exp_env)
      if fn then
         return tostring(fn())
         error(err, 0)

It works just like the Python example:

a = "Hello"
b = "World"
print(f"{a} {b}")

Unlike the one-liner from the Lua manual, it also works with local variables:

local c = "Hello"
local d = "World"
print(f"Also works with locals: {c} {d}")

   local h = "Hello"
      local w = "World"
      print(f"Of any scope level: {h} {w}")

Some more demos:

print(f"Allows arbitrary expressions: one plus one is {1 + 1}")

local t = { foo = "bar" }
print(f"And values: t.foo is {t.foo}; print function is {_G.print}")

local ok, err = pcall(function()
   print(f"This fails: { 1 + } ")
print("Errors display nicely: ", err)

If there’s interest, I can make this a module in LuaRocks (probably calling it F rather than f).

Update! This is now available in LuaRocks as a module! Install it with:

luarocks install f-strings

More info at the f-strings GitHub page. Enjoy!

🔗 How to make a pull request on GitHub - a quick tutorial

So you made changes to a project — a bugfix or maybe a new feature — and you want to send it for inclusion in the official (“upstream”) sources. Perhaps you sent an email or opened an issue in the bugtracker, and the project maintainers asked you to send a Pull Request (PR) on GitHub. But how to do this? Here’s a quick how-to guide!

Step 0 - Have a GitHub account

Before anything, you need to have a GitHub account! If you don’t have one already, go to github.com and sign up. Just follow the instructions, it’s easy and free.

Step 1 - “Fork the repository”

“Forking a repository” on GitHub means creating your own Git repository, which is a copy of the original.

Let’s visit a repository and fork it. Start by visiting https://github.com/hishamhm/pull-request-tutorial

In the upper-right there’s a button named “Fork”. It also shows a number: how many times this repository was forked by other people).

Press it, and it will create your own copy of the pull-request-tutorial repository, at https://github.com/YOUR_USERNAME/pull-request-tutorial (the real URL will, of course, contain your own username).

Step 2 - Download your fork and create a branch

Now, it’s time for you to make your changes in the source code (your bugfix or new feature). Start by downloading your repository to your computer. Go to the terminal, make sure git is installed in your computer and type:

git clone https://github.com/YOUR_USERNAME/pull-request-tutorial.git

This will download the files and create a directory called pull-request-tutorial that is linked to your fork (i.e. the copy of the repository under your control).

To avoid trouble later, let’s create a new “branch” in our repository so that the work on our bugfix or feature is stored separately. Pick a meaningful name that represents the changes you plan to make in your code. In our example, I’ll call it “fix-typo”:

git checkout -B fix-typo

Step 3 - Make your changes in your fork

Now enter the directory of your local fork, and edit it at will, implementing your bugfix or feature.

If you create a new file, remember to add it with git add:

git add new_file.txt

Commit your changes, adding a description of what was added. If you’re not used to Git, the simplest way is to commit all modified files and add a description message of your changes in a single command like this:

git commit -a -m "Fix typo in README file"

(But there are lots of ways to choose which files (and even parts of files) do commit and edit the commit message. Look for the Git documentation for details.)

Once your changes are committed, “push” the changes: send them to your GitHub repository using git push

git push

(The first time you push from a branch, Git will complain that your local branch in your computer is not connected to a branch in the GitHub server. Just do what the command tells you to do:

git push --set-upstream origin fix-typo

Next time you push again to this repository, just “git push” will do fine.)

Now, when you visit https://github.com/YOUR_USERNAME/pull-request-tutorial again, you should see your changes there.

Step 4 - Make the Pull Request

This is the simplest step! In your repository page, the next time you open the page after pushing to a new branch, there’s a big green button saying “Compare & pull request”. Press it!

This will open a page in which you’ll be able to further edit the description for your proposed changes. Write down a nice report explaining why these changes should be included in the official sources of your project, and then confirm.

The project authors will receive an email notification that you sent them a PR. Then it’s their turn to read it and comment. You will get notifications when they comment. If they suggest any changes to your bugfix or feature, go back to Step 3, edit it and push again: your Pull Request will be automatically updated. If they are happy with the changes and want to integrate your contributions to the project, the maintainers will click “Merge” and your code will become part of the original repository!

If you want to give it a try, feel free to use the repository I created for this tutorial: https://github.com/hishamhm/pull-request-tutorial

Fork it, edit it, commit and push your changes and send me a PR!

If you liked this tutorial, leave a star on its repo. :)

🔗 Vídeos em HTML5 no GloboEsporte com Firefox 40 no Linux

Escrevendo aqui para quem estiver com o mesmo problema que eu.

Desde que o GloboEsporte mudou de Flash para HTML5, os vídeos pararam de tocar no Firefox (39 e 40, pelo menos) no Linux. Aqui está como habilitar os recursos para fazer voltar a funcionar:

  1. Na barra de endereços, digite about:config. Vai aparecer uma lista de configurações.
  2. Na barra de busca de configurações, digite media.frag. A lista vai filtrar e aparecer opções começando com “media.fragmented”
  3. Dê duplo-clique nas seguintes opções, para trocá-las de “false” para “true”:
    • media.fragmented-mp4.exposed
    • media.fragmented-mp4.ffmpeg.enabled
    • media.fragmented-mp4.gmp.enabled
  4. Na barra de busca de configurações, digite media.media. A lista vai filtrar e aparecer opções começando com “media.mediasource”
  5. Dê duplo-clique nas seguintes opções, para trocá-las de “false” para “true”:
    • media.mediasource.enabled
    • media.mediasource.webm.enabled
  6. Pronto!

Encontrei a solução aqui.

🔗 A comparison between Linux and FreeBSD ps columns

Here’s a diff between which columns are supported in Linux and FreeBSD ps commands, with aliases cleaned up by hand. The lists were gathered from their respective manpages. This is based on ps from FreeBSD 11.0 and from Linux procps-ng 3.3.9.

--- freebsd-ps-columns.txt	2015-03-15 23:44:58.710635450 -0300
+++ linux-ps-columns.txt	2015-03-15 23:42:43.894637864 -0300
@@ -1,81 +1,84 @@

🔗 Migrating my projects from SourceForge+Subversion to Github+Git

It’s been a while that I’ve been using Git comfortably — even though I still get stumped now and then, the workflow is much better than Subversion. I do finer grained commits with ease and I’m no longer afraid of making branches. Still, some projects of mine are still hosted in svn servers, mostly due to inertia and because they’re mostly single-person projects with the occasional patch and bug report but not much collaboration. For a more “social” project such as LuaRocks, git and Github have proven to be very useful tools.

Farewell to SourceForge

This, however, was the push I needed to move my projects away from SourceForge. From gimp.org:

In the past few months, we have received some complaints about the site where the GIMP installers for the Microsoft Windows platforms are hosted.

SourceForge, once a useful and trustworthy place to develop and host FLOSS applications, has faced a problem with the ads they allow on their sites - the green “Download here” buttons that appear on many, many adds leading to all kinds of unwanted utilities have been spotted there as well.

The tipping point was the introduction of their own SourceForge Installer software, which bundles third-party offers with Free Software packages. We do not want to support this kind of behavior, and have thus decided to abandon SourceForge.

From now on, Jernej Simončič, who provides the installer packages, uploads them to our FTP directly, and from there they will be distributed automatically to our mirrors. Please check Downloads page for updated information. http://gimp-win.sourceforge.net will remain active for the time being and direct users to the new download locations.

This saddens me a lot. I’ve been a SourceForge user for over 13 years. Having my first project there with a “.sourceforge.net” URL was a moment of pride; I felt I was becoming a free software developer “for real”, seeing my code there along with all those other projects I relied on daily, such as GIMP.

htop, in particular, has lived a beautiful life in SourceForge:

It blows my mind to think that these are direct downloads of the source code only. I assume the vast majority of users install htop running the distro package manager (apt-get, yum, etc.) but I have absolutely no way to estimate how many times this program has been installed. And that’s not only okay, it’s beautiful: it’s the nature of free software, the actual freedom, at work. There is no tight grip on users from a central authority, the code is roaming free in what is essentially a network of solidarity. I’ve certainly benefited from this network much more than I’ve contributed to it, but I’m happy to give a small part.

Another achievement I’m very proud of: a perfect 5-star rating score for htop. Surely not that many reviews when compared to really big projects, but it’s noteworthy to me at least, and I’m thankful to everyone who rated.

So, thanks for everything SourceForge, but it looks like it’s time to move on.

Say hello to Github, htop

I’ve already got a bunch of projects in Github so this change should not be traumatic.

I’m converting the repositories to Github and moving the website to my own domain. I’ve started with dit, which is a low-profile project, and everything went smoothly. So it’s time to do the same with htop.

The process is straightforward:

  1. Here are the Instructions for importing from Subversion from Github
  2. They recommend using svn2git. It took me a few tries to get the conversion perfect. I recommend taking a look at the generated repository with gitk and creating a file called ~/.svn2git/authors containing aliases matching your svn usernames with Github equivalents.

    My authors file looks like this:

    loderunner = Hisham Muhammad <hisham@gobolinux.org>
    hisham = Hisham Muhammad <hisham@gobolinux.org>

    And the command-line for svn2git:

    svn2git svn://svn.code.sf.net/p/htop/code/
  3. The next step was to create a new Github repository. I did that through their web interface.
  4. And then, to push the code from the locally generated git repo to Github:
    git remote add origin https://github.com/hishamhm/htop.git
    git push -u origin master
  5. Next, I wanted to download the htop website from SourceForge. I usually edited things straight through their shell account, but this got me to an SFTP session in which I could fetch the files:
    sftp loderunner,htop@frs.sf.net

    (By the way, I actually use yafc, which I highly recommend, instead of sftp. Also, as I looked for its URL to post on this paragraph, I just learned that the original yafc 1.1.1 from 2001, which I still use and was hosted in SourceForge and sat there for years without updates, has been taken by a new group of developers who resurrected the project and develop it in Github.)

    The site for htop is really simple so moving it to a new location was a relatively quick process; just needed to grep all references to sf.net and svn, and get my own direct Paypal donation button (to replicate the one I had in SourceForge I used this and this).

  6. Getting the archive of releases was a bit trickier. It’s also in frs.sf.net, but you need to know the correct directory. It doesn’t show up when you log in and ls. You have to cd to it:
    yafc ftp://loderunner@frs.sf.net
    # then, in the sftp session:
    cd /home/frs/project/htop
    get -p -r htop

    Now I have an archive of all releases, with their (mostly accurate) historical timestamps!

  7. The final steps are shutting down the sf.net services, such as the bug tracker and the code repository. This can be done easily through their admin interface. I’ve never had any plans to migrate the bug tracker history; this simplifies things (and I don’t even know if it’s possible). I’m not shutting everything down immediately, though: until I make a proper new release and distro maintainers catch up with the new URLs, I’ll keep the download links active there.

    The original website, however, is now gone and replaced with the following:

    <meta http-equiv="refresh" content="0; url=http://hisham.hm/htop">

    (I did try an .htaccess file, but the sf.net servers kept redirecting to a default page even when I tried to do it via html… thanks to Lynx I realized it was redirecting with a 403 Forbidden error, so I removed the .htaccess file and things worked as expected.)

  8. Still TODO: migrate the htop-general mailing list.

One criticism I’ve had of Github in the past was that it did not promote a culture of making proper releases like SourceForge always did, but that has improved in recent years. Github now has a “releases” feature which, while not perfect, does the job in many cases. I’m not sure if I’ll use it, since I prefer to make the tarballs for htop using the make dist feature from GNU Autotools. I hope to cause as little disruption as possible to the distro maintainers and I want to keep my packages looking the same.

The big test for the new setup will be the next release, which I hope to make in time for htop’s tenth anniversary(!), in the coming months. It is quite fitting that htop presents its new home in such a special occasion!

Latest posts


Admin area