Assignment 8: Software Engineering Toolkits (Make and git)

Assigned: 11/21
Due: 11/30 at 11:59 p.m.

This assignment include two parts on software engineering toolkits:

Part 1: Makefiles & the Make utility

Part 2: Basic Version Control with git

 

Part 1: Makefiles & the Make utility

Libraries You May Use

Description

The purpose of this assignment is simple: practice writing Makefiles for a given project. A good compilation system (e.g., Make) will make your lives easier while working on your own projects, and makes the use of your software easier for the end user. I have provided you with the source code for a simple linked list class: linkedlist.zip. Your assignment will be to write and turn in a working makefile for the class.

Assignment Specifications

At minimum your makefile should include:

What you must turn in.

Electronically a single zip file, with the name LASTNAME_FIRSTNAME.zip. Your zip file should extract into a directory with the same name as the zip (please make sure to put your files in a separate directory before submission). Your zip should include all files necessary to compile and run your program including:


Note: Your program must compile and run on CS1 (or a UD lab machine) or it will not be graded. Please see the syllabus for details.

 

Part 2: Basic Version Control with git

Libraries You May Use

Description

When doing your projects, you may create a directory in each of your project directories called (something like) backup, so that whenever you have your work at a stable point you can cache a copy in backup by just saying cp * backup. (If you have not been doing so, the cp will copy everything * from the current directory into a contained directory called backup). This strategy works in a pinch (and has saved your professor's bacon on a number of occasions when a bad rm command was issued), however its simplicity can be a weakness in practice.

In practice, a version control system (VCS) is typically the preferred route for the world of software engineering/computer science. Version control software packages are used to track and manage changes to documents, programs, web pages, and just about any other (typically text based) systems that are under active development. The git software package was also developed by Linus Torvalds (of Linux fame), and among other things (e.g., the primary purpose was for Linux kernel development) has become a relatively popular version control system in the real world of software engineering. (Other options exist, however for the purposes of this course we will be focusing on just the one package.)

Advantages of using version control include:

Getting signed up with github.

  1. First, go to github.com and sign up for an account using your university email address.
  2. After you have signed up for your github account, go to your profile (in the upper-right corner of the webpage there should be a dropdown with your github identicon. You will have the ability to upload your own image, but unless you feel like it github will generate a 5x5 "pixel sprite" automatically from your user id. Mine looks like . At any time you should always be able to navigate back to your profile in this way.
  3. In your profile, select the tab. A repository (or repo) is essentially a VCS database where all of your project information is stored remotely.
  4. At the start this tab should read that you don't currently have any public repositories. Click the icon to create a new repo.
  5. On the new repository page use the following information to initialize your repository:
  6. Click to create your online repository.
  7. You may want to save the resulting page for a moment (print, screencap, etc.) so you can refer back to it. If you lose track it will not be a big deal, however I often use the links and commands they provide so that I can quickly copy-paste when I create a new repo.
  8. Next, we will be creating a project locally and linking it to your repo.

Creating your project.

  1. We will start by initializing git in your account. Git will store most of your information in a file called .gitconfig, so you can always view or edit it later. Issue the following commands, with your information substituted in the appropriate locations (in bold below). These will configure your git setup in your account.

    The above commands will configure your name, email address (use your university email again for consistency), and your preferred editor. If you mistype something don't worry, you should be able to issue them again if necessary.

  2. You can now view the contents of your .gitconfig with either cat .gitconfig (from your home directory) or git config --list (go ahead and try both).
  3. Go to your CSCI 325 directory where you would normally create a software engineering tools assignment (wherever that happens to be--it doesn't matter where you do the following). Create a directory for this project called git_test, and change into that directory.
  4. Initialize your git repo in the local directory with git init. After a brief pause it should confirm that it has created a git repo in that directory.
  5. In order to connect the repo in your local directory to the cloud version hosted on github.com, issue the command:

    where the user name you selected (you can see it in your git account and in the url bar) is substituted for your_user_name. Note that you should find the full command with the correct user name and repo name on the page you saved in the previous steps. If this works you should see a brief pause, and then return to a command line (otherwise it is likely that you mistyped something).

  6. Using Emacs create a new file called README.md. The .md stands for markdown--like a regular README you can use plain text, however github allows you to use special syntax for when it is rendered in a web browser. In the README.md file put a few sentences specifying that you plan to use the repo for practice with git. The wording is up to you. Normally here you would describe the purpose of your project. Afterward, save and close out the README.md.
  7. You can view the status of your git repo at any time by typing git status (try it now). You should see that README.md is under a heading of Untracked files: (as is the Emacs backup). Untracked files are files that you have created locally, but have not pushed to github.com. You should also see a note like nothing added to commit but untracked files present. This means that nothing is ready to push to github.com, either.
  8. Issue the command git add README.md, followed by git commit -m "First commit: adding project README.". A commit is an entry stored in the version control system, and you (as the programmer get to decide exactly when and how this happens). You can commit as many files as you need to save the current snapshot of your progress, and you can do this whenever you want. However you first need to add the files that you wish to commit. A typical workflow includes frequently adding files and immediately committing whenever you wish to save your progress. The -m specifies a message that explains the purpose of each commit. E.g., the reason may be documentation, adding a new file, fixing a bug, adding a feature, etc. These are recorded online and locally so you can easily browse your history.
  9. You should get a message after the commit indicating that the commit was inserted locally. You can perform as many add/commits as you need, however these only save changes locally. If you do a git status you should see that the README.md is no longer listed as "Untracked". (Don't do anything with the Emacs backup--there is no reason to add it to a commit and we will take care of its clutter on your status screen later.)
  10. To push your current commits to github.com, use the command git push -u origin master. This tells git on your local system to record all of your changes in your online repo. You will probably be prompted to log into github.com on the command line. Use the user name and password that you selected earlier for your account. This should not be required in the future, but protects your repo from someone pretending to be you.
  11. Refresh your webpage for your "Git-Test" repo. You should now see that your README.md file has been uploaded, and is being used to describe your project for the world! Along with having the README.md immediately rendered on the front page of the repo, you should now also see it listed in the file list with the appropriate commit message.

Writing/pushing code, ignoring files.

  1. We'll start with a simple, single-file project. The workflow we have already described easily extends to multiple file projects. Create a new file in your project directory called main.cpp and a corresponding Makefile. Make your main.cpp a simple "Hello World!", and use your Makefile to compile and test your program. In your Makefile make sure to compile to a .o first, then to the executable main.
  2. Check your status. At this point you should see all of the files that you created (Makefile, main, main.cpp, main.o).
  3. Add the main.cpp and its corresponding Makefile to the next commit, commit your work, and push it to github.com. Use a commit message that describes what you are doing (something to describe that you are adding the first files of the project).
  4. At this point you should be able to refresh your project page on github.com and see the files that you uploaded with the appropriate commit messages. Many source files have automatic syntax highlighting on the web (check your main.cpp).
  5. If you check your status again, you should note that you may be starting to accumulate files that you probably don't want in your online repo, but also don't want to continue seeing when you check your status (object files, binaries, Emacs backups, etc.). We can tell git to selectively ignore certain files for this project.
  6. Use Emacs to open and edit a new file: .gitignore. The file does exactly what its name implies: it specifies files or patterns in file names to ignore. I would recommend adding the following entries for now (one per line):
    	    # Ignore any binaries and Emacs backups.
    	    main
    	    *.o
    	    *~
    	  

    The above patterns specify for git to ignore changes made to your executable, main, all .o files, and all Emacs backups (any ~ file).

  7. At this point your status should be nearly clean (except for the new .gitignore. You could specify for .gitignore to ignore itself, however a better solution is to add/commit/push the file so it is a part of your repo. (Please go ahead and add it to your repo.) Once you do so your status should be clean.

Tracking your progress: Diffs and commits.

  1. Edit your main.cpp to ask the user for a number, n. Write a method called sum that takes the integer as a parameter, sums the numbers from 1 to n, and returns the sum. Have your main call the function, and print its value. Compile and test your program to make sure it works. Don't commit or push your changes yet.
  2. Issue the command git diff main.cpp. Diff is a Unix command that shows the differences between two files. You could call it on the command line with two files using the syntax diff file1 file2. By default, the git version automatically compares the file in your current directory with the file on your remote repo. The top of the file identifies which files are being fed into diff (both are main.cpp). You should see lines from your old file that are removed prefaced with one symbol (probably the -, lines that just occur in your new file prefaced with a +, and lines that occur in both prefaced with nothing. If terminal colors are enabled you should also see the different files highlighted in a certain color to make them stand out. You can move up and down with the arrows, and quit with q. Diff is a handy tool to recall what you have done (among other things) since your last commit.
  3. Add, commmit, and push your new main.cpp
  4. On your github.com page, click the icon. The icon will identify the number of commits in the repo (mine shows 4).
  5. Note the hash value of your most recent commit:

    For example, my most recent commit has a value of 7006bc4. Each commit is uniquely identified in the system.

  6. Click on the commit message to see what has changed since the last commit. Note that this should look much like the command-line diff in a previous step. You can click the button to see the files side-by-side. Take a screenshot of the screen showing the commit in mode. Put it in your project in a directory called screenshots, and give it the same name as the commit (you noted this in your previous step). Mine is 7006bc4.png.
  7. Your status should now show that everything in the screenshots directory is untracked. Go into the directory and add/commit/push the screenshot. When you refresh the project repo page you should see that the directory was added automatically with the screenshot (typically you can just focus on non-directory files when you work).

Creating and merging branches.

  1. Have you ever found yourself creating multiple files (main.cpp, main.old.cpp) to save your old work in case you introduce new (and problematic) errors while you are trying to add a new feature or fix a bug? (I've found myself having to resort to this in a pinch.)
  2. By default your project has a single "branch" called master (as in origin master. You can create an arbitrary number of "branches" from any point in your commit chain in order to add a new feature.
  3. Create a new branch by clicking the icon, and type feature in the box. Normally you would create a more descriptive name for the feature you were working on. At this point you can use the drop-down to view both branches, however the files and their contents should be identical.
  4. On the local machine, switch to the feature branch, with git checkout -b feature. Note that if you have work that was not committed you may overwrite your work by doing this. (In other words, make sure your work is committed before switching branches. If your syntax is correct, the application should respond saying that you switched to feature. Note now that you can move between branches, make updates, and commit them to the respective branch so you can develop multiple ideas (or among multiple collaborators) in parallel. Your status should also reflect your branch.
  5. Add a new feature to your main.cpp: along with the sum function, write a product function that computes the product from 1 to n. Modify your main to call product and report the answer as well as the sum. Try to do so by only adding lines (for simplicity). Compile, test, then add/commit the change. Since you have switched to feature, the commit should report that it has committed to the feature branch. For me it reported the following:

    [feature 35dcfb0] Added product function.
    1 file changed, 12 insertions(+), 1 deletion(-)

    The syntax for the add/commit should not have changed (note we never specified the specific branch during an add or commit.

  6. Next push your code to the correct branch: git push -u origin feature. Before you move on, use the branch button on your repo to view the code for main.cpp in both master and feature. You should see the new commit only in feature, and master should remain unchanged.
  7. Now that we have implemented the feature to our liking we merge the changes back into our master branch. This can be accomplished on the command line, but for the purposes of this project we will use github.com to accomplish the merge (the interface is a little simpler). (You can have arbitrarily many branches open to eventually merge back into the master branch).
  8. Go to github.com and use the branch button to switch back to master. Normally someone would be in charge of a repo, and we would issue a pull request to that person. Click the button to issue a pull request (we will handle it on behalf of our own repo). You should be able to select the feature branch on the resulting page:

  9. The next page shows a diff of the two so you can visually compare and confirm that the files you wish to merge are correct. If you agree to the merge, click the button. (For a merge this simple github.com may indicate that the branches can be merged automatically by the system.)
  10. On the "Open a pull request" page you will see a commit message (automatically populated by the commit message) and comment section where you can discuss the changes with the person in charge of the repo (put whatever you want here, it is just for us). Click the final "Create pull request" button.
  11. Since we have permissions to both create pull requests and manage them, the resulting page will have a button to . We may have some decisions to make for complicated merges (where conflicts may exist) but here we have only added some simple code, and the system should still indicate that it can merge automatically. Click the button, then again on the confirmation button. You should see that the pull request was successfully merged and closed.
  12. Before exiting the page (and once we have confirmed the merge has occurred successfully) you can click the button to close the branch out. (We can always create new branches for additional features or ideas.)
  13. If you go back to your area, you should be able to confirm by the comment and content of your main.cpp that the code has been merged correctly.
  14. On your local machine (back to the terminal) you should still see the old version of things, and you are probably still in your (now defunct) feature branch. Changes will only show up on the local machine when you tell them to. Switch back to the master with git checkout master (no -b this time). Update your changes from the online repo with git pull. You should see a message indicating that the system is downloading the new version of the repo. Finally, if you view the main.cpp and check your status you should be able to visually compare to see that you have the correct version of main.cpp. (You may want to recompile to generate new binary files since they are untracked, and hence unchanged by git.)
  15. Congratulations! You are now ready to start using version control like a professional! We will be starting with a version controlled (through git) version of your next programming assignment.

Adding a collaborator.

  1. For this assignment you will not submit using email, you will simply add me csci325 to the project.
  2. On your project page click then . In the search box, you can select me by user name. Click to "Add collaborator", and you are done.
  3. In a real-world project you may have a number of collaborators, including your partner for this course.

What you must turn in.

Nothing. Once you have added me as a collaborator I will be able to view your project, your commit history, and anything else that I need.


Note: Your program must compile and run on CS1 (or a UD lab machine) or it will not be graded. Please see the syllabus for details.