2014年12月4日 星期四

Step by Step 使用github參與專案流程(後記)- 媽~我被Merge啦!


        病了兩天,早上看到這個令人振奮的好消息,貢獻給gcloud的code被merge啦~(撒花)雖然只是短短幾行code,但是能對網路社群有個小小的貢獻還是非常開心,記錄一下這個patch的前因後果.
        這個patch主要的目標是https://github.com/GoogleCloudPlatform/gcloud-python/issues/81裡面提出的問題:原本要從dataset裡面取得entity的話,需要兩個階段:
key = Key.from_path(['Person', 'jim'])
dataset.get_entity(key)
這個ISSUE問說可不可以簡化這個API:
dataset.get_entity(['Person', 'jim']) or
dataset.entity('Person').get('jim')
我的patch是針對第一種做法:
原本的code長這樣:

def get_entity(self, key):
entities = self.get_entities([key])
if entities:
return entities[0]
view raw gistfile1.py hosted with ❤ by GitHub
要取得entity只能在裡面放Key,如果要簡化的話,概念上很單純,就是下個判斷說:如果丟進來的東西不是Key,就要呼叫原本key的from_path function來取得key,這樣就能在簡化原本的流程;但是除了簡化流程外,我們也必須保留原來的功能,不然一堆相關功能都壞掉了,所以變成下面這樣:

def get_entity(self, key_or_path):
if isinstance(key_or_path, Key):
entities = self.get_entities([key_or_path])
else:
key = Key.from_path(*key_or_path)
entities = self.get_entities([key])
if entities:
return entities[0]
view raw gistfile1.py hosted with ❤ by GitHub
透過if is instance的功能來對輸入進來的東西做判斷,來達到在既有功能不變的情況下增加新的功能.但是不是改完功能就可以push上專案,還要寫Unitest.針對剛剛不到五行的修改,我大概來來回回另外寫了二,三十行的Unitest,這是我第一次push上去的Unitest,主要就是針對新的功能做測試:

def test_get_entity_path(self):
from gcloud.datastore.connection import datastore_pb
DATASET_ID = 'DATASET'
KIND = 'Kind'
ID = 1234
PATH = [{'kind': KIND, 'id': ID}]
entity_pb = datastore_pb.Entity()
entity_pb.key.partition_id.dataset_id = DATASET_ID
path_element = entity_pb.key.path_element.add()
path_element.kind = KIND
path_element.id = ID
prop = entity_pb.property.add()
prop.name = 'foo'
prop.value.string_value = 'Foo'
connection = _Connection(entity_pb)
dataset = self._makeOne(DATASET_ID, connection)
result = dataset.get_entity([KIND, ID])
key = result.key()
self.assertEqual(key._dataset_id, DATASET_ID)
self.assertEqual(key.path(), PATH)
self.assertEqual(list(result), ['foo'])
self.assertEqual(result['foo'], 'Foo')
view raw gistfile1.py hosted with ❤ by GitHub
但是大大覺得還有必要針對Exception做測試,所以後來又增加新的測試:

def test_get_entity_odd_nonetype(self):
from gcloud.datastore.connection import datastore_pb
DATASET_ID = 'DATASET'
KIND = 'Kind'
entity_pb = datastore_pb.Entity()
connection = _Connection(entity_pb)
dataset = self._makeOne(DATASET_ID, connection)
with self.assertRaises(ValueError):
dataset.get_entity([KIND])
with self.assertRaises(TypeError):
dataset.get_entity(None)
view raw gistfile1.py hosted with ❤ by GitHub
來來回回幾次的詳細內容可以看這裡:https://github.com/GoogleCloudPlatform/gcloud-python/pull/393
最後在解決一些failure後終於被merge.

雖然這只是一個很小的patch,但是學到很多參與專案的經驗:像是嚴格的Unitest設計,github整合CI工具的好處,嚴謹的coding style等等,跟大大的討論以及互動都相當愉快,是很難得的經驗!沒想到自己能對google有所貢獻XD(雖然很微小啦)




沒有留言:

張貼留言