2015년 5월 31일 일요일

git commit 합치기

pull request시에 하나의 commit message를 전달하기 위한 목적으로 여러 번 commit한 것을 합쳐서 하나의 commit를 만들려면 rebase를 사용하면 된다.

아래 3개의 commit을 하나로 묶어서 push할 예정이다.

스크린샷 2015-05-31 16.03.46

rebase -i 옵션을 사용하여 아래와 같이 주면 HEAD부터 3개의 commit를 합친다.

$ git rebase -i HEAD~3

명령을 주면 편집창에서 수정할 수 있게 되는데, 아래와 같이 log가 나오는 순서의 반대인 커밋한 순서대로 나온다. 여기서 2,3번을 pick에서 squash로 변경하면 합치겠다는 의미이다.(그냥 편집창이므로, pick을 지우고, squash로 다시 써주면 된다.

squash로 변경한 후에 저장하고 나오게 되면, commit message를 수정할 수 있는 창이 나온다.

주석으로 되어 있는 부분을 제외하고 합쳐진다고 보면 된다. 적절히 메세지를 수정하고 저장하고 나오면, 아래와 같이 성공메세지가 나온다.

다시 push를 해보면 commit이 하나만 나와 있고, commit message도 합쳐진 것을 확인할 수 있다.

스크린샷 2015-05-31 16.34.12

주의 : 이미 upstream에 올라간 것을 묶으면 난리(?)난다. rebase는 무조건 local(작업하고 있는 저장소)에 대한  commit에 한해서만 사용해야 한다.

참고
http://ift.tt/1DyxAAS
http://ift.tt/1GlF8tu




from WordPress http://ift.tt/1FmeBIl

2015년 5월 24일 일요일

github pull request 취소하고 수정하여 다시 pull request하기.

pull request 보낸 code가 기각되어 수정하여 다시 pull reqest하고자 한다.

스크린샷 2015-05-24 12.05.56

위와 같이 automatically merge가 안되므로 close하고 다시 수정하고 pull request합니다.

스크린샷 2015-05-24 12.05.25

close하면 branch를 지울 것인가 물어봅니다.

스크린샷 2015-05-24 12.05.41

위에서 지우게 되면 local에서 214_category_tag_sync에서 rebase해서 적용하면 됩니다.

우선 충돌한 pull request의 branch를 불러 온다.

rebase를 하면 아래와 같이 conflict가 발생하고, 수정한 이후에는 ‘git rebase –continue’ 하라고 되어 있다.

git status를 보면 두개의 파일이 conflicting(Unmerged paths) 인 것을 확인할 수 있다.

참고
http://ift.tt/1RdHZIe




from WordPress http://ift.tt/1LrP04a

2015년 5월 23일 토요일

github에서 pull requst 잘하기.

SVN을 오랫동안 써온 그것도 회사에서 약간 이상하게 써온 나로써는 git과 github에 적응하는데는 많은 시간과 어려움이 있었다.

최근에 계속 고민하게 된것은 두가지인데,

pull request 전에 upstream에 새로운 commit이 올라오면 그것을 merge해서 보내야 하는데 이때 내 만든 commit과 merge한 commit이 두개 올라가는 짜증(?) 나는 상황이 생긴다.

또 한가지는 내가 보낸 pull request가 아직 upstream에 merge되기 전에 pull request를 보내면, 이미 보낸 pull request에 붙어 버리는 문제가 생긴다.

이런 한 것에 대하여 왜(why)를 설명하기 보다는 어떤 방식으로 작업하면 이런 문제가 발생하지 않는가(how)에 대해서 설명하고자 한다.

1. contribute 하고자 하는 repository를 Fork 해온다.

스크린샷 2015-05-23 오전 7.48.57

2. local pc에 개발환경 셋업하기.

local pc에 clone 한다.

remote에 upstream 추가하기

3. issue(일감)에 따라 branch하기

앞에 이야기 한 두번째 문제인 pull request가 붙어버리는 문제가 발생하지 않게 하기 위해서는 내가 처리할 이슈(즉 pull request할 부분)을 branch로 분리해서 작업하고 commit(local에 적용)/pull(origin에 적용)/pull request(upstream에 적용요청) 하는 것이다.

사실 일하다 보면 그렇게 미리 지정해서 하기가 잘 안된다. 쉽게 생각했던 issue가 풀리지 않아서 하다가 다른거 하는 경우가 허다하다. 그래서 내 경우에는 master에서 이것저것 만지다가 commit전에 stash로 수정사항 저장하고 new branch를 생성하고 거기서 stash pop하여 commit한다.  여기서는 branch하고 수정하는 걸로 설명한다.

branch를 새로 생성하고 checkout 하기.

issue 수정하기

issue는 wrapMediaTag를 warpMediaTag로 잘 못 쓴 것을 고치는 것이다.

git diff 를 활용하여 아래와 같이 수정상태를 확인 할 수 있다.

4. commit 하고 pull, rebase, push하기

사실 upstream에 변경이 있기 전에 빠르게 commit/pull/pull request를 던지면 제일 좋지만 맘대로 되지 않는다. ㅡ.ㅡ;

rebase 고민 없이 하는 방법이 이슈 수정 및 테스트가 끝났다면 commit하지 말고, stash로 묶어두고 merge후에 stash pop해서 수정한 사항을 재반영하고 빠르게 test 및 commit/pull/pull request를 하는 것이 좋다.

그러나 항상 그럴 수는 없기에 여기서는 commit하고, rebase하고 pull, pull request하는 것으로 설명하겠다.
git에서는 staged 상태라는 개념이 있는데 여기서는 설명하지 않는다. 그냥 -a 옵션으로 커밋!

commit하기

rebase하기

앞에 commit한 log와 비교하면, 새로 갱신된 내용이 내가 새로 commit한 log 전으로 들어오고, 내가 commit한 hash값이 변경된 것을 확인할수 있다.  주의사항은 내가 local에 commit한 것이 다른 곳으로 전달되지 않았을 경우에만 rebase해야 한다.

push하기

5. pull request 하기

이제 github에 들어가면 보면 pull reqest하라는 내용이 나오고, 깔끔한 1 commit을 볼 수 있다.

스크린샷 2015-05-23 오전 9.34.51

깔끔한 1 commit

스크린샷 2015-05-23 오전 9.36.25

끝~

참고
http://ift.tt/1LmNtMN
http://ift.tt/1caBfeh
http://ift.tt/1JIm1uF




from WordPress http://ift.tt/1AkCfZa

JavaScript/Node.js Array(배열) 만큼 비동기함수 호출하여 값받기

tistory의 경우 다수의 blog를 생성할 수 있다. 그리고 각 blog마다 category를 만들 수 있다.

#214 issue에서는 blogList를 가지고 오면서 같이 각 blog의 category를 가지고 오고 싶었다.

그렇게 하려면 비동기함수(callback function)을 여러번(즉 blog수만큼) 호출하고, 모두가 값을 받아왔을 때 다음 단계로 넘어가는 것이 필요하다.

이번에 사용한 것이 npm async였다.

async example을 보면 async.parallel 의 first parameter에 callback function array를 넣고, second parameter에 들어온 결과를 처리할 함수를 넣으면 된다.

문제의 부분은 어떻게 내가 만든 함수로 function array를 만들 것인가 인데, 아래의 예제처럼 기존에 사용하던 모든 그대로 function(callback){}; 으로 싸서 Tasks array에 넣어버리면 된다.

full code는 아래의 링크를 참조해주세요~

BlogSync/routes/tistory.js

참고
http://ift.tt/1IUa4RR
http://ift.tt/1bR87EC




from WordPress http://ift.tt/1HzXYvw

JavaScript 문자열에서 동일한 단어 모두 바꾸기.

kakao story의 경우 줄 바꿈을 newline으로 하고 있는데, 그 글을 그대로 blogger나 tistory에 posting하면 줄바꿈이 동작하지 않는다.

그래서 한번에 newline(\n)을 break tag(<br>)으로 변경해야 하는데 이런 경우에는 RegExp와 replace를 사용하면 가능하다.

참고
http://ift.tt/1JI0hPx




from WordPress http://ift.tt/1JI0hPF

2015년 5월 20일 수요일

JointJS를 활용하여 Provider관계 그리기.

BlogSync

http://ift.tt/1FvpkDD

blog post를 다른 blog와 SNS에 posting해주는 서비스임

스크린샷 2015-05-17 18.24.28

목표

blog의 post가 어디로 갈 수 있는지 설정해주는 기능.
diagram을 사용한 직관적인 UI를 제공하자.
http://ift.tt/1Fvpif5

스크린샷 2015-05-17 18.24.09

몇가지 검토하에 JointJS로 만들게 되었음.

  • go.js
  • HighCharts
    • General drawing 예제로 ux는 비슷하게 지원은 가능하나 interactive를 지원하지 않는 것으로 보여 사용하지 않음
    • http://ift.tt/1w2Qk6f
  • JointJS

JointJS is a modern HTML 5 JavaScript library for visualization and interaction with diagrams and graphs. It can be used to create either static diagrams or, and more importantly, fully interactive diagramming tools and application builders.

코드 설명

graph와 paper를 생성시킴.

centerX,centerY를 중심으로 거리 200에 있는 circle 갯수만큼 간격을 가지고 위치시킴.

동작화면

provider 만큼 object그리기

스크린샷 2015-05-20 21.24.41

provider 하나 선택한 화면

스크린샷 2015-05-20 21.25.05

Line을 클릭할 수 있으며 누를때 마다 방향이 바뀌는데, post가 어느 방향으로 갈지 설정할 수 있게 된다.

스크린샷 2015-05-20 21.25.16

 

하면서 만난 문제

[Polygons 방식의 show/hide 처리 문제]

  • joint.js에서 최상위 element로 아래와 같이 div가 필요함
<div id="paper"></div>

  • 위의 div에 ng-show와 같은 angular.js의 directive를 사용해서 처리하면 타이밍 문제로 동작하지 않음
  • 해결 방법
    • $(‘#paper’).show(); / $(‘#paper’).hide(); 을 사용하면 정상 동작함
    • jquery를 사용하게 되는 문제가 있음(joint.js가 jquery를 사용함)

개선해야 할 부분

jquery 부분을 제거

angular.js를 쓰면서 jquery를 쓰지 않는 방향으로 진행하였으나, joint.js가 jquery기반으로 되어 있어서 추후에 빼는 방법을 모색할 필요가 있다.




from WordPress http://ift.tt/1FvplaL

2015년 5월 4일 월요일

분석 : d3.js bar chart with tooltips

d3js.org example 중에 “Using d3-tip to add tooltips to a d3 bar bart”를 분석하였다.

아래 분석은 “Let’s Make a Bar Chart, Part 1 2 3“내용을 참조하였다.

example 예제에서 꾸미는 CSS나 속성은 모두 제외하고 데이타가 있을 때 어떻게 bar chart를 만들 것인가 순으로 분석하였다.

Step 1- Loading an external data file in tab-separated values(TSV) format

d3.tsv를 사용하여 데이터를 읽어오고, div tag기준으로 분류하였다. 또한 div의 width를 달리하여 값에 따라 차이가 나도록 하였다.

스크린샷 2015-05-04 16.15.07

위의 결과는 html으로 아래와 같이 된다.

http://ift.tt/1OT5Cbc

Step 2 – Bar chart using SVG

d3.select와 append를 사용하여 svg를 dom에 추가하고, selectAll.data를 사용하여 rect 객체를 추가 한다.

scale.ordinal은 공평하게 분류할때 사용한다. 주어진 0~width에서 domain에 들어온 갯수만큼 나누어서 x(d)에 의해서 x값을 주고, x.rangeBand()로 동일한 넓이를 받는다.

scale.linear는 주어진 범위와 domain으로 들어온 최대값을 매핑해서 그 값에 맞는 상대값을 계산하여 반환한다.

아래와 같은 결과가 나오게 된다.

스크린샷 2015-05-04 16.51.31

위의 결과는 html으로 아래와 같이 된다.

http://ift.tt/1OT5Cbe

Step 3 – Adding Axes

x,y축을 그리기 위해서 left, bottom에 margin를 넣어야 한다. 실제 예제에서는 top, right 모두 들어가지만 내용의 이해를 돕기 위해서 left, bottom만 넣었다.

svg를 640×480 전체 사이즈를 가지고, scaler들의 최대값을 margin를 뺀 값으로 변경하고, chart라는 object가 left로 translate left해서 실제 그리는 영역으로 사용했다.

d3에서는 축을 그리는 위해서 axis라는 api를 제공한다. 그 중에 orient는 axis(축)을 어디에 둘 것인가 지정하는 것이지만 내부적으로 tick를 그릴때 참고하는 것이지 실제 위치를 찾아주는 것이 아니므로 위치는 직접 잡아주어야 한다.

y축이 헷갈릴 수 있는데, 이유가 값이 일반적으로 우리가 배운 반대인 가장 위가 좌표상으로 0이고, 가장 아래가 가장 크므로 반대로 생각해야 한다.

스크린샷 2015-05-04 17.04.28

위의 결과는 html으로 아래와 같이 된다.

http://ift.tt/1OT5Ejo

html tag를 보면, tick이라는 group에 line과 text element가 추가된 것을 볼 수 있다. path, line, text를 axis가 넣어주는 것이다.

Step 4 – Add tooltips to a d3 bar chart

d3-tip은 추가로 lib가 필요로 한다.

사용법은 간단하다.

d3.tip이라는 api로 tip를 생성해서 연결하고자 하는 selector에서 call 하면 된다.

그리고 실제 적용해야 하는 rect object의 mouse event에 연결하면 끝난다.

해보면 각 rect에 event를 붙이고 나서 axes를 추가하면 정상적으로 svg element에 추가 되지 않는데 정확한 이유는 모르겠음.

스크린샷 2015-05-04 17.15.29

위의 결과는 html으로 아래와 같이 된다.

http://ift.tt/1EKDzD5

위의 full code는 http://ift.tt/1OT5Cbl 올려두었으니 참고바랍니다.

참고
http://ift.tt/HJj3sZ
http://ift.tt/1OT5Cbi




from WordPress http://ift.tt/1EKDz63

2015년 5월 3일 일요일

passport를 통하여 google, kakao oauth 사용시에 access token갱신하기.

google과 kakao의 경우에 refresh token과 함께 expires_in(초단위)를 주는데 그 시간 안에 access token을 갱신해야 한다.

access token의 만기 시간과 refresh token의 만기 시간이 다르기 때문에 rest api 요청시에 error 401이 발생하면 access token을 갱신해주어도 되지만, 이러면 rest api 사용하는 모든 부분에 대하여 401처리를 해주어야 한다.

blogsync의 경우에는 정기적인 스케줄러(2분)가 돌아가고 있기 때문에 그때 갱신해줘야 하는 타임이 넘은 경우에 갱신해주도록 하였다.

로그인했을때, expires_in값을 가지고 expireTime으로 저장하도록 만들었다.

UserMgr.makeTokenExpireTime = function (expires_in) {
    var expireDate;
    if (expires_in) {
        expireDate = new Date();
        expireDate.setSeconds(expireDate.getSeconds()+expires_in);
    }

    return expireDate;
};
function(req, accessToken, refreshToken, params, profile, done) {
    var meta = {"cName": GOOGLE_PROVIDER, "fName":"passport.use" };

    log.debug("accessToken:" + accessToken, meta);
    log.debug("refreshToken:" + refreshToken, meta);
    log.debug("params:"+JSON.stringify(params), meta);
    log.debug("profile:" + JSON.stringify(profile), meta);

    //It's not correct information. but I confirmed by /blogger/v3/users/self"
    var providerId = "g"+profile.id;

    var provider = {
        "providerName": profile.provider,
        "accessToken": accessToken,
        "refreshToken": refreshToken,
        "providerId": providerId.toString(),
        "tokenExpireTime": userMgr.makeTokenExpireTime(params.expires_in),
        "displayName": profile.displayName
    };
}

expire time이 되기 전에 access token을 갱신한다.

function _updateAccessToken(user, provider, callback) {
    var url = "https://kauth.kakao.com" + "/oauth/token";
    var data = {
        grant_type: 'refresh_token',
        client_id: clientConfig.clientID,
        refresh_token: provider.refreshToken
    };

    _requestPost(url, provider.accessToken, data, function (error, response, body) {
        if (error) {
            log.error(error);
            return callback(error);
        }
        log.info(body);

        var newProvider = userMgr.updateAccessToken(user, provider, body.access_token, body.refresh_token, body.expires_in);
        return callback(null, newProvider);
    });
}

아래와 들어오는 결과를 가지고 기존 값은 변경하면 된다.

[Response]

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
    "access_token":"wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww",
    "token_type":"bearer",
    "refresh_token":"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz",  //optional
    "expires_in":43199,
}

google도 kakao랑 동일한 방법으로 동작된다.

참고

http://ift.tt/1zmUaxp

http://ift.tt/1bO5FD7




from WordPress http://ift.tt/1bO5CY3

2015년 4월 26일 일요일

ajax와 request of node

사실 둘다, get, post를 한다는 것은 동일한데, ajax로 구현한 것을 server side인 node에서 구현해야 할때도 있다.

그럴때, 참고하기 위해 실제 동작은 동일하지만 구현법이 다른 두개 비교 해둔다.

jquery의 ajax post

$.ajax({ url:"/login", type:"post", 
  data:{userId:"userA", userPwd:"pwdA"},
  success : function(response) {
    console.log(response);
}, 
  error : function(request, response, error) {
    console.log(request);
}});

node.js의 request post

request.post("/login", {
    json: false,
    form: {userId:"userA", userPwd:"pwdA"}
}, function (error, response, body) {
    if (error) {
        return console.error(error);
    }
    return console.log(body);
});



from WordPress http://ift.tt/1Dojezm

2015년 4월 9일 목요일

vi에서 한글 encoding 변환하기.

vi에서 한글이 ??? 깨져서 보이는 경우가 있는 이 경우에는 encoding 을 아래와 같이 변환해야 한다.



:e ++enc=euc-kr



자꾸 잊어버려 기록 차원에서 남긴다.








from WordPress http://ift.tt/1FDPsux

2015년 3월 17일 화요일

몰입, 두 번째 이야기

892554296x_1


생존을 위한 삶은 필요한 만큼의 노력을 하는데 그치지만, 후회없는 삶은 최대한의 노력을 하게 한다.

생존을 위한 삶은 수동적인 삶에 머물지만, 후회 없는 삶은 능동적이고 적극적인 삶으로 이끈다.

그 차이는 시간이 갈수록 커진다.


자유시간이 주어졌을 때 심심하다고 생각하는 사람은 구조적으로 수동적일 수 밖에 없다.


무리가 없는 최선, 그래서 오랜기간 아무 탈 없이 지속적으로 실천할 수 있는 최선, 이것이 첫번째 패러다임의 변화다.

‘의식이 있는 한 생각의 끈을 놓지 않겠다!’고 결심하고 이것을 실천하면서 몰입을 체험했다. 이것이 두번째 패러다임의 변화다.

인간이 할 수 있는 최대의 집중 상태와 최대의 열정이 결합될 때 비로소 궁극의 최선이 발휘되는 것이다.

나는 몇달간 몰입을 지속하면서 이러한 궁극의 최선을 경험했다.


일반적으로는 서로 들어맞지 않는 아이디어와 사건과 기억들을 연결하는 것, 그것이 바로 창의성의 기본이다.


고민은 단지 생각을 유도할 뿐이다. 고민과 생각을 확실히 구별해야 한다.

고민이 지속되면 노이로제가 되고 스트레스와 병을 유발하지만, 올바른 방법으로 생각을 지속하면 부작용이 거의 없다.


공허함과 부질없음은 주로 마음의 중심이 일 안에 있지 않고, 바깥에 있을 때 생긴다.


내가 하는 일이 과연 꽃다운 나의 청춘과 바꿀 만한 가치가 있는지 잘 생각해봐야 한다.

그것은 어떠한 일을 하느냐의 문제가 아니라 어떻게 일을 하느냐의 문제다.


열정과 도전정신은 끊임없는 도전을 통해서만 키울 수 있는 것이다.


확률에 영향을 주는 요소에 대해 올바른 판단을 내려야 문제가 효과적으로 해결된다는 것이 엔트로피 법칙이 주는 시사점이다.


프로는 선택과 집중을 통해 필요한 곳에 모든 에너지를 쏟아 붓지만, 아마추어는 불필요한 곳에 에너지를 흩뿌린다.


가치관은 어떤 일을 하느냐가 아니라 어떻게 일을 하느냐에 따라 달라지는 것이다.


나이가 들수록, 그리고 새로운 지식을 흡수하지 않을수록 신념우위체계의 성향이 강해진다.


이 세상에 역기능 없이 순기능만 있는 것도 없고, 순기능없이 역기능만 있는 것도 없다.

똑같은 상황이라도 어느 쪽에 몰입하는냐에 따라 결과가 달라지는 것이다.


행복이 넘치는 상태를 오랜기간 경험하다 보면 행복에 대한 비중이 점점 줄어든다는 것이다.

행복은 인생의 목적이라기보다 무엇인가 보람있고 가치 있는 일을 찾고 이를 보다 더 잘하기 위해 거쳐야 하는 하나의 과정이자 수단이다.


‘자신의 능력을 발휘하고 그 한계를 넓혀가는 삶’을 살아 한다.








from WordPress http://ift.tt/1EmJDyw

2015년 2월 8일 일요일

WebStorm 실행과 창 관련 단축키

Run


ctl+shift+R


실행하기.


Debug


ctl+shift+D


디버깅모드로 실행하기.


Node.js에서 server, client 모두 debug mode로 디버깅하기.


스크린샷 2015-02-08 20.06.53


위와 같이 server(node.js)에 break point를 걸고, shift+ctl+d로 debug mode로 실행한다.


스크린샷 2015-02-08 20.15.41


client (angular.js)쪽에 break point를 걸어준다.


스크린샷 2015-02-08 20.16.57


index.html에서 debug로 실행하면 break가 client, server 왔다갔다하면서 디버깅이 가능한다.


Hide active tool window


shift + esc


Terminal window


alt + F12 (alt+fn+f12)


Project tab on/off


cmd + 1


참조









from WordPress http://ift.tt/16Gk4yH

WebStorm에서 변수, 함수 추가 단축키 사용하기.

Extract -> Variable


alt+cmd+v


지정된 부분을 변수에 추가하는 기능이다.


case 1) require부분에 변수로 빠르게 넣기.



require("assert")|

위와 같이 require부분까지만 넣고, alt+cmd+v를 하면 var assert 그리고 ;까지 추가해준다.


스크린샷 2015-02-08 17.06.19


case 2) url이나, 특정 string을 변수로 변환하기.



$http.get("http://localhost:3000").success(function(products) {
});

위의 코드에서 url를 선택하여 alt+cmd+v를 하면 아래와 같이 수정된다.


스크린샷 2015-02-08 17.00.02


위와 같이 var key = “http://localhost:3000&#8243;;이 상위라인에 생성되고, 본래 위치는 변수로 대처된다. 여기서 변수명을 수정하면 위의 라인 정의된 변수 명도 같이 변경된다.


새로 만들어진 변수를 함수 시작부분으로 옮기는 것은 직접 해야 하는듯하다.


Extract -> Method


alt+cmd+m


특정 코드 부분을 Method로 빼는 경우에 유용하다.


스크린샷 2015-02-08 19.15.24


위와 같이 Method로 빼고자 하는 부분을 선택하고, alt+cmd+m을 한다.


그러면 위와 같이 method scope를 지정하는 팝업창이 뜬다.


스크린샷 2015-02-08 19.16.10


원하는 scope를 지정하면 함수명을 변경하고, parameter를 설정하는 창이 나온다.


스크린샷 2015-02-08 19.16.33


함수명과 parameter를 설정하면 위와 같이 함수로 분리된 코드를 볼 수 있다.








from WordPress http://ift.tt/1Kw170E