Skip to content
This repository has been archived by the owner on Mar 15, 2024. It is now read-only.

Commit

Permalink
Merge pull request #60 from mozilla/invoke-tasks
Browse files Browse the repository at this point in the history
Add invoke tasks
  • Loading branch information
patjouk committed Jul 16, 2019
2 parents 4464c7b + e4326c6 commit 997e2cc
Show file tree
Hide file tree
Showing 49 changed files with 1,354 additions and 1,142 deletions.
18 changes: 18 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": [
"prettier"
],
"plugins": [
"prettier",
"react"
],
"parserOptions": {
"sourceType": "module"
},
"env": {
"es6": true
},
"rules": {
"prettier/prettier": "error"
}
}
7 changes: 7 additions & 0 deletions .stylelintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"plugins": ["stylelint-prettier"],
"rules": {
"prettier/prettier": true,
"color-hex-length": "long"
}
}
22 changes: 22 additions & 0 deletions .stylelintrc-colors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
var config = {
"plugins": ["stylelint-prettier"],
"rules": {
"color-named": "never",
"color-no-hex": true,
"declaration-property-value-blacklist": [
{
"/.*/": [
/rgba{0,1}\(/i,
/hsla{0,1}\(/i,
/hwb\(/i,
/gray\(/i
]
},
{
"message": "Custom colors are not allowed. Please use brand colors listed in _variables.scss."
}
]
}
};

module.exports = config;
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,9 @@ matrix:
- pipenv run coverage run --source './donate' ./manage.py test --settings=donate.settings_test
after_success:
- coveralls
- name: npm tests
before_install:
- nvm install --lts=carbon
- nvm use --lts=carbon
install: "./travis-scripts/npm-install.sh"
script: npm run test
48 changes: 44 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,60 @@ It should be possible to connect the python virtual env inside the container to

- Install [Docker Desktop](https://www.docker.com/products/docker-desktop) (macOS and Windows). For Linux users: install [Docker CE](https://docs.docker.com/install/#supported-platforms) and [Docker Compose](https://docs.docker.com/compose/install/). If you don't want to create a Docker account, direct links to download can be found [in this issue](https://github.com/docker/docker.github.io/issues/6910),
- [Check your install](https://docs.docker.com/get-started/#test-docker-version) by running `docker run hello-world`,
- [Install Invoke](https://www.pyinvoke.org/installing.html),
- If relevant: delete your node_modules directory (`rm -rf node_modules`). It's not necessary, but it speeds up the install.
- Run `docker-compose build`.
- Apply migrations: `docker-compose run backend pipenv run python manage.py migrate`.
- Run `inv docker-setup`.

When it's done, run `docker-compose up`, wait until the static files to be built, and go to `0.0.0.0:8000`. When you want to stop, do `^C` to shut down your containers.

## Invoke tasks

Invoke is a python tasks runner that creates shortcuts for commands we frequently use. For example, instead of `docker-compose run --rm backend pipenv manage.py migrate`, you can use `inv docker-migrate`. It can also be used to run management commands: `inv docker-manage load-fake-data`. If you need to add multiple args to an invoke commands, use quotes. ex: `invoke docker-npm "install moment"`

Installation instructions: https://www.pyinvoke.org/installing.html

### With Docker

### Invoke tasks available:

- `inv -l`: list available tasks,
- `inv docker-catch-up (docker-catchup)`: Rebuild images and apply migrations
- `inv docker-makemigrations`: Creates new migration(s)
- `inv docker-manage`: Shorthand to manage.py. ex: `inv docker-manage "[COMMAND] [ARG]"`
- `inv docker-migrate`: Updates database schema
- `inv docker-npm`: Shorthand to npm. ex: `inv docker-npm "[COMMAND] [ARG]"`
- `inv docker-nuke-db`: Delete your database and create a new one with fake data
- `inv docker-pipenv`: Shorthand to pipenv. ex: `inv docker-pipenv "[COMMAND] [ARG]"`
- `inv docker-setup`: Prepare your dev environment after a fresh git clone
- `inv docker-test-python`: Run python tests

Use `docker-compose up/down` to start or shutdown the dev server.

**note**: use `inv docker-setup` when you've just cloned the repo. If you did a `git pull` on master and want to install the latest dependencies and apply migrations, use `inv docker-catchup` instead.

### Without Docker

### Invoke tasks available:

- `inv -l`: list available tasks,
- `inv catch-up (catchup)`: Install dependencies and apply migrations
- `inv makemigrations`: Creates new migration(s)
- `inv manage`: Shorthand to manage.py. ex: `inv manage "[COMMAND] [ARG]"`
- `inv migrate`: Updates database schema
- `inv setup`: Prepare your dev environment after a fresh git clone
- `inv test`: Run python tests
- `inv runserver`: Start a web server

**note**: use `inv setup` when you've just cloned the repo. If you did a `git pull` on master and want to install the latest dependencies and apply migrations, use `inv catchup` instead.

### Without Invoke

### Running commands inside the Docker container

When the Django server is running, you can start the Django shell with:

docker-compose exec backend pipenv run python manage.py shell

(TODO: wrap this with invoke to make it less cumbersome).

### Running tests

Run the back-end test suite with:
Expand Down
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,13 @@
"optimize": "run-p optimize:**",
"server": "pipenv run python manage.py runserver",
"start": "run-p build-uncompressed server watch:**",
"test:eslint": "eslint --config ./.eslintrc.json \"donate/{,!(frontend)/**/}*.js\" \"source/js/**/*.js\" \"source/js/**/*.jsx\" webpack.config.js",
"test:eslint": "eslint --config ./.eslintrc.json \"source/js/**/*.js\" webpack.config.js",
"test:scss": "stylelint \"source/sass/**/*.scss\" \"source/js/**/*.scss\" --syntax scss",
"test:scss:styleguide:color": "stylelint \"source/sass/**/*.scss\" \"source/js/**/*.scss\" \"!source/sass/**/_colors.scss\" --syntax scss --config .stylelintrc-colors.js",
"test:css": "stylelint \"donate/{,!(frontend)/**/}*.css\" --syntax scss",
"test:scss:styleguide:color": "stylelint \"source/sass/**/*.scss\" \"source/js/**/*.scss\" \"!source/sass/**/_variables.scss\" \"!source/sass/**/_normalize.scss\" --syntax scss --config .stylelintrc-colors.js",
"test": "run-s test:** build",
"watch": "npm run build && run-p watch:**",
"watch:images": "chokidar \"source/images/**/*\" -c \"npm run build:images\"",
"watch:js": "chokidar \"source/js/**/*.js\" \"source/js/**/*.jsx\" -c \"npm run build:js-uncompressed\"",
"watch:js": "chokidar \"source/js/**/*.js\" -c \"npm run build:js-uncompressed\"",
"watch:sass": "chokidar \"source/**/*.scss\" -c \"npm run build:sass\""
},
"browserslist": [
Expand Down
62 changes: 31 additions & 31 deletions source/js/components/menu-toggle.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,45 @@
class MenuToggle {
static selector() {
return '[data-menu-toggle]';
}
static selector() {
return "[data-menu-toggle]";
}

constructor(node, openCb = () => {}, closeCb = () => {}) {
this.node = node;
constructor(node, openCb = () => {}, closeCb = () => {}) {
this.node = node;

// Any callbacks to be called on open or close.
this.openCb = openCb;
this.closeCb = closeCb;
// Any callbacks to be called on open or close.
this.openCb = openCb;
this.closeCb = closeCb;

this.state = {
open: false,
};
this.state = {
open: false
};

this.bindEventListeners();
}
this.bindEventListeners();
}

bindEventListeners() {
this.node.addEventListener('click', () => {
this.toggle();
});
}
bindEventListeners() {
this.node.addEventListener("click", () => {
this.toggle();
});
}

toggle() {
this.state.open ? this.close() : this.open();
}
toggle() {
this.state.open ? this.close() : this.open();
}

open() {
this.node.classList.add('is-open');
this.openCb();
open() {
this.node.classList.add("is-open");
this.openCb();

this.state.open = true;
}
this.state.open = true;
}

close() {
this.node.classList.remove('is-open');
this.closeCb();
close() {
this.node.classList.remove("is-open");
this.closeCb();

this.state.open = false;
}
this.state.open = false;
}
}

export default MenuToggle;
54 changes: 27 additions & 27 deletions source/js/components/tabs.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
class Tabs {
static selector() {
return '.js-tab-item';
}
static selector() {
return ".js-tab-item";
}

constructor(node) {
this.tab = node;
this.tabset = this.tab.closest('.js-tabs');
this.allTabs = this.tabset.querySelectorAll('.js-tab-item');
let tabPanelId = this.tab.getAttribute('aria-controls');
this.tabPanel = document.getElementById(tabPanelId);
this.allTabPanels = this.tabset.querySelectorAll('.js-tab-panel');
this.bindEvents();
}
constructor(node) {
this.tab = node;
this.tabset = this.tab.closest(".js-tabs");
this.allTabs = this.tabset.querySelectorAll(".js-tab-item");
let tabPanelId = this.tab.getAttribute("aria-controls");
this.tabPanel = document.getElementById(tabPanelId);
this.allTabPanels = this.tabset.querySelectorAll(".js-tab-panel");
this.bindEvents();
}

bindEvents() {
this.tab.addEventListener('click', (e) => {
e.preventDefault();
bindEvents() {
this.tab.addEventListener("click", e => {
e.preventDefault();

for (let tab of this.allTabs) {
tab.classList.remove('tabs__item--selected');
tab.setAttribute('aria-selected', 'false');
}
for (let tab of this.allTabs) {
tab.classList.remove("tabs__item--selected");
tab.setAttribute("aria-selected", "false");
}

for (let tabPanel of this.allTabPanels) {
tabPanel.classList.add('tabs__panel--hidden');
}
for (let tabPanel of this.allTabPanels) {
tabPanel.classList.add("tabs__panel--hidden");
}

this.tab.classList.add('tabs__item--selected');
this.tab.setAttribute('aria-selected', 'true');
this.tabPanel.classList.remove('tabs__panel--hidden');
});
}
this.tab.classList.add("tabs__item--selected");
this.tab.setAttribute("aria-selected", "true");
this.tabPanel.classList.remove("tabs__panel--hidden");
});
}
}

export default Tabs;
41 changes: 20 additions & 21 deletions source/js/main.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,37 @@
import 'babel-polyfill';
import "babel-polyfill";

import Tabs from './components/tabs';
import MenuToggle from './components/menu-toggle';
import Tabs from "./components/tabs";
import MenuToggle from "./components/menu-toggle";

// Manage tab index for primary nav
function tabIndexer() {
document.querySelectorAll('[data-nav-tab-index]').forEach(navLink => {
navLink.tabIndex = "-1";
})
document.querySelectorAll("[data-nav-tab-index]").forEach(navLink => {
navLink.tabIndex = "-1";
});
}

// Open the mobile menu callback
function openMenu() {
document.querySelector('[data-primary-nav]').classList.add('is-visible');
document.querySelectorAll('[data-nav-tab-index]').forEach(navLink => {
navLink.removeAttribute("tabindex");
})
document.querySelector("[data-primary-nav]").classList.add("is-visible");
document.querySelectorAll("[data-nav-tab-index]").forEach(navLink => {
navLink.removeAttribute("tabindex");
});
}

// Close the mobile menu callback
function closeMenu() {
document.querySelector('[data-primary-nav]').classList.remove('is-visible');
tabIndexer();
document.querySelector("[data-primary-nav]").classList.remove("is-visible");
tabIndexer();
}

document.addEventListener('DOMContentLoaded', function() {
document.addEventListener("DOMContentLoaded", function() {
for (const menutoggle of document.querySelectorAll(MenuToggle.selector())) {
new MenuToggle(menutoggle, openMenu, closeMenu);
}

for (const menutoggle of document.querySelectorAll(MenuToggle.selector())) {
new MenuToggle(menutoggle, openMenu, closeMenu);
}
for (const tabs of document.querySelectorAll(Tabs.selector())) {
new Tabs(tabs);
}

for (const tabs of document.querySelectorAll(Tabs.selector())) {
new Tabs(tabs);
}

tabIndexer();
tabIndexer();
});
Loading

0 comments on commit 997e2cc

Please sign in to comment.