User:Lexinatrix/Sandbox/Blacksmiths

Ways to Help
Blacksmiths are vital to the success of Habitica. Your contributions are needed and appreciated! There are several ways to contribute coding expertise to the website and mobile apps. A great first step in getting acquainted with what needs to be done is joining the the Aspiring Coders guild to discuss programming for the site, learn some tips, and get ideas for what to work on.

Mobile App for iOS
The iOS "Habitica" app has its own code base in its own GitHub repository at github.com/HabitRPG/habitrpg-ios. It is open source and contributions are welcome.

The old iOS "HabitRPG" app is no longer under development and contributions will not be accepted.

Mobile App for Android
The Android "Habitica" app has its own code base in its own GitHub repository at github.com/HabitRPG/habitrpg-android. It is open source and contributions are welcome.

The old Android "HabitRPG" app is no longer under development and contributions will not be accepted.

How Can I Help?

 * I want to help with the Android or iOS mobile apps: email mobile@habitica.com to talk to our main mobile devs about the kind of work you'd like to do.
 * I want to start small: hit the issue queue, take something that looks simple enough (probably the priority - minor, priority - medium, and entry level coding (text etc.) tickets
 * I'm ready to dive in, and I want to help where I'm most needed: priority - critical and priority - important on the issue queue

Once you see an issue you would like to work on, check the conversation to see if somebody is already working on it, or to see if a pull request is linked (which means someone has already submitted a fix). If you are not sure, post a comment on the issue to either ask about the current status or express your interest in fixing the issue.
 * Unit tests & Karma tests!: Oh please, oh please, oh please! We love you and need you.
 * I can finish what someone else started: There are many issues that someone has started and then abandoned for a while due to overwork in other areas. If you see a likely issue with no recent comments, it might be available. You're welcome to post in the issue to ask if it's still being worked on.
 * Forget that, I want to build things!: Make way for the new hero! Check out the Trello feature queue. Ask first to find out if the feature request is approved by the staff.

Join

Setting up Habitica Locally

 * Main article: Setting up Habitica Locally

Blacksmiths should create a local running instance of Habitica, for testing and development. The process to create a local instance can be difficult, so we've collected helpful notes and tips by operating system.

BountySource
Users may now post bounties for Habitica bug fixes and feature requests on BountySource.

Technologies discussion
Why do we use Jade and Stylus?

Jade: We need a server-side templating language so we can inject variables (`res.locals` from Express). Jade is great because the "significant whitespace" paradigm protects you from HTML errors such as missing or mismatched close tags.

Stylus: Vanilla CSS wasn't cutting it for our app.

Before reading this page, first read:
 * Contributing to Habitica (from the "Coders (Web & Mobile)" section onwards)
 * Setting up Habitica Locally

Technology Stack
The technologies that Habitica uses for its website are listed below. You don't need to be familiar with all of them, or even most of them, to be able to contribute! Some links to high-quality learning material are included.
 * Server:
 * ExpressJS
 * Node.js
 * How do I get started with Node.js
 * nodeschool - included in the SO article linked above, but a particularly awesome entry level interactive node curriculum
 * MongoDB
 * MongooseJS
 * Bower
 * Gulp
 * Client:
 * AngularJS
 * Shaping up with Angular.js - A video tutorial with exercises. You'll probably find that the videos alone are enough to help you understand Habitica's AngularJS code, although of course completing the exercises too would be more beneficial.
 * Learn Angular - Free interactive lessons.
 * Bootstrap
 * Jade
 * Stylus
 * Testing:
 * Karma
 * Mocha
 * Jasmine (used only for an end-to-end test for the static home page working)
 * Selenium (used only for an end-to-end test for the static home page working)
 * Services:
 * New Relic
 * Heroku
 * AWS
 * Amplitude
 * Other:
 * iOS
 * Android
 * git and GitHub
 * Pro Git - An excellent resource. You will be much more comfortable with git if you take the time to read this.
 * git-it - scroll down to see more info. This is part of the nodeschool curriculum and is a fun and interactive way to learn git and github.

Tips for Working with a Local Installation
After you've followed the instructions on the Setting up Habitica Locally page, these are a couple useful tips to using your installation.

Quick Server Restart
After you've started the server (i.e., run ), the end of the console's output should look something like Running "nodemon:dev" (nodemon) task [nodemon] v1.2.1 [nodemon] to restart at any time, enter `rs` [nodemon] watching: *.* [nodemon] starting `node ./website/src/server.js` info: Express server listening on port 3000 info: Connected with Mongoose The lines about  mean that after you make any change to the code that you'd like to test, you can simply type rs and then hit enter to restart the server. This is much faster than exiting and running  again.

The Debug Menu
The following menu is in the footer of every page of your local installation, and can be used to quickly cause certain actions to happen, making testing your code easier.



Git
Here is a small tutorial to explain how to fork habitrpg, create new feature branches, and perform pull requests:

Fork & Clone Habitica
The easiest way is to go on the habitrpg github page and click the Fork button. Then do a git clone of your own repository.

Another way is to   git directly, then (and note you need to change "YourUsername" with your actual github.com username) cd habitrpg git Finally, git push to update your fork.

Setup Upstream Remote
Next step is to keep track of the upstream habitrpg repository, so we can easily update our fork with the latest changes. Because origin is the url to our fork, we will create another remote upstream for habitrpg: Then, every time you want to get habitrpg's latest code, you can do: git fetch upstream

Rebase Branch
When you want to update your local branch, you need to rebase it from the upstream branch. Let's update develop: git checkout develop git fetch upstream git rebase upstream/develop git push # to update your fork If you get the error "fatal: 'upstream' does not appear to be a git repository", then follow the instructions in the Setup Upstream Remote section above.

After updating, there may be new node packages in the project so run this again: sudo npm install

Create a New Feature
Now, you want to start a new task, and pull request it. First, you need to find which branch to start the feature from. Do a  to see the list of remote branches. Choose the appropriate branch depending on the task you want to work on. This will almost always be the develop branch.

Let's say you decide to start your task from the develop branch. To create your feature, do: git checkout -b relevant_branch_name upstream/develop Then you can make your changes, use  to push it to your fork in GitHub, and then do a pull request from there.

Assist Another user with a Feature
To work on a feature that was started by someone else, and not yet merged in upstream, you can pull their commits to your local install.

Let's say the user 'jdoe' wrote a feature branch 'add_theme' which is awaiting a pull request into upstream/develop. You also have your fork of upstream/develop, and would like to get jdoe's changes right now. git fetch upstream git checkout -b jdoe-add_theme upstream/develop git pull https://github.com/jdoe/habitrpg.git add_theme

Write Commits
When developing code, It is recommend that you do regular small commits, which are easier to review than a big one. It's also easier for developers to refuse or edit one specific commit that needs changes.

For example, you could have a commit dedicated to tests, followed by one with UI changes, and one (or more!) to write the logic.

If your changes are done in several days, make sure you rebase your branch to properly update your code. If some conflicts appear, you might want to use the upstream version: git rebase -Xours upstream/develop

Keeping your Commits Clean
It is important that the commits you make include only files that are suitable for inclusion in Habitica's official repository. If you add any files that are purely for your own use, do not allow them to be included with a `git add` command. Also do not specify them in the repository's  file because changes to that file will be included in the official repository. You can use your global  file for personal files.

Testing your Changes
Before submitting your changes in a pull request, run the tests locally to see if anything is no longer working correctly. If you can't work out why a test is failing, ask for help because it might not be caused by your changes.

Running tests is not necessary before a pull request for partially completed work (e.g., if you are seeking assistance before finishing your changes).

Pull Request
When you've finished your code, or half-finished it but would like feedback or assistance, push your branch code into your fork with

Then go to https://github.com/YourUsername/habitrpg.git and click on the Pull Request (PR) button. Before saving the PR:
 * Verify that the merge will be done in the correct branch. It often defaults to upstream/develop even if you created your branch from another one, so change that if necessary (although most requests will be made into the upstream/develop branch).
 * Type a meaningful name for the PR that succinctly but accurately describes the change.
 * Add  at the end of the name, where 1234 is the number of the issue that is being fixed (not necessary if your PR is not fixing an issue).
 * Describe your change in as much detail as necessary in the body of the PR. Please do not expect Habitica's staff and admins to work out what your PR does by just reading your code. A written description gives them the context necessary to understand your code more rapidly.
 * If your PR changes any user-visible parts of Habitica, include screenshots that show the new behaviour (and also the old behaviour if that will be of assistance in understanding why the change is important).
 * Include your User ID (from Settings > API).
 * Admins receive emails for all new PRs and all new comments added to PRs but they are not emailed when any comment in the PR is edited. To ensure that everything you write is seen by admins, it is best to always make new comments instead of editing old ones. If there's a reason to edit an existing comment, you're welcome to do so but please also create a new comment containing the new or changed material (you can delete the new comment after you've made it if you wish, since the only purpose of it is to get the new material into the email stream). The same applies to Issues.
 * Admins also don't receive emails when new commits are added to an existing PR, so add a brief comment when you've pushed a new commit.

Problems
You tried to do a rebase and now you have many new and irrelevant commits in your branch.

No worries, there are several solutions to get out of that mess:

Cherry-pick
One solution is to keep a  window open, with all your commit hash IDs (the long string of letters and numbers) visible in a list.

You can now perform  (if there is only one commit to remove, otherwise HEAD~nb_of_commits). If you delete too many commits, just  again from your fork. Then, copy the commit hash of the commits you want to re-add on top of your branch (from the git log window you left open before doing a reset). For example, git cherry-pick ee1768b7e2c0bcee9eff1a45be1e3543fac0687b This will re-add commit ee1768b7e2c0bcee9eff1a45be1e3543fac0687b on top of HEAD.

Stash
if your attempt to push failed because remote has a different HEAD than your local repo (this happens to people working together on the same branch and pushing on the same remote), don't pull! Instead, do   git reset --soft HEAD~n_local_commits_ahead git stash git pull git stash pop git commit -am "message"

Work with habitrpg-shared
NOTE!  habitrpg-shared has been deprecated. The habitrpg-shared files have been moved to the /common subdirectory under habitrpg, and all actions you used to do in habitrpg-shared can be done there. If you see any instructions telling you to take actions in habitrpg-shared, please report them in the Aspiring Coders guild and ask for clarification if you need it.

MongoDB
Quick tips for new developers to get the hang of using the database.

In the commands below, the $ sign indicates a Unix or Windows or Git Shell prompt and the > sign indicates a mongo shell prompt. Type only the text that appears after $ or >

Access a shell
Start the mongo shell then select the database: $ mongo > show dbs > use habitrpg Alternatively, directly start the shell with the correct database: $ mongo habitrpg

Use the shell
View the "collections" in the database ("users", "groups", etc): > show collections

Find your test user and examine its data. From localhost settings, copy the User ID, then run this command: > db.users.find({_id: '85b007a2-b5b9-4bb4-8b82-e4567edb4919'})[0] Want to see the preferences only? > db.users.find({_id: '85b007a2...'})[0].preferences

To update something for your user, use the update method with $set. For example, edit your profile blurb: > db.users.update({_id: '85b007a2...'}, {$set: {'profile.blurb':'test'}}) Give yourself 10 gems (can also be done from the Debug menu in the lower right of the footer): > db.users.update({_id: '85b007a2...'}, {$set: {'balance':10}}) Get admin rights (you will then see extra options in the Hall): > db.users.update({_id: '85b007a2...'}, {$set: {'contributor': {'admin':1}}})

Assign yourself unpurchasable quest scrolls (e.g., for limited edition quests): > db.users.update({_id: '85b007a2...'}, {$set: {'items.quests': {"egg":2,"dilatory":1,"stressbeast":1,"basilist":1,"evilsanta":1,"evilsanta2":1}}}) This gives the user two Egg Hunt scrolls ('egg') and one scroll each for another five quests. Please note that this will clear all other quest scrolls that the user possesses, but as others can be added in the same way (respective keys can be found in the content.coffee) or can be purchased later from the market.

Creating a Local User Account Identical to your Production Site Account
Export your user data using the GET /user API route, and import it locally using MongoDB commands such as. This can be a fast way to create a local account pre-populated with tasks, equipment, etc.

Your account will need to be inserted into the  collection, but this collection won't exist in mongo until an account is created in your local install. This can be done simply by starting your local install and creating a test account, and then inserting your production account.

The API does not export some authentication information for security reasons, so you will need to set it after inserting your user data. This sets the password to "test" and creates an API token: > db.users.update({'auth.local.username': 'your-username'}, {$set: {'auth.local.salt': '7eff6ff32a', 'auth.local.hashed_password': '5b5d5f748091e62aadf2f109f4a7379d2d8653dc', 'apiToken': '48ed9d70-0adf-431d-a001-1cb12d57590e'}}); Do not use the same API token or password that are used for your production site account! If you ever need to seek support for your local install or report information from it, you might include the full authentication data, and if it were the same as for your production account, the security of your production account would be compromised. The token used in the example above was randomly generated and is safe to use in your local install.

Migrations
Some Habitica website changes require existing user accounts to be modified (e.g., to assign a default value for a new setting to all users). Such database changes are done with a migration script, which contains JavaScript that connects to the database and makes modifications. All migration scripts are in migrations/. Read them and use them as examples to write your own script. The more recently edited scripts are likely to contain better, more up-to-date code than the older scripts.

To test a migration script: $ mongo habitrpg migrations/name_of_script.js

Data Binding, and Template Conditionals:
When working in the Jade templates, you may see element attributes such as ng-class, ng-show, or ng-if. These are bindings that are used to map model data to elements for display that are part of AngularJS. These bindings can be used to define styles or display based on conditionals.

You may also notice some other attributes such as bo-class or bo-if.... so what's the difference?

Bindings that begin with "ng" are part of Angular and are completely dynamic. This means that every time something changes with the app, Angular will test all of these bindings with conditionals again and take action again. Obviously this is a concern for performance.

Sometimes the data used to calculate these conditionals will not change often, if ever. When that is the case, we have an option for static binding, using a library called Bindonce. These are similar bindings, but they only are checked at the initial load of the application. If possible, this should be the preferred method of binding as long as the data will not change.

Bindonce directives should only be used if the following rule is true: the model data being used for the conditional will not change during a session, or will change infrequently enough that it's not unreasonable to expect the user to refresh the page. If not, stick with traditional binding. If you can't decide or have no idea what you just read, just use the ng-&lt;whatever&gt; attributes.

Adding Translatable Strings
If you need to add a new translatable string in some template, it must be written in the jade file as follow: env.t("stringLabel") Then, in the  directory, edit the json files, adding the new string as follow: 'lastLabel': 'Add a comma at the end of this line', 'stringLabel': 'String Title' } Do not update files in other directories under ; translations are managed in Transifex.

To test the string:
 * stop npm if it is running (Ctrl-C)
 * run  

Modifying Translatable Strings
Translatable strings appear in files in the  directory. Each string consists of a key and a piece of text, for example: 'clearAll': 'clear all items', If you need to change the text of a translatable string, do not also change the key unless there is a very good reason to do so. For example, if you needed to change 'clear all items' to 'delete all items', you would not also change 'clearAll' to 'deleteAll'.

This is because the key ('clearAll') can be used in many places throughout Habitica's code, and so changing the key would require you to also make otherwise unnecessary changes to the code.

In addition, the keys that are used in the English translatable strings are also used throughout all the other languages directories under. When a piece of English text is changed without the key being changed, the other languages will keep using the existing translations for the original English text until the translators have had time to update the translations. Usually this is what you want because the existing translations are usually still good enough to be used. However if you were to change the key as well as the text, all the existing translations would no longer be used because the language files do not contain the new key. This would mean that people using languages other than English would see the new English text until the translators had time to provide strings for the new key.

Tests
Habitica has a suite of tests that can be run manually and automatically to help us avoid bugs. When Habitica's admins deploy a new version of the website to production, the deployment process runs the tests and refuses to deploy the site if there are any failed tests.

Before you make a pull request, it is recommended that you run all existing tests to ensure that your changes have not introduced any errors.

If you are unable to run the tests, make a pull request anyway. Travis CI is used to run all the tests for every pull request. If any tests fail, Travis will report that in your pull request and will give a link that you can use to view the test output. If the failed tests are caused by your code, it will be necessary to change the code before the pull request can be merged.

Sometimes tests will fail for reasons not connected with new code, so if you can't work out why the tests are failing, you can ask about the failing tests in your pull request.

Most new code should have tests written for it before it will be merged into the code base, however Habitica admins will help you write such tests, and might be able to write them for you if you aren't able to if they have time available. Do not be afraid to submit a pull request without tests, especially if you are not sure what is involved in the testing process, but please be aware that your submission might not be accepted until you or the admins have created the tests.

Before running one test or the entire test suite on your local install, follow these steps: To run the entire test suite locally: To run a single test: To run all tests in one subdirectory: For more information about the API tests, see So you want to write API integration tests?
 * 1) Install gulp if it is not already installed, using  . If you are not sure whether gulp is installed, it is safe to run that command.
 * 2) Ensure that mongod is running.
 * 3) Stop any npm process such as   or any process that is already running the tests. Don't try to run two test processes at the same time.
 * 4) Run  . This step is not always necessary, but if you have recently run tests and try to run them again, you might see errors such as   and  ; killing all node processes will prevent those errors.
 * 5) Change directory into the top-level directory of your local install.
 * 1) Run   (this is an alias for , which prepares the test environment and runs all the test suites).
 * 1) Run  in one terminal session.
 * 2) Wait for it to get to  and then leave it running.
 * 3) In another terminal session, run
 * 1) Run  in one terminal session.
 * 2) Wait for it to get to  and then leave it running.
 * 3) In another terminal session, run

Tests in Vagrant
If you are running the tests in vagrant, you might see the following error: Error: /vagrant/.eslintrc: Configuration for rule "func-style" is invalid: Value "2,declaration,[object Object]" has more items than allowed. or many instances of these: 1:1 error  Definition for rule 'no-empty-pattern' was not found    no-empty-pattern 1:1 error  Definition for rule 'no-arrow-condition' was not found  no-arrow-condition You might also find that this test starts but never completes: Starting 'test:e2e:safe'... A proper fix for these problems will be documented here soon, but as a short-term fix, you can avoid those problems by editing two files in the top-level directory of your local install.
 * Edit  to comment out these lines:

Do not commit those changes because those lines are needed for running tests on the server.
 * Edit  to comment out this line:

Images
For information about creating new images for Habitica, see Guidance for Artisans.

When a new image has been prepared and has been approved by the staff, an issue will be created to request that it be added to Habitica. A Blacksmith will then need to add it to the repository. Most images will need to be copied into suitable subdirectories under

After you have added new images or new versions of existing images, run  to recompile the image spritesheets.

Sometimes, this command will result in a new spritesheet being created, in which case you must use  to add the new files. You will find them under  (a *.png and *.css file for each spritesheet).

Other
Various useful commands.

Search code
In the console, type: grep -R "STRING" * To search for STRING in all files in the current directory and all the directories within it.

If you want to make a search case insensitive (STRING or String or string etc), add -i grep -iR "STRING" * You'll often want to search all files containing some keyword, in order to determine what files need to be edited when adding/editing some feature.

The grep command also takes a regex as its search parameter: grep -R "REGEX" * Read more about grep and regex here.

Search and replace
Here is a perl command to run in the terminal: perl -e "s/FROM/TO/g" -pi $(find . -name "*.js") Replace FROM by the string you want to replace, and TO by the string to replace the first one with. Note that this example will replace that string only in javascript files (extension .js), but you can specify other filetypes if you want.

If you want to replace all strings, but not their plural or other words containing that string (e.g. replace weapon by TEST, but do not replace weapons, do:   perl -e 's/weapon\b/TEST/g' -pi *

If you want to remove all lines in the javascript files that contain some keyword, do: perl -ni -e 'print unless /keyword/' -pi $(find . -name "*.js") These commands are particularly useful with translation-related work.

Testing the Swagger API Interface Locally
Habitica has an API interface at https://habitrpg.com/static/api, which uses the production database and code. When you have made your own local install of Habitica, you can test the local version of that interface at http://localhost:3000/static/api

If your version of config.json was created a long time ago and you don't have the most up to date data from config.json.example, you might need to edit config.json to change the BASE_URL line to  and then cancel and rerun the npm start command.

Preference Settings
Habitica has preference settings for the users to customise the website's behaviour. You can add new settings if necessary. However please do not add settings that only a small proportion of users are likely to use, or settings for trivial customisations; instead choose a behaviour that the majority of users are likely to be happy with. Too many preferences will make the settings screen look bloated and cluttered and will increase the appearance of complexity. If you're uncertain about whether a preference setting is desirable, you can discuss it in the Aspiring Coders guild or in a relevant GitHub issue or pull request.

Cool tip for storing preferences
From a git issue discussing a possible new user preference setting comes this tip: New preference options can be added to  and the database will pick them up automatically (but if it's ever necessary to adjust the database, we can do that).

"Information for Developers" Sections on General Wiki Pages
At the bottom of some wiki pages, you will see sections called Information for Developers. These contain useful tips for Blacksmiths related to the content on that page.

The information is hidden behind a spoiler-style show/hide toggle button so that it doesn't clutter the page for non-technical users.

The sections use the InfoForDevs Start and InfoForDevs End templates to ensure correct formatting and wording for the buttons and other text. To see how that is done, open any page that has the section in the source editor.

To see a list of all pages that have this section, use the "What links here" tool for the 'Start' template.

If you'd like to see all Information for Developers sections unhidden by default: /* Force all "Information for Developers" sections to always be visible */ .habitrpg-InfoForDevs { display:block !important; }   .habitrpg-InfoForDevs-hideIfDev { display:none; } You can see an example at http://habitrpg.wikia.com/wiki/User:LadyAlys/wikia.css
 * create a Wikia account if you don't already have one
 * edit your personal Wikia css file, which you will find at http://habitrpg.wikia.com/wiki/User:YOUR_USERNAME_HERE/wikia.css
 * insert these lines into that css file:

Contributor Tier Process
You're in luck! Blacksmiths do not need to do anything special, like complete a Contributor Tier request, in order to earn Contributor Tiers. Contributor Tiers will be granted by the admins as they review and accept Blacksmith submissions. Admins will track Blacksmith contributions for credit toward future Contributor Tiers.