Forcing arbitrary content deployment to the git branch

One of the popular options to deploy something nowadays is git-based deployment (Github pages is a good example). Here’s a recipe to push some content to the remote branch ignoring whatever this branch already has:

1
2
3
4
5
6
7
8
9
10
11
mkdir deploy
cd deploy
echo `date` > 1.txt
git init
git add .
git commit -m "autocommit"
git push -u https://github.com/loki2302/git-force-push-experiment.git \
master:deployed --force
cd ..
rm -rf ./deploy
echo DONE

In this snippet:

  • The directory deploy is created.
  • Within that directory, a current time is echoed to 1.txt.
  • Then, a brand new git repository is created, the entire folder contents are added and committed to the local master.
  • After it comes a trick: we take the local master and push it to the remove deployed branch.

See the demo repository here.

Parameterized AngularJS directives

One of the few redeeming facets of JavaScript is that occasionally its dynamic nature comes in very handy. Imagine you’re building a new app with Angular and you just want to get started with simple CRUD functionality. You want to your all “entity views” to look and feel the same internally.

One of the options is, you build a shared entity-view directive and end up with something like this:

1
2
<entity-view entity="myPerson" template="person.html"></entity-view>
<entity-view entity="myProject" template="project.html"></entity-view>

This works. But there’s a funnier option.

What we’d like to have instead is something like this:

1
2
<person-view person="myPerson"></person-view>
<project-view project="myProject"></project-view>

If we try to code both and then compare the results, it will be clear that the differences between them are minimal:

1
2
3
4
5
6
7
8
9
directive('personView or projectView', function() { // NOTE
return {
restrict: 'E',
scope: {
'person or project': '=' // NOTE
},
template: 'person.html or project.html' // NOTE
};
});

Enter factory method! Perhaps we could design a function that returns a directive definition object based on the input parameters. Let’s give it a try:

1
2
3
4
5
6
7
8
9
10
11
12
function makeDirective(entityName) {
var scope = {};
scope[entityName] = '=';
return function() {
return {
restrict: 'E',
template: entityName + '.html',
scope: scope
};
};
}

Now, calling makeDirective('something') will construct a DDO that defines a directive with template set to something.html and a something local scope property derived from the parent scope:

app.js
1
2
3
4
5
6
7
angular.module('demo', [])
.directive('personView', makeDirective('person'))
.directive('projectView', makeDirective('project'))
.controller('AppController', function($scope) {
scope.myPerson = { name: 'John' };
scope.myProject = { codename: 'Something' };
});

person.html
1
<div class="person">{{person.name}}</div>
project.html
1
<div class="project">{{project.codename}}</div>
app.html
1
2
3
4
<div ng-controller="AppController">
<person-view person="myPerson"></person-view>
<project-view project="myProject"></project-view>
</div>

But wait, where does the makeDirective() come from actually? That’s a good question.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
angular.module('demo', [])
.constant('makeDirective', function(entityName) {
var scope = {};
scope[entityName] = '=';
return function() {
return {
restrict: 'E',
template: entityName + '.html',
scope: scope
};
};
})
.directive('personView', function(makeDirective) {
return makeDirective('person');
})
.directive('projectView', function(makeDirective) {
return makeDirective('project');
});

Sure you can use this approach to parameterize controllers, services, filters and whatever else you can imagine.

The Jasmine/Karma test is here.

My Test Post

Hello there. Here’s some code:

1
console.log('hello world');

Bye.

Hi content! This should be red.

Hi content! This should be pink.

g interface Interface impl1 Implementation #1 interface->impl1 impl2 Implementation #2 interface->impl2 impl3 Implementation #2 interface->impl3 something1 something1 impl3->something1 something2 something2 impl3->something2 something3 something3 impl3->something3 something4 something4 impl3->something4

Inclusion by tag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const line = fileLines[i];
let shouldAppendThisLine = false;
if(state === LOOKING_FOR_START_TAG) {
const match = line.match(startTagRegex);
if(match && match[1] === tagname) {
state = LOOKING_FOR_END_TAG;
}
} else if(state === LOOKING_FOR_END_TAG) {
const match = line.match(endTagRegex);
if(match && match[1] === tagname) {
state = LOOKING_FOR_START_TAG;
} else {
shouldAppendThisLine = true;
}
} else if(state === EXTRACTING_EVERYTHING) {
shouldAppendThisLine = true;
} else {
throw new Error('Unexpected state');
}
if(shouldAppendThisLine) {
const lineIsAnotherStartOrEndTag =
startTagRegex.test(line) || endTagRegex.test(line);
if(lineIsAnotherStartOrEndTag) {
continue;
}
extractedContent += line + '\n';
}

Inclusion by other tag

1
2
3
4
5
6
const match = line.match(endTagRegex);
if(match && match[1] === tagname) {
state = LOOKING_FOR_START_TAG;
} else {
shouldAppendThisLine = true;
}

Complete inclusion

1
2
3
4
5
6
7
.DS_Store
Thumbs.db
db.json
*.log
node_modules/
public/
.deploy*/