Should I break_the_build?

Started by
12 comments, last by zee_ola05 9 years, 9 months ago

I'm going to preface this topic with the fact that I've only every worked alone on projects.

In the project I'm working on, I have got to a stage where I've finally decided to refactor one of the systems that a lot of the total code depends on. Refactoring this would probably mean refactoring a lot of other code afterwards. Now I realise that I've got to this scenario through a horrible combination of bad design choices and lack of forethought, but my question is what to do when I find myself in this situation.

Because I'm working alone on this project, it doesn't really matter if I just make a new branch, completely refactor the system and then all of the other code afterwards. This could mean that the project won't actually build for days. Again, not too much of a problem considering that I'm working by my self.

What would be your advice if I encounter this when I'm working with a team of programmers? Assuming that the refactoring work HAS to be done, how can I approach this problem so that I cause minimum disruption to the other programmers?

Thanks for your time.

Advertisement
Disruption just has to be managed. Usually there are a few tricks available that can be juggled during the disruptive period.

Private branches allow you to keep the mainline stable for other devs.

Communication is important, you can warn people to steer clear of the code you are changing, on pain of a hellish merge otherwise. If people need to work on the same code at the same time then taking small steps with frequent published commits works well, that way everyone can keep synchronised.

You can also usually achieve partial refactorings, where temporary shim layers and hacks at the seam between new and old soon-to-be-dead code can allow the program to work as normal.

Different shops take different views on this, but it may be perfectly tolerable to enter a period of instability or even brokenness during a radical change - so long as it's planned for and communicated.

Thanks dmatter, good info.

You can also usually achieve partial refactorings, where temporary shim layers and hacks at the seam between new and old soon-to-be-dead code can allow the program to work as normal.

This seems like a very useful skill to learn. I'm going to try and challenge myself to keep the project working as it was previously at every commit, while still slowly changing things around and refactoring.

Yeah this is what branches are for :)
The master branch should always be in a working condition, but your own WIP branches can be broken, as long as no one else on the team expects them to be working.

At my last job, it was almost impossible to break the master branch. Any commits to it were queued up in a staging area, where a build machine would automatically merge/rebase them, compile for every platform/configuration, rebuild any data files if you'd changed the tools, then run the game through a series of tests and AI vs AI matches on every platform. If anything went wrong, your commit would be rejected (and you'd be emailed the error log).
It meant that committing to master took 20mins, but also that the build was never broken. Best system I've ever worked with :D

In other jobs, sometimes a broken build will cause other people to waste half an hour of their time. When you're on a team of 50 people, that's actually a rediculously large amount of money in wasted wages!

Yeah this is what branches are for smile.png
The master branch should always be in a working condition, but your own WIP branches can be broken, as long as no one else on the team expects them to be working.

At my last job, it was almost impossible to break the master branch. Any commits to it were queued up in a staging area, where a build machine would automatically merge/rebase them, compile for every platform/configuration, rebuild any data files if you'd changed the tools, then run the game through a series of tests and AI vs AI matches on every platform. If anything went wrong, your commit would be rejected (and you'd be emailed the error log).
It meant that committing to master took 20mins, but also that the build was never broken. Best system I've ever worked with biggrin.png

In other jobs, sometimes a broken build will cause other people to waste half an hour of their time. When you're on a team of 50 people, that's actually a rediculously large amount of money in wasted wages!

We have that all the way down to the "rejection" part -- bad commits just break the continuous builder, which seems to me to kind of defeat the purpose of the entire pipeline.

That said, yes, in a professional environment, the less downtime in the build, the better. If you need to fix bad architecture, then make a branch (or if you're using something like hg/git, just have a local repo). Even with a totally screwed up arch, you can usually fix each component piecemeal.

EDIT: Honestly, I think this applies to hobby stuff too. The more I treat my hobby work like "professional" work, the happier I am. A lot of work in professional infrastructure goes into reducing headaches and downtime, and I like not having headaches and downtime. I don't think I'll ever make a continuous build server for my side project, but things like keeping the build unbroken, data-driving the game, and pushing what you can into runtime make the process a lot more enjoyable in the long run.


Refactoring this would probably mean refactoring a lot of other code afterwards.

You keep using that word. I do not think it means what you think it means.

"Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure." -- Martin Fowler (one of the small group of authors who put the term into popular use)

When you refactor a chunk of code it should break exactly nothing.

If you are rewriting methods or rewriting your API, then that can break things.

I recommend constantly refactoring your code. Refactor aggressively.

I like to think of it as you would work in a shop. Refactoring is much like sweeping up the scrap bits and sawdust. You need to clean up the code every time you work with it. Failure to do so and you will quickly find yourself ankle-deep in sawdust and unused scrap bits.

"Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure." -- Martin Fowler (one of the small group of authors who put the term into popular use)

What do you call

If you are rewriting methods or rewriting your API, then that can break things.

Can't we call this refactoring too?

And I agree, we should refactor aggressively. :)

"Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure." -- Martin Fowler (one of the small group of authors who put the term into popular use)

What do you call

If you are rewriting methods or rewriting your API, then that can break things.

Can't we call this refactoring too?

And I agree, we should refactor aggressively. smile.png

Redesign, maybe? I'm asking because I usually misuse the word "refactor" too.

It is all about the interface, or the API, or the contracts that you give the user of your library.

It might be that you are the only user of the library. It might be that millions of people use your library. Either way you are providing an interface, a contract, that they can call the function and get reliable results.

Rewrite generally implies that you are throwing it away and starting over from scratch. The entire interface will be different.

Redesign generally implies that pieces will change but much will remain. Some of the interface will be different.

Revision generally implies new features are added. Interfaces will change slightly to accommodate new features.

Refactor means internal changes only. The interface will remain unchanged.

Rewrite generally implies that you are throwing it away and starting over from scratch. The entire interface will be different.

Redesign generally implies that pieces will change but much will remain. Some of the interface will be different.

Revision generally implies new features are added. Interfaces will change slightly to accommodate new features.

Refactor means internal changes only. The interface will remain unchanged.

Ah my bad. Thanks for pointing that out Frob.

I guess what I'm trying to do is redesign without breaking anything.

This topic is closed to new replies.

Advertisement