Contributing to SC using a GUI - mtmccrea/supercollider GitHub Wiki
Have an idea of something you’d like to contribute to SC, but don’t know how to use git? This tutorial will walk you through the steps of cloning the SC source code, making a change to it, and submitting that change as a Pull Request for review for inclusion in your favorite music making application, SuperCollider.
We’ll use GitHub Desktop so you won’t need to use git directly, or the command line, at all. But you’ll learn the basic git workflow which might be helpful for learning git later.
- Preliminary steps
- What is going to happen
- Get your own copy of SC
- Making Changes
- Saving your changes locally and remotely
- Submitting your changes in a Pull Request
- The Review process
- Going further
- Other types of changes, workflows, and resources
- The SuperCollider source code lives on GitHub, so in order to author a change you’ll need a GitHub account.
- You’ll need the GitHub Desktop application. This is your graphical interface to source code control with git.
- Open GitHub Desktop and sign into your GitHub account within the app—you’ll either be prompted to log into GitHub when first opening the app, or you can log in from the menu bar GitHub Desktop → Settings.
Here’s an overview of what’s going to happen in this tutorial. You’re going to:
-
Create a copy of the SuperCollider repository (“repo”) over to your GitHub account.
The public repo is called the upstream repo and your copy on GitHub is called the origin repo.
-
Copy (“clone”) your origin repo from GitHub to your local computer—this is your local repo.
-
Create a feature “branch” in your local repo—a new unique history of work to be built on top of the repo’s previous history.
-
Change files in the repo locally.
-
Save ("commit") those changes locally, storing them in your branch history.
-
Upload ("push") your local feature branch and its commits to your origin repo so that your local changes are also reflected in your origin repo.
-
Open a "Pull Request" (PR) asking for the new work in your feature branch to be reviewed and possibly “merged” from your origin repo into the public upstream repo.
Once you have your GitHub account set up, head over to the Supercollider repository.
- You’ll create a fork, or copy, of the repository to store in your own GitHub account. The public SC repo is the upstream repo. Your fork will be your origin repo.
- Click the Fork button at the top right.
- When prompted to create a fork, choose an owner (in case you have multiple options), and feel free to just leave all the rest of the defaults.
More options and details
You could give your fork of SC a unique name, which can be helpful to easily spot *your* version at-a-glance in the future. For example, if Aphex Twin were forking SC, they may call their copy supercollider-at.
Another option, indicated by the bottom check box, is to copy only the `develop` branch. Deselecting this will copy *all* branches from the upstream repository (there are many).
How do I know if I need more than the `develop` branch?
Any future changes you make will be on a new branch that you create in your fork (copy) of SC. That new branch will (nearly) always stem from, and be submitted back to, the `develop` branch. So it’s ok to just copy the `develop` branch for now. You can always get the other branches later.
But if you expect to get more involved with SC than making just a couple of changes from time to time, it will make sense to deselect this checkbox and get all the branches. E.g. for longer-term projects it can be useful to compare your changes to other branches, namely `main`, which reflects the current SuperCollider release in circulation.
- Click Create Fork.
After creating your fork of supercollider, you’ll be taken to the origin repository on your GitHub account. Note the url: github.com/yourGitHubUsername/supercollider.
Congratulations, you have your very own SuperCollider 😊
Your fork of SC is stored in your GitHub account. To make changes to the code you’ll need a local copy on your computer. There are two ways to do this:
- Clone (download) directly from GitHub.com.
- On the GitHub page of your SC fork, click the Code button and you’ll see an option to Open with GitHub Desktop.
- This will take you to the GitHub Desktop app and prompt you to clone the repository.
- Clone it from within the GitHub Desktop app.
- In the app, click File → Clone Repository… You’ll be prompted with the dialogue to choose a repository to clone…
- Enter the URL of your origin repo. (This is already filled in if you cloned directly from GitHub.)
- You can type it in, or copy from your GitHub repository webpage by clicking the Code button and copying the URL to the clipboard.
- Alternatively, in the Clone a Repository dialogue, you can select the GitHub.com tab to have it automagically scan for repositories in your GitHub account.
- Finally, choose a Local Path where you’d like to store the local copy of the repository.
Considerations
You might already have, or want to create, a directory in your home or documents folder where you keep source code, like /src or /dev, etc.
It's best to choose a place you want to keep SC for a while 🏖️. We won’t be building the SuperCollider app in this tutorial (it's unnecessary when just modifying Help files) but you may want to make future changes that require building the app. When you do, lots of build files will be generated that may refer to this Local Path. So if you move this directory later, you may have to re-initialize the build process.
-
Click Clone.
- You may be prompted whether you want your local repository to be configured to contribute to the upstream project. Agreeing to this will make your future pull requests a bit more streamlined.
With SuperCollider freshly cloned, you’ll see something like this:
Everything went ok? 🤞
SuperCollider’s DNA is now in your computer.
Getting close! A quick review of all these repo copies you've interacted with:
- A remote upstream repository: the public version of SC on GitHub, which is where you eventually want your changes to be merged.
- A remote origin repository: the forked **copy of the upstream repo that you have in **your GitHub account.
- A local repository: the local copy of your origin repo, cloned onto your computer. This is where the work happens.
-
Note the Current Branch dropdown menu—it should say
develop.If it says anything else (e.g.main) use the dropdown menu to select and switch to thedevelopbranch.Remember: any time you want to make a new change to the SC source code, you’ll want to start from the
developbranch. Any changes you request to be merged into SuperCollider are submitted to the upstreamdevelopbranch for review. If accepted they get merged there, where they stay until a release manager merges all new changes fromdeveloptomainfor the next SC version release. -
You can now create your own new feature branch, to begin your work. From the menu bar, select Branch → New Branch…
- Give your branch a descriptive name.
Use the naming convention of
topic/brief-description-of-change. Using thetopic/prefix helps distinguish it from other types of branches created for other development work. - Click Create Branch.
Note: Creating your feature branch from
developmeans any new changes you make are built on top of all previous changes contained in thedevelopbranch, but your changes are unique to your new feature branch until they are later merged into, and become part of, thedevelopbranch.
You now have your first feature branch and you’re ready to start making changes!
Let’s go.
In this tutorial, we’re going to make changes to a documentation page. We won't alter the actual page we see in the Help system. Rather, we'll edit the source file that is used to generate the (HTML) page we see int he Help system.
To test the changes we won't need to build a new SuperCollider application. Instead, we just tell SuperCollider to look for the source files for its Help system in our new repo, instead of its usual internal help source directory.
-
Open SuperCollider…
-
Set the
helpSourceDirto point to the HelpSource directory in your new repo by running the following lines:~defaultHelpDir = SCDoc.helpSourceDir; // store the current (default) help dir SCDoc.helpSourceDir_("/Path/to/my/supercollider/HelpSource"); SCDoc.indexAllDocuments(clearCache: true); // force update from source file
-
The first line stores the default help source directory path to
~defaultHelpDir, in case we want to switch back to it later. -
Calling
SCDoc.indexAllDocuments(clearCache: true)updates the file path of the source files used to generate the HTML Help files. So that when we tell the Help files to reload, they’ll be rebuilt using the source files in the specified HelpSource directory (the ones we’ll be changing).
-
-
Open the Help Browser.
At the bottom of any SC documentation page, you will see a footer indicating the source file used to render that page. It should show a path to a file in your repository.
- If not, it may be the case that you already had the Help Browser open when running the above code, so the page hasn’t actually been re-rendered. To do this, click the Reload (circular blue arrows) at the top right of the Help Browser, next to the text search field.
This should refresh the page, with the proper source file shown in the footer. You’ll click this Reload button every time you save new changes to the document’s source file and want to render the results.
-
Note: if there were any problems opening the Help system after running the above code, it may be the path to the HelpSource directory was not correct. You can try resetting the source directory back to the default with
SCDoc.helpSourceDir_(~defaultHelpDir); SCDoc.indexAllDocuments(clearCache: true);
and Reload. If it’s still broken/stuck you can hard-reset back to the default Help system from the Menu with Language → Reboot Interpreter and try again.
Let’s edit a Help file!
-
Navigate to your new local supercollider/HelpSource/Classes subdirectory, and locate the file Buffer.schelp.
All of the SC class Help files live in the /Classes subdirectory, while other types of SC documentation files will be in their respective categorical subdirectories: /Guides, /Tutorials, /Overviews, /Reference, etc.
-
Open Buffer.schelp. It will open automatically in SuperCollider.
You can use any other text editor or IDE of your choice, but you’ll be viewing the rendered help file in the Help Browser, so it can be helpful to make basic edits using the SC IDE. Also, SC has basic syntax colorizing support for .schelp files, which make it a bit easier to read and edit.
-
Make some changes! In this example, we’ll update the
Buffer:*sendCollectionmethod example to use the recommended style for SuperCollider code.
A couple things stand out:
- the
actionfunction arguments to both*sendCollectionand-getmethods are mixing styles—one uses theargkeyword to specify the function argumentbuf, while the argumentmsgis specified using pipes. We want to use the correct style of pipes. - We’ll also want to add spaces inside any curly brackets, space after commas, and no need for semicolons if the statement is at the end of the function.
Search down the Buffer.schelp file to find where the changes need to be made:
method:: sendCollection
Stream a large collection into a buffer on the server using multiple setn messages. Returns a Buffer object.
...
discussion::
This allows for larger collections than setn, below. This is not as safe as link::#*loadCollection:: above, but will work with servers on remote machines. The sample rate of the buffer will be the sample rate of the server on which it is created.
code::
s.boot;
(
a = Array.fill(2000000,{ rrand(0.0,1.0) }); // a LARGE collection
b = Buffer.sendCollection(s, a, 1, 0, {arg buf; "finished".postln;});
)
b.get(1999999, {|msg| (msg == a[1999999]).postln});
b.free;
::After editing:
code::
s.boot;
(
a = Array.fill(2000000, { rrand(0.0,1.0) }); // a LARGE collection
b = Buffer.sendCollection(s, a, 1, 0, { |buf| "finished".postln });
)
b.get(1999999, { |msg| (msg == a[1999999]).postln });
b.free;
::After saving the change click the Reload icon in the top right of the Help Browser and see the change take effect. 💫
Soooooo much better! 🤩
- Note: you can view the original help file that you’re replacing by resetting the `SCDoc` source directory back to the one bundled with the SuperCollider app:
```supercollider
SCDoc.helpSourceDir_(~defaultHelpDir)
SCDoc.indexAllDocuments(clearCache: true)
```
-
Head back over to GitHub Desktop.
You’ll see the changes show up in the list of changed files on the left, and in the file difference (“diff”) display on the right.
-
Inspect the changes.
- Look closely at the diff to make sure all of your changes are there, and that you didn’t change anything you didn’t intend to. If you need to make any further changes, return to SC, make those changes, and, importantly, test the changes again.
Once your satisfied with your work, you’re ready to save them in your repo’s history by “committing” them.
You can see that this change is listed in the Changes tab (upper left), meaning the change is “staged” locally (saved on your local machine), but is not yet in your repo’s history. The changes need to be “committed” (saved) to the repo’s history.
Committing creates a kind of milestone in the history of your work (and in fact the history of the whole SuperCollider project), and serves two purposes:
- You can roll back to this milestone in the future, either temporarily or permanently. This is useful, for example, if you want to abandon new work that went in the wrong direction, or you want to retrace your work to find out where an unexpected bug was introduced.
- It allows yourself and others to look back over the history of the changes to comprehend at a glance what has been changed. (Especially useful if you return to this work far into the future.)
For these reasons, you’ll want to make commits in small “work units” which are fully functional, so that if you return to any point in the history everything still works (i.e. don’t commit non-working changes).
Give each commit a descriptive title and a description if necessary. We use a specific commit message format to help reviewers quickly assess the changes you’ve made. Namely: component: sub-component: short description of changes.
The commit message should be very concise. If you want to elaborate, provide rationale, references other Issues, Discussions, or Pull Requests, you can add that to the Description field.
Here’s what it looks like in this example: docs: Buffer: update style in sendCollection example:
Now click the Commit to topic/… button.
The diff disappears and you see the status “No local changes”. This means your code has all been saved into the repo’s history!
Click on the History tab in the upper left and you’ll now see the change you made at the top of the long list of all other changes in SuperCollider’s history (from the develop branch, from which you created your feature branch).
Notice there’s an arrow next to your commit, meaning that it doesn’t yet exist in your remote origin repo on GitHub.
To “push” (upload) it there, click Publish Branch in the top right.
This pushes your local feature branch, with the commit stored on it, to the origin repo on GitHub. ☁️
You can confirm this by going to you forked repo on GitHub. You’ll see a banner there indicating that you’ve updated the repo, and you’ll notice your commit message listed as the most recent commit:
Not done yet?
Let’s say that while you were making your changes to the help file, you noticed a couple other changes you’d like to make, which are related to the change you just made (this is important: all Pull Requests should have commits representing changes related only the the feature / topic being proposed).
In this case, say you noticed the example in the Buffer:*loadCollection method documentation also needed some style updates. Let’s fix those too…
- Make the changes to Buffer.schelp.
- Reload the Help Browser window (button on the top right).
- Test the example code that you changed to make sure it still works.
Head back over to GitHub Desktop. Your changes will show up again in the Changes tab.
Review the diff to confirm your changes are all intended and complete.
Add your commit message.
Click Commit.
In the History tab, you’ll now see your two commits listed. The most recent commit again has an arrow next to it indicating it needs to be pushed to your remote origin repo, which you can do by clicking Push origin at the top right (where it previously said Publish Branch).
Great! You can call your changes done and skip to Submitting your changes in a Pull Request.
Or … you can consider a couple more tips. Before you push your changes, perhaps you’re thinking that these changes are very similar and may not need to be considered separate changes, they could just be one change…
You can compress multiple changes into one, by squashing the commits (merging them into one). To do this, shift-click to select both commits in the History list, then right-click to select Squash 2 Commits…
You’ll then be presented with a dialog to update the new single commit message and description that will replace the previous two. It auto-populates with the most recent commit message by default, and any other messages from commits being squashed into the Description field. In our case, a single message without a Description will be enough:
You’ll be asked whether your sure you want to squash… it’s worth considering because you can’t undo this!
You’ll now this this single squashed commit in the history, with the arrow next to it indicating it hasn’t yet been pushed to your remote origin repo. Note that the Push origin button now says Force push origin. This is because your first commit was pushed to the remote repo, but now you’ve overwritten that commit in your local repo by squashing it with your second commit. This created a new commit that replaces both previous commits. As the name implies, force pushing it will force your remote repo to be in sync with your local repo by overwriting your first commit there with this new one (which contains both of your changes).
You can also Force push from the menu bar: Repository → Force push…
-
A note of caution about force pushing
CAUTION: In general, you only want to force push to your remote repo if you’re the only one making changes to your branch. If you were collaborating with someone else to make changes on a shared branch, they would be making updates to the remote repo as well. You would both periodically pull each others changes into your local copy to build on top of. This requires that you have an exact shared history. Because force pushing overwrites that shared history, your collaborator may have pulled your previous commits to build on, but you then overwrote them so you both have divergent histories!
Note: Because force push performs a rewriting operation to your changed files under the hood, you may be prompted by your IDE that the file you were editing has been changed externally. That’s ok. In the case of the SC IDE, just click “Reload” when prompted.
Just as you can select commits in the History list to squash them, GitHub Desktop lets you make other changes to your commit history. For example:
-
Undo the most recent commit. You can right-click the most recent commit to undo it. This reverses the operation of pushing the Commit button, effectively removing the change from the history list, but your changes and commit message will still be there, staged and ready to commit again after you make your update to it.
-
Amend the most recent commit. You can right-click the most recent commit to amend it. This leaves the code changes in the history, but allows you to modify the Message and Description attached to it.
-
Reorder commits. Drag commits around in your History list to reorder them. Be careful… if changes in a commit rely on previous commits, reordering them require you to manually resolve the differences between them which can get messy (you’ll learn this eventually 😉)
-
Checkout a previous commit. You can right-click any commit to check it out. Doing this rewinds the state of your repo to that point in history, removing all changes, any new files, etc. that were added after that commit. This change is actually happening to the files on your computer. But don’t worry, the history that follows that commit is still intact and can be replayed you bring you back up to the most recent commit.
- Note: After checking out a past commit, the GitHub interface may look confusing—it appears commits after the one you checked out have disappeared. But notice that the Branch dropdown menu indicates that you’re in a Detached HEAD state. This just means you’re floating in the history of your repo, and reminds you not to be making any changes to files while your in this state (the proper way to make changes at some point in the history is to create a new branch for that).
To return to the state of the most up-to-date commit on your branch, just select your branch from the Branch dropdown menu (the one that currently says Detached HEAD).
You’ll be submitting your feature branch changes to be added to the upstream develop branch. This means they need to have a shared history in order for your changes to be added onto the “tail end” of the upstream repo’s history. If some time has passed while making your changes (it’s not uncommon for changes to take days, weeks, months…), you’ll want to update your local repo and feature branch to be sure it includes any changes that have been made upstream to the develop branch while you’ve been working on your feature branch.
GitHub Desktop makes this easy with one step:
- Menu → Branch → Update from upstream/develop
-
More background
This is performing an operation under the hood called *rebasing,* in which any new upstream commits are *pulled* from *upstream/develop*, and your branch changes are “replayed” again from the up-to-date `develop` branch (the new “base” to your branch is the updated last commit in the `develop` branch). GitHub Desktop can do this in one step because it knows your branch is based on the `develop` branch. Note: this doesn’t affect your *local* `develop` branch, so if you wanted to update that branch with the latest upstream changes, you would just switch to (checkout) that branch and pull from *upstream* `develop`.As long as there have been no upstream changes to the same parts of files you’ve changed, this should resolve without issues. Otherwise, you may encounter a “merge conflict”, in which case you’ll need to resolve how these differences will be merged together in a code editor. (We won’t cover that here.)
Now you’re ready to submit your Pull Request.
You’ll be submitting your feature branch changes to be added to the public upstream develop branch. GitHub Desktop knows this so it will automatically take you to GitHub to do this when you select Branch → Create Pull Request
You can also create a Pull Request from the GitHub page of your supercollider fork by viewing your feature branch, and a banner will show at the top of the page giving you the option to create a Pull Request.
On GitHub, the Pull Request is initiated with the PR template:
First, confirm some details:
- The proper branches are being merged:
your feature branch
topic/docs-buffer-example-style-updatefrom youryourname/supercolliderorigin repo , into the upstreamsupercollider/supercolliderrepo,base:developbranch. - The status reads: ✓ Able to merge. If not, you may need to go back and rebase your feature branch.
- Add a title. The default title is your most recent commit message, but update it to be a complete, concise phrase of what your change is.
- Fill out all of the Description template. It’s important not to skip any fields.
- Provide as much detail as possible as to why your changes are needed and why you chose this particular solution/implementation.
- If the work is ready to be reviewed by others, all check boxes should be filled with an ‘x’ in the To-do list.
- If you check the Ready for review box, it’s important that the work is ready to be discussed towards a merge.
- Don’t check this box if you still plan on pushing new work to this branch (this updates the PR automatically). For example, you may be pushing your work here for discussion with a working group, for curious onlookers, or if you have specific implementation questions you’d like to discuss with others.
Submit your PR, you're done for now!
Reviewers look at Pull Requests on a regular basis, and sometimes in a public meeting in the case of larger PRs. The meeting times are announced on the scsynth forum and on Slack.
You can expect feedback and requests for changes, even for seemingly minor changes. There are community members with years of experience across the SC code base and user experience, they may offer perspective you hadn’t considered while making changes in the context of your situation.
Even documentation changes may receive requests for grammar, punctuation, rewording, or content and structural revisions. This due diligence really helps the overall quality and consistency of the project. Please remain open and responsive, the goal of everyone involved is to have your ideas and feedback integrated into SC.
Changes should to be made in a timely manner. Momentum is important for seeing the process through, and it’s important to respect everyone’s time, effort and attention. Pull requests may be closed if they aren't showing any activity.
Be aware that reviews can be backlogged for long periods of time, Reviewer activity can ebb and flow throughout the year. This is just a reality of the constrained resources of this volunteer-based project, and doesn’t reflect the perceived importance of your contribution.
Once you're comfortable with the process of branching, making changes and submitting PRs, you may want to eventually start making changes to SuperCollider class files or backend C++ code. For that, you'll need to learn a few more important processes, such as the style guidelines for SuperCollider, how to build the SuperCollider app (for Mac, Windows and Linux), how to lint and format C++ code, and other aspects of contributing to SuperCollider. But the underlying process of planning features, making changes, committing them in an orderly way, and submitting PRs is exactly the same.
More resources and links on that TBD...
How your changes move through develop to an eventual release.
You may find it useful to know what Reviewer Instructions are advised for reviewers.
It’s appreciated if you consider making reviews yourself to give back to contribute to the forward movement of the project! It’s ok to start small by first just contributing to discussions about open PRs and Issues, and eventually start reviewing “easier” changes, like documentation fixes.
More info here TBD…