add gerrit.googlesource.com for android develop

the 'repo' tool google provided will use it to initialize the android build directory

0.docs.google.com
0.drive.google.com
1.docs.google.com
1.drive.google.com
10.docs.google.com
10.drive.google.com
11.docs.google.com
11.drive.google.com
12.docs.google.com
12.drive.google.com
13.docs.google.com
13.drive.google.com
14.docs.google.com
14.drive.google.com
15.docs.google.com
15.drive.google.com
16.docs.google.com
16.drive.google.com
2.docs.google.com
2.drive.google.com
3.docs.google.com
3.drive.google.com
4.docs.google.com
4.drive.google.com
5.docs.google.com
5.drive.google.com
6.docs.google.com
6.drive.google.com
7.docs.google.com
7.drive.google.com
8.docs.google.com
8.drive.google.com
9.docs.google.com
9.drive.google.com
admin.google.com
answers.google.com
appengine.google.com
apps.google.com
appspot.l.google.com
bks0.books.google.com
bks1.books.google.com
bks10.books.google.com
bks2.books.google.com
bks3.books.google.com
bks4.books.google.com
bks5.books.google.com
bks6.books.google.com
bks7.books.google.com
bks8.books.google.com
bks9.books.google.com
blogsearch.google.com
books.google.com
browserchannel-docs.l.google.com
browserchannel-spreadsheets.l.google.com
browsersync.google.com
browsersync.l.google.com
buzz.google.com
cache.l.google.com
cache.pack.google.com
calendar.google.com
cbk0.google.com
cbk1.google.com
cbk2.google.com
cbk3.google.com
cbks0.google.com
cbks1.google.com
cbks2.google.com
cbks3.google.com
chart.apis.google.com
chrome.google.com
cloud.google.com
code.google.com
code.l.google.com
csi.l.google.com
desktop.google.com
desktop.l.google.com
desktop2.google.com
developers.google.com
ditu.google.com
dl.google.com
dl.l.google.com
dl-ssl.google.com
docs.google.com
docs0.google.com
docs1.google.com
docs2.google.com
docs3.google.com
docs4.google.com
docs5.google.com
docs6.google.com
docs7.google.com
docs8.google.com
docs9.google.com
drive.google.com
drive0.google.com
drive1.google.com
drive2.google.com
drive3.google.com
drive4.google.com
drive5.google.com
drive6.google.com
drive7.google.com
drive8.google.com
drive9.google.com
earth.google.com
encrypted.google.com
encrypted-tbn.l.google.com
encrypted-tbn0.google.com
encrypted-tbn1.google.com
encrypted-tbn2.google.com
encrypted-tbn3.google.com
feedburner.google.com
feedproxy.google.com
finance.google.com
fusion.google.com
geoauth.google.com
gg.google.com
ghs.google.com
ghs.l.google.com
ghs46.google.com
ghs46.l.google.com
google.com
googleapis.l.google.com
googleapis-ajax.google.com
googleapis-ajax.l.google.com
googlecode.l.google.com
google-public-dns-a.google.com
google-public-dns-b.google.com
goto.google.com
groups.google.com
groups.l.google.com
groups-beta.google.com
gxc.google.com
id.google.com
id.l.google.com
images.google.com
images.l.google.com
investor.google.com
jmt0.google.com
kh.google.com
kh.l.google.com
khm.google.com
khm.l.google.com
khm0.google.com
khm1.google.com
khm2.google.com
khm3.google.com
khmdb.google.com
khms.google.com
khms.l.google.com
khms0.google.com
khms1.google.com
khms2.google.com
khms3.google.com
labs.google.com
large-uploads.l.google.com
lh2.google.com
lh2.l.google.com
lh3.google.com
lh4.google.com
lh5.google.com
lh6.google.com
linkhelp.clients.google.com
local.google.com
m.google.com
map.google.com
maps.google.com
maps.l.google.com
maps-api-ssl.google.com
mars.google.com
mobile.l.google.com
mobile-gtalk.l.google.com
mobilemaps.clients.google.com
mt.google.com
mt.l.google.com
mt0.google.com
mt1.google.com
mt2.google.com
mt3.google.com
mtalk.google.com
mts.google.com
mts.l.google.com
mts0.google.com
mts1.google.com
mts2.google.com
mts3.google.com
music.google.com
music-streaming.l.google.com
mw1.google.com
mw2.google.com
news.google.com
news.l.google.com
pack.google.com
photos.google.com
photos-ugc.l.google.com
picasa.google.com
picasaweb.google.com
picasaweb.l.google.com
places.google.com
play.google.com
productforums.google.com
profiles.google.com
reader.google.com
safebrowsing.cache.l.google.com
safebrowsing.clients.google.com
safebrowsing.google.com
safebrowsing-cache.google.com
sb.google.com
sb.l.google.com
sb-ssl.google.com
sb-ssl.l.google.com
scholar.google.com
scholar.l.google.com
script.google.com
services.google.com
sites.google.com
sketchup.google.com
sketchup.l.google.com
spreadsheet.google.com
spreadsheets.google.com
spreadsheets.l.google.com
spreadsheets0.google.com
spreadsheets1.google.com
spreadsheets2.google.com
spreadsheets3.google.com
spreadsheets4.google.com
spreadsheets5.google.com
spreadsheets6.google.com
spreadsheets7.google.com
spreadsheets8.google.com
spreadsheets9.google.com
spreadsheets-china.l.google.com
suggestqueries.google.com
suggestqueries.l.google.com
support.google.com
tbn0.google.com
tbn1.google.com
tbn2.google.com
tbn3.google.com
toolbar.google.com
toolbarqueries.clients.google.com
toolbarqueries.google.com
toolbarqueries.l.google.com
tools.google.com
tools.l.google.com
translate.google.com
trends.google.com
upload.docs.google.com
upload.drive.google.com
uploads.code.google.com
uploadsj.clients.google.com
v3.cache1.c.docs.google.com
video.google.com
video-stats.l.google.com
voice.google.com
wallet.google.com
wire.l.google.com
writely.google.com
writely.l.google.com
writely-china.l.google.com
writely-com.l.google.com
www.l.google.com
www2.l.google.com
www3.l.google.com
www4.l.google.com
ytstatic.l.google.com
plus.google.com
plus.url.google.com
plusone.google.com

www.google.com
ssl.google-analytics.com
www.google-analytics.com
accounts.l.google.com
checkout.l.google.com
sandbox.google.com
wifi.google.com
wifi.l.google.com
clients.l.google.com
clients1.google.com
clients2.google.com
clients3.google.com
clients4.google.com
clients5.google.com
clients7.google.com
checkout.google.com
accounts.google.com
m.google.com
adwords.google.com
talk.google.com

mail.google.com
filetransferenabled.mail.google.com
chatenabled.mail.google.com

apis.google.com
clients6.google.com
talkgadget.google.com

0-open-opensocial.googleusercontent.com
0-focus-opensocial.googleusercontent.com
1-focus-opensocial.googleusercontent.com
1-open-opensocial.googleusercontent.com
1-ps.googleusercontent.com
2-focus-opensocial.googleusercontent.com
2-open-opensocial.googleusercontent.com
2-ps.googleusercontent.com
3-focus-opensocial.googleusercontent.com
3-ps.googleusercontent.com
3hdrrlnlknhi77nrmsjnjr152ueo3soc-a-calendar-opensocial.googleusercontent.com
3-open-opensocial.googleusercontent.com
4-ps.googleusercontent.com
4fjvqid3r3oq66t548clrdj52df15coc-a-oz-opensocial.googleusercontent.com
53rd6p0catml6vat6qra84rs0del836d-a-oz-opensocial.googleusercontent.com
59cbv4l9s05pbaks9v77vc3mengeqors-a-oz-opensocial.googleusercontent.com
8kubpeu8314p2efdd7jlv09an9i2ljdo-a-oz-opensocial.googleusercontent.com
adstvca8k2ooaknjjmv89j22n9t676ve-a-oz-opensocial.googleusercontent.com
a-oz-opensocial.googleusercontent.com
blogger.googleusercontent.com
bt26mravu2qpe56n8gnmjnpv2inl84bf-a-oz-opensocial.googleusercontent.com
clients1.googleusercontent.com
clients2.googleusercontent.com
clients3.googleusercontent.com
clients4.googleusercontent.com
clients5.googleusercontent.com
clients6.googleusercontent.com
clients7.googleusercontent.com
code-opensocial.googleusercontent.com
debh8vg7vd93bco3prdajidmm7dhql3f-a-oz-opensocial.googleusercontent.com
doc-00-7o-docs.googleusercontent.com
doc-08-7o-docs.googleusercontent.com
doc-0c-7o-docs.googleusercontent.com
doc-0g-7o-docs.googleusercontent.com
doc-0s-7o-docs.googleusercontent.com
doc-10-7o-docs.googleusercontent.com
doc-14-7o-docs.googleusercontent.com
feedback.googleusercontent.com
googlehosted.l.googleusercontent.com
gp0.googleusercontent.com
gp1.googleusercontent.com
gp2.googleusercontent.com
gp3.googleusercontent.com
gp4.googleusercontent.com
gp5.googleusercontent.com
gp6.googleusercontent.com
hsco54a20sh11q9jkmb51ad2n3hmkmrg-a-oz-opensocial.googleusercontent.com
i8brh95qor6r54nkl52hidj2ggcs4jgm-a-oz-opensocial.googleusercontent.com
images1-focus-opensocial.googleusercontent.com
images2-focus-opensocial.googleusercontent.com
images3-focus-opensocial.googleusercontent.com
images4-focus-opensocial.googleusercontent.com
images5-focus-opensocial.googleusercontent.com
images6-focus-opensocial.googleusercontent.com
images7-focus-opensocial.googleusercontent.com
images8-focus-opensocial.googleusercontent.com
images9-focus-opensocial.googleusercontent.com
images-docs-opensocial.googleusercontent.com
images-oz-opensocial.googleusercontent.com
k6v18tjr24doa89b55o3na41kn4v73eb-a-oz-opensocial.googleusercontent.com
lh1.googleusercontent.com
lh2.googleusercontent.com
lh3.googleusercontent.com
lh4.googleusercontent.com
lh5.googleusercontent.com
lh6.googleusercontent.com
mail-attachment.googleusercontent.com
music.googleusercontent.com
music-onebox.googleusercontent.com
oauth.googleusercontent.com
ob7f2qc0i50kbjnc81vkhgmb5hsv7a8l-a-oz-opensocial.googleusercontent.com
ode25pfjgmvpquh3b1oqo31ti5ibg5fr-a-calendar.opensocial.googleusercontent.com
qhie5b8u979rnch1q0hqbrmbkn9estf7-a-oz-opensocial.googleusercontent.com
r70rmsn4s0rhk6cehcbbcbfbs31pu0va-a-oz-opensocial.googleusercontent.com
rbjhe237k979f79d87gmenp3gejfonu9-a-oz-opensocial.googleusercontent.com
s1.googleusercontent.com
s2.googleusercontent.com
s3.googleusercontent.com
s4.googleusercontent.com
s5.googleusercontent.com
s6.googleusercontent.com
spreadsheets-opensocial.googleusercontent.com
static.googleusercontent.com
t.doc-0-0-sj.sj.googleusercontent.com
themes.googleusercontent.com
translate.googleusercontent.com
u807isd5egseeabjccgcns005p2miucq-a-oz-opensocial.googleusercontent.com
upt14k1i2veesusrda9nfotcrbp9d7p5-a-oz-opensocial.googleusercontent.com
webcache.googleusercontent.com
www.googleusercontent.com
www-calendar-opensocial.googleusercontent.com
www-fc-opensocial.googleusercontent.com
www-focus-opensocial.googleusercontent.com
www-gm-opensocial.googleusercontent.com
www-kix-opensocial.googleusercontent.com
www-open-opensocial.googleusercontent.com
www-opensocial.googleusercontent.com
www-opensocial-sandbox.googleusercontent.com
www-oz-opensocial.googleusercontent.com
www-hangouts-opensocial.googleusercontent.com
www-onepick-opensocial.googleusercontent.com

lh1.ggpht.com
lh2.ggpht.com
lh3.ggpht.com
lh4.ggpht.com
lh5.ggpht.com
lh6.ggpht.com
nt0.ggpht.com
nt1.ggpht.com
nt2.ggpht.com
nt3.ggpht.com
nt4.ggpht.com
nt5.ggpht.com

csi.gstatic.com
g0.gstatic.com
g1.gstatic.com
g2.gstatic.com
g3.gstatic.com
maps.gstatic.com
mt0.gstatic.com
mt1.gstatic.com
mt2.gstatic.com
mt3.gstatic.com
mt4.gstatic.com
mt5.gstatic.com
mt6.gstatic.com
mt7.gstatic.com
ssl.gstatic.com
t0.gstatic.com
t1.gstatic.com
t2.gstatic.com
t3.gstatic.com
www.gstatic.com

ajax.googleapis.com
chart.googleapis.com
fonts.googleapis.com
maps.googleapis.com
mt0.googleapis.com
mt1.googleapis.com
mt2.googleapis.com
mt3.googleapis.com
redirector-bigcache.googleapis.com
translate.googleapis.com
www.googleapis.com
content.googleapis.com

appspot.com
chrometophone.appspot.com
evolutionofweb.appspot.com
googcloudlabs.appspot.com
gv-gadget.appspot.com
magnifier.blogspot.com
moderator.appspot.com
newsfeed-dot-latest-dot-rovio-ad-engine.appspot.com
productideas.appspot.com
project-slingshot-gp.appspot.com
r2303.latest.project-slingshot-hr.appspot.com
r3085-dot-latest-dot-project-slingshot-gp.appspot.com
r3091-dot-latest-dot-project-slingshot-gp.appspot.com
r3101-dot-latest-dot-project-slingshot-gp.appspot.com
r3269-dot-latest-dot-project-slingshot-gp.appspot.com
r3432-dot-latest-dot-project-slingshot-hr.appspot.com
r4681-dot-latest-dot-project-slingshot-hr.appspot.com
r7647-dot-latest-dot-project-slingshot-hr.appspot.com
wcproxyx.appspot.com
balsamiqgdrive.appspot.com
www.appspot.com

autoproxy-gfwlist.googlecode.com
chromium.googlecode.com
closure-library.googlecode.com
earth-api-samples.googlecode.com
gmaps-samples-flash.googlecode.com
google-code-feed-gadget.googlecode.com
smarthosts.googlecode.com

accounts.youtube.com
apiblog.youtube.com
help.youtube.com
insight.youtube.com
m.youtube.com
ytimg.l.google.com
www.youtube.com
i.ytimg.com
i1.ytimg.com
i2.ytimg.com
i3.ytimg.com
i4.ytimg.com
s.ytimg.com

blogsearch.google.cn
ditu.google.cn
gg.google.cn
id.google.cn
maps.gstatic.cn
m.google.cn
mt.google.cn
mt0.google.cn
mt1.google.cn
mt2.google.cn
mt3.google.cn
news.google.cn
scholar.google.cn
translate.google.cn
www.google.cn
www.gstatic.cn

clients1.google.com.hk
accounts.google.com.hk
blogsearch.google.com.hk
books.google.com.hk
desktop.google.com.hk
encrypted.google.com.hk
groups.google.com.hk
gxc.google.com.hk
id.google.com.hk
images.google.com.hk
m.google.com.hk
maps.google.com.hk
news.google.com.hk
picasaweb.google.com.hk
plus.url.google.com.hk
scholar.google.com.hk
toolbar.google.com.hk
toolbarqueries.google.com.hk
translate.google.com.hk
translate.google.com.hk
wenda.google.com.hk
www.google.com.hk

android.googlesource.com
gerrit.googlesource.com
auth.keyhole.com
chrome.angrybirds.com
developer.android.com
domains.googlesyndication.com
earthengine.googlelabs.com
feeds.feedburner.com
g.co
goo.gl
golang.org
listen.googlelabs.com
m.googlemail.com
market.android.com
ngrams.googlelabs.com
www.googleadservices.com
www.googlelabs.com
www.googlesource.com
www.orkut.com
www.blogger.com
accounts.blogger.com
www.panoramio.com
panoramio.com
static.panoramio.com
tpc.googlesyndication.com
uberproxy.corp.google.com
developer.chrome.com

0.docs.google.com
0.drive.google.com
1.docs.google.com
1.drive.google.com
10.docs.google.com
10.drive.google.com
11.docs.google.com
11.drive.google.com
12.docs.google.com
12.drive.google.com
13.docs.google.com
13.drive.google.com
14.docs.google.com
14.drive.google.com
15.docs.google.com
15.drive.google.com
16.docs.google.com
16.drive.google.com
2.docs.google.com
2.drive.google.com
3.docs.google.com
3.drive.google.com
4.docs.google.com
4.drive.google.com
5.docs.google.com
5.drive.google.com
6.docs.google.com
6.drive.google.com
7.docs.google.com
7.drive.google.com
8.docs.google.com
8.drive.google.com
9.docs.google.com
9.drive.google.com
admin.google.com
answers.google.com
appengine.google.com
apps.google.com
appspot.l.google.com
bks0.books.google.com
bks1.books.google.com
bks10.books.google.com
bks2.books.google.com
bks3.books.google.com
bks4.books.google.com
bks5.books.google.com
bks6.books.google.com
bks7.books.google.com
bks8.books.google.com
bks9.books.google.com
blogsearch.google.com
books.google.com
browserchannel-docs.l.google.com
browserchannel-spreadsheets.l.google.com
browsersync.google.com
browsersync.l.google.com
buzz.google.com
cache.l.google.com
cache.pack.google.com
calendar.google.com
cbk0.google.com
cbk1.google.com
cbk2.google.com
cbk3.google.com
cbks0.google.com
cbks1.google.com
cbks2.google.com
cbks3.google.com
chart.apis.google.com
chrome.google.com
cloud.google.com
code.google.com
code.l.google.com
csi.l.google.com
desktop.google.com
desktop.l.google.com
desktop2.google.com
developers.google.com
ditu.google.com
dl.google.com
dl.l.google.com
dl-ssl.google.com
docs.google.com
docs0.google.com
docs1.google.com
docs2.google.com
docs3.google.com
docs4.google.com
docs5.google.com
docs6.google.com
docs7.google.com
docs8.google.com
docs9.google.com
drive.google.com
drive0.google.com
drive1.google.com
drive2.google.com
drive3.google.com
drive4.google.com
drive5.google.com
drive6.google.com
drive7.google.com
drive8.google.com
drive9.google.com
earth.google.com
encrypted.google.com
encrypted-tbn.l.google.com
encrypted-tbn0.google.com
encrypted-tbn1.google.com
encrypted-tbn2.google.com
encrypted-tbn3.google.com
feedburner.google.com
feedproxy.google.com
finance.google.com
fusion.google.com
geoauth.google.com
gg.google.com
ghs.google.com
ghs.l.google.com
ghs46.google.com
ghs46.l.google.com
google.com
googleapis.l.google.com
googleapis-ajax.google.com
googleapis-ajax.l.google.com
googlecode.l.google.com
google-public-dns-a.google.com
google-public-dns-b.google.com
goto.google.com
groups.google.com
groups.l.google.com
groups-beta.google.com
gxc.google.com
id.google.com
id.l.google.com
images.google.com
images.l.google.com
investor.google.com
jmt0.google.com
kh.google.com
kh.l.google.com
khm.google.com
khm.l.google.com
khm0.google.com
khm1.google.com
khm2.google.com
khm3.google.com
khmdb.google.com
khms.google.com
khms.l.google.com
khms0.google.com
khms1.google.com
khms2.google.com
khms3.google.com
labs.google.com
large-uploads.l.google.com
lh2.google.com
lh2.l.google.com
lh3.google.com
lh4.google.com
lh5.google.com
lh6.google.com
linkhelp.clients.google.com
local.google.com
m.google.com
map.google.com
maps.google.com
maps.l.google.com
maps-api-ssl.google.com
mars.google.com
mobile.l.google.com
mobile-gtalk.l.google.com
mobilemaps.clients.google.com
mt.google.com
mt.l.google.com
mt0.google.com
mt1.google.com
mt2.google.com
mt3.google.com
mtalk.google.com
mts.google.com
mts.l.google.com
mts0.google.com
mts1.google.com
mts2.google.com
mts3.google.com
music.google.com
music-streaming.l.google.com
mw1.google.com
mw2.google.com
news.google.com
news.l.google.com
pack.google.com
photos.google.com
photos-ugc.l.google.com
picasa.google.com
picasaweb.google.com
picasaweb.l.google.com
places.google.com
play.google.com
productforums.google.com
profiles.google.com
reader.google.com
safebrowsing.cache.l.google.com
safebrowsing.clients.google.com
safebrowsing.google.com
safebrowsing-cache.google.com
sb.google.com
sb.l.google.com
sb-ssl.google.com
sb-ssl.l.google.com
scholar.google.com
scholar.l.google.com
script.google.com
services.google.com
sites.google.com
sketchup.google.com
sketchup.l.google.com
spreadsheet.google.com
spreadsheets.google.com
spreadsheets.l.google.com
spreadsheets0.google.com
spreadsheets1.google.com
spreadsheets2.google.com
spreadsheets3.google.com
spreadsheets4.google.com
spreadsheets5.google.com
spreadsheets6.google.com
spreadsheets7.google.com
spreadsheets8.google.com
spreadsheets9.google.com
spreadsheets-china.l.google.com
suggestqueries.google.com
suggestqueries.l.google.com
support.google.com
tbn0.google.com
tbn1.google.com
tbn2.google.com
tbn3.google.com
toolbar.google.com
toolbarqueries.clients.google.com
toolbarqueries.google.com
toolbarqueries.l.google.com
tools.google.com
tools.l.google.com
translate.google.com
trends.google.com
upload.docs.google.com
upload.drive.google.com
uploads.code.google.com
uploadsj.clients.google.com
v3.cache1.c.docs.google.com
video.google.com
video-stats.l.google.com
voice.google.com
wallet.google.com
wire.l.google.com
writely.google.com
writely.l.google.com
writely-china.l.google.com
writely-com.l.google.com
www.l.google.com
www2.l.google.com
www3.l.google.com
www4.l.google.com
ytstatic.l.google.com
plus.google.com
plus.url.google.com
plusone.google.com

www.google.com
ssl.google-analytics.com
www.google-analytics.com
accounts.l.google.com
checkout.l.google.com
sandbox.google.com
wifi.google.com
wifi.l.google.com
clients.l.google.com
clients1.google.com
clients2.google.com
clients3.google.com
clients4.google.com
clients5.google.com
clients7.google.com
checkout.google.com
accounts.google.com
m.google.com
adwords.google.com
talk.google.com

mail.google.com
filetransferenabled.mail.google.com
chatenabled.mail.google.com

apis.google.com
clients6.google.com
talkgadget.google.com

0-open-opensocial.googleusercontent.com
0-focus-opensocial.googleusercontent.com
1-focus-opensocial.googleusercontent.com
1-open-opensocial.googleusercontent.com
1-ps.googleusercontent.com
2-focus-opensocial.googleusercontent.com
2-open-opensocial.googleusercontent.com
2-ps.googleusercontent.com
3-focus-opensocial.googleusercontent.com
3-ps.googleusercontent.com
3hdrrlnlknhi77nrmsjnjr152ueo3soc-a-calendar-opensocial.googleusercontent.com
3-open-opensocial.googleusercontent.com
4-ps.googleusercontent.com
4fjvqid3r3oq66t548clrdj52df15coc-a-oz-opensocial.googleusercontent.com
53rd6p0catml6vat6qra84rs0del836d-a-oz-opensocial.googleusercontent.com
59cbv4l9s05pbaks9v77vc3mengeqors-a-oz-opensocial.googleusercontent.com
8kubpeu8314p2efdd7jlv09an9i2ljdo-a-oz-opensocial.googleusercontent.com
adstvca8k2ooaknjjmv89j22n9t676ve-a-oz-opensocial.googleusercontent.com
a-oz-opensocial.googleusercontent.com
blogger.googleusercontent.com
bt26mravu2qpe56n8gnmjnpv2inl84bf-a-oz-opensocial.googleusercontent.com
clients1.googleusercontent.com
clients2.googleusercontent.com
clients3.googleusercontent.com
clients4.googleusercontent.com
clients5.googleusercontent.com
clients6.googleusercontent.com
clients7.googleusercontent.com
code-opensocial.googleusercontent.com
debh8vg7vd93bco3prdajidmm7dhql3f-a-oz-opensocial.googleusercontent.com
doc-00-7o-docs.googleusercontent.com
doc-08-7o-docs.googleusercontent.com
doc-0c-7o-docs.googleusercontent.com
doc-0g-7o-docs.googleusercontent.com
doc-0s-7o-docs.googleusercontent.com
doc-10-7o-docs.googleusercontent.com
doc-14-7o-docs.googleusercontent.com
feedback.googleusercontent.com
googlehosted.l.googleusercontent.com
gp0.googleusercontent.com
gp1.googleusercontent.com
gp2.googleusercontent.com
gp3.googleusercontent.com
gp4.googleusercontent.com
gp5.googleusercontent.com
gp6.googleusercontent.com
hsco54a20sh11q9jkmb51ad2n3hmkmrg-a-oz-opensocial.googleusercontent.com
i8brh95qor6r54nkl52hidj2ggcs4jgm-a-oz-opensocial.googleusercontent.com
images1-focus-opensocial.googleusercontent.com
images2-focus-opensocial.googleusercontent.com
images3-focus-opensocial.googleusercontent.com
images4-focus-opensocial.googleusercontent.com
images5-focus-opensocial.googleusercontent.com
images6-focus-opensocial.googleusercontent.com
images7-focus-opensocial.googleusercontent.com
images8-focus-opensocial.googleusercontent.com
images9-focus-opensocial.googleusercontent.com
images-docs-opensocial.googleusercontent.com
images-oz-opensocial.googleusercontent.com
k6v18tjr24doa89b55o3na41kn4v73eb-a-oz-opensocial.googleusercontent.com
lh1.googleusercontent.com
lh2.googleusercontent.com
lh3.googleusercontent.com
lh4.googleusercontent.com
lh5.googleusercontent.com
lh6.googleusercontent.com
mail-attachment.googleusercontent.com
music.googleusercontent.com
music-onebox.googleusercontent.com
oauth.googleusercontent.com
ob7f2qc0i50kbjnc81vkhgmb5hsv7a8l-a-oz-opensocial.googleusercontent.com
ode25pfjgmvpquh3b1oqo31ti5ibg5fr-a-calendar.opensocial.googleusercontent.com
qhie5b8u979rnch1q0hqbrmbkn9estf7-a-oz-opensocial.googleusercontent.com
r70rmsn4s0rhk6cehcbbcbfbs31pu0va-a-oz-opensocial.googleusercontent.com
rbjhe237k979f79d87gmenp3gejfonu9-a-oz-opensocial.googleusercontent.com
s1.googleusercontent.com
s2.googleusercontent.com
s3.googleusercontent.com
s4.googleusercontent.com
s5.googleusercontent.com
s6.googleusercontent.com
spreadsheets-opensocial.googleusercontent.com
static.googleusercontent.com
t.doc-0-0-sj.sj.googleusercontent.com
themes.googleusercontent.com
translate.googleusercontent.com
u807isd5egseeabjccgcns005p2miucq-a-oz-opensocial.googleusercontent.com
upt14k1i2veesusrda9nfotcrbp9d7p5-a-oz-opensocial.googleusercontent.com
webcache.googleusercontent.com
www.googleusercontent.com
www-calendar-opensocial.googleusercontent.com
www-fc-opensocial.googleusercontent.com
www-focus-opensocial.googleusercontent.com
www-gm-opensocial.googleusercontent.com
www-kix-opensocial.googleusercontent.com
www-open-opensocial.googleusercontent.com
www-opensocial.googleusercontent.com
www-opensocial-sandbox.googleusercontent.com
www-oz-opensocial.googleusercontent.com
www-hangouts-opensocial.googleusercontent.com
www-onepick-opensocial.googleusercontent.com

lh1.ggpht.com
lh2.ggpht.com
lh3.ggpht.com
lh4.ggpht.com
lh5.ggpht.com
lh6.ggpht.com
nt0.ggpht.com
nt1.ggpht.com
nt2.ggpht.com
nt3.ggpht.com
nt4.ggpht.com
nt5.ggpht.com

csi.gstatic.com
g0.gstatic.com
g1.gstatic.com
g2.gstatic.com
g3.gstatic.com
maps.gstatic.com
mt0.gstatic.com
mt1.gstatic.com
mt2.gstatic.com
mt3.gstatic.com
mt4.gstatic.com
mt5.gstatic.com
mt6.gstatic.com
mt7.gstatic.com
ssl.gstatic.com
t0.gstatic.com
t1.gstatic.com
t2.gstatic.com
t3.gstatic.com
www.gstatic.com

ajax.googleapis.com
chart.googleapis.com
fonts.googleapis.com
maps.googleapis.com
mt0.googleapis.com
mt1.googleapis.com
mt2.googleapis.com
mt3.googleapis.com
redirector-bigcache.googleapis.com
translate.googleapis.com
www.googleapis.com
content.googleapis.com

appspot.com
chrometophone.appspot.com
evolutionofweb.appspot.com
googcloudlabs.appspot.com
gv-gadget.appspot.com
magnifier.blogspot.com
moderator.appspot.com
newsfeed-dot-latest-dot-rovio-ad-engine.appspot.com
productideas.appspot.com
project-slingshot-gp.appspot.com
r2303.latest.project-slingshot-hr.appspot.com
r3085-dot-latest-dot-project-slingshot-gp.appspot.com
r3091-dot-latest-dot-project-slingshot-gp.appspot.com
r3101-dot-latest-dot-project-slingshot-gp.appspot.com
r3269-dot-latest-dot-project-slingshot-gp.appspot.com
r3432-dot-latest-dot-project-slingshot-hr.appspot.com
r4681-dot-latest-dot-project-slingshot-hr.appspot.com
r7647-dot-latest-dot-project-slingshot-hr.appspot.com
wcproxyx.appspot.com
balsamiqgdrive.appspot.com
www.appspot.com

autoproxy-gfwlist.googlecode.com
chromium.googlecode.com
closure-library.googlecode.com
earth-api-samples.googlecode.com
gmaps-samples-flash.googlecode.com
google-code-feed-gadget.googlecode.com
smarthosts.googlecode.com

accounts.youtube.com
apiblog.youtube.com
help.youtube.com
insight.youtube.com
m.youtube.com
ytimg.l.google.com
www.youtube.com
i.ytimg.com
i1.ytimg.com
i2.ytimg.com
i3.ytimg.com
i4.ytimg.com
s.ytimg.com

blogsearch.google.cn
ditu.google.cn
gg.google.cn
id.google.cn
maps.gstatic.cn
m.google.cn
mt.google.cn
mt0.google.cn
mt1.google.cn
mt2.google.cn
mt3.google.cn
news.google.cn
scholar.google.cn
translate.google.cn
www.google.cn
www.gstatic.cn

clients1.google.com.hk
accounts.google.com.hk
blogsearch.google.com.hk
books.google.com.hk
desktop.google.com.hk
encrypted.google.com.hk
groups.google.com.hk
gxc.google.com.hk
id.google.com.hk
images.google.com.hk
m.google.com.hk
maps.google.com.hk
news.google.com.hk
picasaweb.google.com.hk
plus.url.google.com.hk
scholar.google.com.hk
toolbar.google.com.hk
toolbarqueries.google.com.hk
translate.google.com.hk
translate.google.com.hk
wenda.google.com.hk
www.google.com.hk

android.googlesource.com
auth.keyhole.com
chrome.angrybirds.com
developer.android.com
domains.googlesyndication.com
earthengine.googlelabs.com
feeds.feedburner.com
g.co
goo.gl
golang.org
listen.googlelabs.com
m.googlemail.com
market.android.com
ngrams.googlelabs.com
www.googleadservices.com
www.googlelabs.com
www.googlesource.com
www.orkut.com
www.blogger.com
accounts.blogger.com
www.panoramio.com
panoramio.com
static.panoramio.com
tpc.googlesyndication.com
uberproxy.corp.google.com
developer.chrome.com


added output

added output

program makedv

local unit `1'
local mode `2'

drop if `unit' == "NA"

egen unitid = group(`unit')
genvar unitid

if "`mode'" == "node"{
    gennodevar unitid
}

if "`mode'" == "way"{
    genwayvar unitid
}

if "`mode'" == ""{
    genchangevar unitid
}

end

program genvar

di "generating county-level vars"

local unit `1'

// useful vars
bysort uid: gen numusercontrib = _N
bysort uid: egen minmonth = min(month)

bysort `unit' uid month: gen tmp1 = (_n==1)
bysort `unit' uid: egen nummonth = total(tmp1)
drop tmp1

// a) contribs
di "numcontrib"
bysort `unit' month: gen numcontrib = _N

// b) users
di "numuser"
bysort `unit' month uid: gen tmp1 = (_n==1)
bysort `unit' month: egen numuser = total(tmp1)
drop tmp1

// c) serious users
// 90 percentile == 18, 95 is 56
di "numserious90, numserious95"
bysort `unit' month uid: gen tmp1 = (_n==1)*(numuserc > 18)
bysort `unit' month: egen numserious90 = total(tmp1)

bysort `unit' month uid: gen tmp2 = (_n==1)*(numuserc > 56)
bysort `unit' month: egen numserious95 = total(tmp2)
drop tmp1 tmp2

// d) new users

// new users
di "numnewusers"
bysort `unit' month uid: gen tmp1 = (_n==1) * (month==minmonth)
bysort `unit' month: egen numnewusers = total(tmp1)
drop tmp1

// new committed users
di "numnewusers6"
bysort `unit' month uid: gen tmp1 = (_n==1) * (month==minmonth) * (nummonth >= 6)
bysort `unit' month: egen numnewusers6 = total(tmp1)
drop tmp1

// new super users
di "numnewusers90"
bysort `unit' month uid: gen tmp1 = (_n==1) * (month==minmonth) * (numuserc >= 18)
bysort `unit' month: egen numnewusers90 = total(tmp1)
drop tmp1

// new first time users in unit
di "numfirstseen"
sort `unit' uid month
bysort `unit' uid: gen tmp1 = (_n==1)
bysort `unit' month: egen numfirstseen = total(tmp1)
drop tmp1

end

program genchangevar

local unit `1'
di "generating change-specific vars"
bysort `unit' month: egen numchanges = total(num_change)

end

//////////////////////////////
/// GEN WAY VAR
//////////////////////////////

program genwayvar

local unit `1'
di "generating way-specific vars"

// gen userfulvars
gen ishighway = (highway!="NA")
gen isbuilding = (building!="NA")
gen isparking = (parking!="NA")
gen isamenity = (amenity!="NA")

gen type = ""
replace type = type + "highway " if ishighway == 1
replace type = type + "building " if isbuilding == 1
replace type = type + "parking " if isparking == 1
replace type = type + "amenity " if isamenity == 1

gen istiger = (tigercfcc == "NA" & tigercounty == "NA" & highway != "NA")
replace istiger = !istiger
replace istiger = . if ishighway == 0

gen hasattrib = (maxspeed != "NA") | (oneway != "NA") | (lanes != "NA") | (access != "NA")
replace hasattrib = . if ishighway == 0

makehighwayclass

// highway, building, parking, amenity

// outcomes
// how many highway, building, amenity were added?
bysort `unit' month: egen numhighway = total(ishighway)
bysort `unit' month: egen numbuilding = total(isbuilding)
bysort `unit' month: egen numamenity = total(isamenity)
bysort `unit' month: egen numparking = total(isparking)
bysort `unit' month: gen numways = _N

// how many non tiger highway added?
bysort `unit' month: egen numnontiger = total(ishighway*(istiger==0))

// how many tiger ways touched?
bysort `unit' month: egen numtiger = total(ishighway*(istiger==1))

// how many of different classes
forvalues x = 1/4{
    bysort `unit' month: egen numclass`x' = total(ishighway*(highwayclass==`x'))
}

end

program makehighwayclass

gen highwayclass = .
replace highwayclass = 1 if highway == "motorway"
replace highwayclass = 1 if highway == "motorway_link"
replace highwayclass = 1 if highway == "trunk"
replace highwayclass = 1 if highway == "trunk_link"

replace highwayclass = 2 if highway == "primary"
replace highwayclass = 2 if highway == "primary_link"
replace highwayclass = 2 if highway == "secondary"
replace highwayclass = 2 if highway == "secondary_link"

replace highwayclass = 3 if highway == "tertiary"
replace highwayclass = 3 if highway == "tertiary_link"
replace highwayclass = 3 if highway == "residential"
replace highwayclass = 3 if highway == "unclassified"
replace highwayclass = 3 if highway == "road"
replace highwayclass = 3 if highway == "service"

replace highwayclass = 4 if highway == "footway"
replace highwayclass = 4 if highway == "track"
replace highwayclass = 4 if highway == "path"
replace highwayclass = 4 if highway == "cycleway"
replace highwayclass = 4 if highway == "pedestrian"
replace highwayclass = 4 if highway == "steps"

replace highwayclass = -1 if ishighway == 1 & highwayclass == .

end

// GEN NODE VAR

program gennodevar

local unit `1'
di "generating node-specific vars"

// note: things can have multiple tags
// num amenity
bysort `unit' month: gen tmp1 = (amenity!="NA")
bysort `unit' month: egen numamenity = total(tmp1)
drop tmp1

// num address
bysort `unit' month: gen tmp1 = (addr!="NA")
bysort `unit' month: egen numaddr = total(tmp1)
drop tmp1

end

program makedv

local unit `1'
local mode `2'

drop if `unit' == "NA"

egen unitid = group(`unit')
genvar unitid

if "`mode'" == "node"{
    gennodevar unitid
}

if "`mode'" == "way"{
    genwayvar unitid
}

if "`mode'" == ""{
    genchangevar unitid
}

end

program genchangevar

local unit `1'
di "generating change-specific vars"
bysort `unit' month: egen numchanges = total(num_change)

end

program gennodevar

local unit `1'
di "generating node-specific vars"

// note: things can have multiple tags
// num amenity
bysort `unit' month: gen tmp1 = (amenity!="NA")
bysort `unit' month: egen numamenity = total(tmp1)
drop tmp1

// num address
bysort `unit' month: gen tmp1 = (addr!="NA")
bysort `unit' month: egen numaddr = total(tmp1)
drop tmp1

end

program genwayvar

local unit `1'
di "generating way-specific vars"

// gen userfulvars
gen ishighway = (highway!="NA")
gen isbuilding = (building!="NA")
gen isparking = (parking!="NA")
gen isamenity = (amenity!="NA")

gen type = ""
replace type = type + "highway " if ishighway == 1
replace type = type + "building " if isbuilding == 1
replace type = type + "parking " if isparking == 1
replace type = type + "amenity " if isamenity == 1

gen istiger = (tigercfcc == "NA" & tigercounty == "NA" & highway != "NA")
replace istiger = !istiger
replace istiger = . if ishighway == 0

gen hasattrib = (maxspeed != "NA") | (oneway != "NA") | (lanes != "NA") | (access != "NA")
replace hasattrib = . if ishighway == 0

makehighwayclass

// highway, building, parking, amenity

// outcomes
// how many highway, building, amenity were added?
bysort `unit' month: egen numhighway = total(ishighway)
bysort `unit' month: egen numbuilding = total(isbuilding)
bysort `unit' month: egen numamenity = total(isamenity)
bysort `unit' month: egen numparking = total(isparking)
bysort `unit' month: gen numways = _N

// how many non tiger highway added?
bysort `unit' month: egen numnontiger = total(ishighway*(istiger==0))

// how many tiger ways touched?
bysort `unit' month: egen numtiger = total(ishighway*(istiger==1))

// how many of different classes
forvalues x = 1/4{
    bysort `unit' month: egen numclass`x' = total(ishighway*(highwayclass==`x'))
}

end

program makehighwayclass

gen highwayclass = .
replace highwayclass = 1 if highway == "motorway"
replace highwayclass = 1 if highway == "motorway_link"
replace highwayclass = 1 if highway == "trunk"
replace highwayclass = 1 if highway == "trunk_link"

replace highwayclass = 2 if highway == "primary"
replace highwayclass = 2 if highway == "primary_link"
replace highwayclass = 2 if highway == "secondary"
replace highwayclass = 2 if highway == "secondary_link"

replace highwayclass = 3 if highway == "tertiary"
replace highwayclass = 3 if highway == "tertiary_link"
replace highwayclass = 3 if highway == "residential"
replace highwayclass = 3 if highway == "unclassified"
replace highwayclass = 3 if highway == "road"
replace highwayclass = 3 if highway == "service"

replace highwayclass = 4 if highway == "footway"
replace highwayclass = 4 if highway == "track"
replace highwayclass = 4 if highway == "path"
replace highwayclass = 4 if highway == "cycleway"
replace highwayclass = 4 if highway == "pedestrian"
replace highwayclass = 4 if highway == "steps"

replace highwayclass = -1 if ishighway == 1 & highwayclass == .

end

program genvar

local unit `1'

// useful vars
bysort uid: gen numusercontrib = _N
bysort uid: egen minmonth = min(month)

bysort `unit' uid month: gen tmp1 = (_n==1)
bysort `unit' uid: egen nummonth = total(tmp1)
drop tmp1

// a) contribs
bysort `unit' month: gen numcontrib = _N

// b) users
bysort `unit' month uid: gen tmp1 = (_n==1)
bysort `unit' month: egen numuser = total(tmp1)
drop tmp1

// c) serious users
// 90 percentile == 18, 95 is 56

bysort `unit' month uid: gen tmp1 = (_n==1)*(numuserc > 18)
bysort `unit' month: egen numserious90 = total(tmp1)

bysort `unit' month uid: gen tmp2 = (_n==1)*(numuserc > 56)
bysort `unit' month: egen numserious95 = total(tmp2)
drop tmp1 tmp2

// d) new users

// new users
bysort `unit' month uid: gen tmp1 = (_n==1) * (month==minmonth)
bysort `unit' month: egen numnewusers = total(tmp1)
drop tmp1

// new committed users
bysort `unit' month uid: gen tmp1 = (_n==1) * (month==minmonth) * (nummonth >= 6)
bysort `unit' month: egen numnewusers6 = total(tmp1)
drop tmp1

// new super users
bysort `unit' month uid: gen tmp1 = (_n==1) * (month==minmonth) * (numuserc >= 18)
bysort `unit' month: egen numnewusers90 = total(tmp1)
drop tmp1

// new first time users in unit
sort `unit' uid month
bysort `unit' uid: gen tmp1 = (_n==1)
bysort `unit' month: egen numfirstseen = total(tmp1)
drop tmp1

end


[iegitaddmd ? ] update helpfile with comparefolder() option

{smcl}
{* 31 Jan 2019}{...}
{hline}
help for {hi:iegitaddmd}
{hline}

{title:Title}

{cmd:iegitaddmd} {hline 2} Creates a placeholder file in subfolders of a GitHub repository folder, which allows committing folder structures with empty folders.

{phang2}For a more descriptive discussion on the intended usage and work flow of this
command please see the {browse "https://dimewiki.worldbank.org/wiki/Iegitaddmd":DIME Wiki}.

{title:Syntax}

{phang} {cmdab:iegitaddmd} , {opt folder(file_path)} [{opt comparefolder(file_path)} {cmd:customfile(}{it:{help filename}}{cmd:)} {opt all} {opt skip} {opt replace}]

{marker opts}{...}
{synoptset 23}{...}
{synopthdr:options}
{synoptline}
{synopt :{opt folder(file_path)}}Specifies the folder path to the project folder clone where placeholder files will be created{p_end}
{synopt :{opt comparefolder(file_path)}}Specifies the top folder of a folder tree to be compared with {opt folder()}{p_end}
{synopt :{cmd:customfile(}{it:{help filename}}{cmd:)}}Specifies a file saved on disk that is used instead of the default file as placeholder{p_end}
{synopt :{cmd:all}}Creates the placeholder file in every subfolder of {opt folder()}, whether empty or not{p_end}
{synopt :{opt skip}}If option {opt all} is used and a folder has a file with same name as placeholder file, then nothing is done{p_end}
{synopt :{opt replace}}If option {opt all} is used and a folder has a file with same name as placeholder file, then the file is overwritten{p_end}
{synopt :{opt manual}}If option {opt manual} is used then the user is prompted before each placeholder file is created.{p_end}
{synoptline}

{marker desc}
{title:Description}

{pstd}GitHub does not sync empty folders, or folder that only contain ignored files. However, it is common in research projects that these types of folders needs to be shared anyways. {cmd:iegitaddmd} provides a solution to this by creating placeholder files in in these folders. This placeholder file can then be shared to GitHub and that way the folder is also shared. {cmd:iegitaddmd} have two ways to identify which those folders are that are developed with the two use cases described below in mind.{p_end}

{pstd}{bf:Use case 1.} It is common in the beginning of a research project that a standardized folder structure is set up (for example with {help iefolder}) where some folders are created that are not yet needed. Examples of folders like that could be the output folders. If these folders are not shared at the time they are created, there is a risk that different team members name them differently which will be confusing and could lead to errors. {cmd:iegitaddmd} can solve this by scanning a folder and all its sub-folders for completely empty folders, and create a placeholder file in that folder..{p_end}

{pstd}The solution to use case 1 in {cmd:iegitaddmd} is a Stata adaptation of {it:Solution B} in {browse "http://bytefreaks.net/gnulinux/bash/how-to-add-automatically-all-empty-folders-in-git-repository" :this post}.{p_end}

{pstd}{bf:Use case 2.} A common method when transferring an already ongoing research project is to copy all of the data work folder from wherever the files and folders where shared before (for example DropBox) to a clone of the repository. Then only the files that are meant to be shared on GitHub are uploaded to the cloud using a {it:.gitignore file}. Empty folders or folders where all files are ignored is not shared this way. {cmd:iegitaddmd} can solve this by scanning the DropBox folder (or wherever the project folder was shared before) for sub-folders that exist in that folder but not in the clone and crate a placeholder file in all those clones.{p_end}

{pstd}The way you differentiate between these two use cases when using {cmd:iegitaddmd} is whether the option {opt comparefolder()} is used or not. If that option is used, then {cmd:iegitaddmd} will identify all folders that are in {opt comparefolder()} that is not in {opt folder()}, and create a placeholder file there. If {opt comparefolder()} is not used, then {cmd:iegitaddmd} will identify all completely empty folders (no files or subfolders) and create a placeholder file there.{p_end}

 {pstd}The default placeholder file used if no file is specified using option {opt customfile()} is called README.md, which is a name and format recognized by GitHub.com so that the content of the file is displayed on GitHub.com when navigating to that folder using a browser. The placeholder file may be removed as	soon as files that are not ignored have been added to the folder, or even better is to keep the file but edit the content of it so it documents the content of that folder for other and future team members.{p_end}

{marker optslong}
{title:Options}

{phang}{opt folder(file_path)} is the folder path to the project folder clone where the placeholder files will be created. Unless option {opt comparefolder()} or {opt all} is used, then placeholder files will be created in all empty folders. See option {opt manual} for a way to manually confirm each folder before a placeholder file is created in it.{p_end}

{phang}{opt comparefolder(file_path)} is used to compare a file tree in a different location and create the folders with placeholder files in all folders that exist in {opt comparefolder()} but not in {opt folder()}. If a folder that does no exist in {opt folder()} has a subfolder, then both the folder and the subfolder will be created and the placeholder file is only crated in the sub-folder. This is enough to share both folder and the subfolder in GitHub. If the {opt comparefolder()} and {opt folder()} ends with folders with different names, for example {opt folder(${project}/datawork/baseline)} and {opt comparefolder(${project}/datawork)}, then the command will throw an error as it is likely that the paths do not point to corresponding folders in the two folder trees. See option {opt manual} for a way to manually confirm each folder before a placeholder file is created in it.{p_end}

{phang}{cmd:file(}{it:{help filename}}{cmd:)} allows the user to specify a file saved on
	the computer to be used as the placeholder file	instead of the default README.md file. This
	allows people and organizations to write their own template placeholder files according to their own
	preferences. We recommend that a file of type .md (markdown) and name README.md is used as
	GitHub.com recognizes this name and format and will display the content of the file when someone
	browse to that folder on GitHub.com. But this is not a technical requirement, any file type
	and name can be used as placeholder file.{p_end}

{phang}{opt all} creates the placeholder file in {opt folder()} and in every subfolder,
	regardless if they are empty or not. This allows the user to create a placeholder file in every
	folder that can be edited with documentation and instructions to the purpose and usage of
	each subfolder. This option can also be important when .{it:gitignore} is used, as {cmd:iegitaddmd} will not
	create files to subfolders that only has ignored file -- in which case the folder will not
	be synced by GitHub.{p_end}

{phang}{opt skip} and {opt replace} tells {cmd:iegitaddmd} what to do if the option {opt all} is used
	and if any of the folders contain a file with the same name as the placeholder file the command
	is trying to create. If a file with the same name as the placeholder file exist and neither of these options
	are used, then the command will throw an error. If {opt skip} is used, then nothing is done in the
	folder where the file with the same name exists and the command proceeds to the next folder.
	If {opt replace} is used then the file with the same name is overwritten with the new placeholder
	file before the command proceeds to the next folder.{p_end}

{phang}{opt manual} can be used to exactly control in which folders a placeholder file will be created. This
allows that this command is run on a the top folder of the repository, but then only selected folders get a placeholder.{p_end}

{title:Example}

{pstd}{inp:global github_folder "C:\Users\JohnSmith\Documents\GitHub\ProjectA"}{break}{inp:iegitaddmd , folder({it:"$github_folder"})}{p_end}

{pstd}In the example above, there is a GitHub repository in the folder ProjectA. This
	repository has a folder structure where some folders are still empty but will later
	be populated with files. In order to have all folders, even the empty ones, synced on all
	collaborators' cloned local copies of the repository, the folders need to contain at least
	one file, which is being created by the command.{p_end}

{title:Acknowledgements}

{pstd}I would like to acknowledge the help in testing and proofreading I received in relation to this command and help file from (in alphabetic order):{p_end}
{pmore}Guadalupe Bedoya{break}Luiza Cardoso de Andrade{break}Mrijan Rimal{break}Benjamin Daniels{break}

{title:Author}

{phang}All commands in ietoolkit is developed by DIME Analytics at DECIE, The World Bank's unit for Development Impact Evaluations.

{phang}Main author: Kristoffer Bjarkefur, DIME Analytics, The World Bank Group

{phang}Please send bug-reports, suggestions and requests for clarifications
		 writing "ietoolkit iegitaddmd" in the subject line to:{break}
		 dimeanalytics@worldbank.org

{phang}You can also see the code, make comments to the code, see the version
		 history of the code, and submit additions or edits to the code through {browse "https://github.com/worldbank/ietoolkit":the GitHub repository of ietoolkit}.{p_end}

{smcl}
{* 31 Jan 2019}{...}
{hline}
help for {hi:iegitaddmd}
{hline}

{title:Title}

{cmd:iegitaddmd} {hline 2} Creates a placeholder file in subfolders of a GitHub repository folder, which allows committing folder structures with empty folders.

{phang2}For a more descriptive discussion on the intended usage and work flow of this
command please see the {browse "https://dimewiki.worldbank.org/wiki/Iegitaddmd":DIME Wiki}.

{title:Syntax}

{phang} {cmdab:iegitaddmd} , {opt folder(file_path)} [{cmd:customfile(}{it:{help filename}}{cmd:)} {opt all} {opt skip} {opt replace}]

{marker opts}{...}
{synoptset 20}{...}
{synopthdr:options}
{synoptline}
{synopt :{opt folder(file_path)}}Specifies the folder path to the repository folder{p_end}
{synopt :{cmd:customfile(}{it:{help filename}}{cmd:)}}Specifies a file saved on disk that is used instead of the default file as placeholder{p_end}
{synopt :{cmd:all}}Creates the placeholder file in every subfolder of {opt folder()}, whether empty or not{p_end}
{synopt :{opt skip}}If option {opt all} is used and a folder has a file with same name as placeholder file, then nothing is done{p_end}
{synopt :{opt replace}}If option {opt all} is used and a folder has a file with same name as placeholder file, then the file is overwritten{p_end}
{synopt :{opt manual}}If option {opt manual} is used then the user is prompted before each placeholder file is created.{p_end}
{synoptline}

{marker desc}
{title:Description}

{pstd}GitHub does not sync empty folders, or folder that only contain ignored files.
	However, it is common in research projects
	that a folder structure is added to the GitHub repository at the beginning of a project. At
	the time the folder structure is added to the repository, several folders might still
	be empty and GitHub will not sync them, meaning that they will not be available to the full
	team. {cmd:iegitaddmd} is a Stata adaptation of {it:Solution B} in {browse "http://bytefreaks.net/gnulinux/bash/how-to-add-automatically-all-empty-folders-in-git-repository" :this post}.

{pstd}{cmd:iegitaddmd} creates a placeholder file in all empty subfolders of
	the folder specified in {opt folder()}. The default file used if no file is specified
	using option {opt customfile()} is called README.md, which is a name and format recognized by
	GitHub.com so that the content of the file is displayed if the folder with that file is
	browsed on GitHub.com. The placeholder file may be removed as
	soon as actual files have been added to the folder. Alternatively, if the option
	{opt all} is used, {cmd:iegitaddmd} will create the placeholder file in each subfolder
	of {opt folder()}, regardless of them being empty or not.

{marker optslong}
{title:Options}

{phang}{opt folder(file_path)} is the folder path to the project folder where the
	placeholder file will be created in each empty folder.

{phang}{cmd:file(}{it:{help filename}}{cmd:)} allows the user to specify a file saved on
	the computer to be used as the placeholder file	instead of the default README.md file. This
	allows people and organizations to write their own template placeholder files according to their own
	preferences. We recommend that a file of type .md (markdown) and name README.md is used as
	GitHub.com recognizes this name and format and will display the content of the file when someone
	browse to that folder on GitHub.com. But this is not a technical requirement, any file type
	and name can be used as placeholder file.

{phang}{opt all} creates the placeholder file in {opt folder()} and in every subfolder,
	regardless if they are empty or not. This allows the user to create a placeholder file in every
	folder that can be edited with documentation and instructions to the purpose and usage of
	each subfolder. This option can also be important when .{it:gitignore} is used, as {cmd:iegitaddmd} will not
	create files to subfolders that only has ignored file -- in which case the folder will not
	be synced by GitHub.

{phang}{opt skip} and {opt replace} tells {cmd:iegitaddmd} what to do if the option {opt all} is used
	and if any of the folders contain a file with the same name as the placeholder file the command
	is trying to create. If a file with the same name as the placeholder file exist and neither of these options
	are used, then the command will throw an error. If {opt skip} is used, then nothing is done in the
	folder where the file with the same name exists and the command proceeds to the next folder.
	If {opt replace} is used then the file with the same name is overwritten with the new placeholder
	file before the command proceeds to the next folder.

{phang}{opt manual} can be used to exactly control in which folders a placeholder file will be created. This
allows that this command is run on a the top folder of the repository, but then only selected folders get a placeholder.

{title:Example}

{pstd}{inp:global github_folder "C:\Users\JohnSmith\Documents\GitHub\ProjectA"}{break}{inp:iegitaddmd , folder({it:"$github_folder"})}

{pstd}In the example above, there is a GitHub repository in the folder ProjectA. This
	repository has a folder structure where some folders are still empty but will later
	be populated with files. In order to have all folders, even the empty ones, synced on all
	collaborators' cloned local copies of the repository, the folders need to contain at least
	one file, which is being created by the command.

{title:Acknowledgements}

{pstd}I would like to acknowledge the help in testing and proofreading I received in relation to this command and help file from (in alphabetic order):{p_end}
{pmore}Guadalupe Bedoya{break}Luiza Cardoso de Andrade{break}Mrijan Rimal{break}Benjamin Daniels{break}

{title:Author}

{phang}All commands in ietoolkit is developed by DIME Analytics at DECIE, The World Bank's unit for Development Impact Evaluations.

{phang}Main author: Kristoffer Bjarkefur, DIME Analytics, The World Bank Group

{phang}Please send bug-reports, suggestions and requests for clarifications
		 writing "ietoolkit iegitaddmd" in the subject line to:{break}
		 dimeanalytics@worldbank.org

{phang}You can also see the code, make comments to the code, see the version
		 history of the code, and submit additions or edits to the code through {browse "https://github.com/worldbank/ietoolkit":the GitHub repository of ietoolkit}.{p_end}


Bugfix ensurelib.ado

Bugfix ensurelib.ado

I have no idea what happened here. I tried to clean it while it was too hot outside, I guess.

/* ensurelib: edit the OS shared library path to ensure shared library dependencies will be found when Stata loads plugins.
 *
 * This allows you to bundle non-plugin DLLs, which you will have to do to create wrapper plugins
 * (unless you want to statically link, which is a almost always wrong).
 *
 * Nick Guenther <nguenthe@uwaterloo.ca>, June 2015.
 * BSD License.
 *
 * Example usage:
 * Suppose you have joesstore.plugin which is linked (dynamically) against library joesmeat and veggiegarden.
 * For Windows, OS X, and *nix joesmeat should be, respectively, compiled to joesmeat.dll, libjoesmeat.dylib,
 * or libjoesmeat.so, and similarly for veggiegarden. It should be distributed to users' adopaths with the
 * special *capitalized* .pkg commands
 *   G WIN joesmeat.dll
 *   G MACINTEL libjoesmeat.dylib
 *   G UNIX libjoesmeat.so
 * Then, in your code
 *   ensurelib joesmeat
 *   ensurelib veggiegarden
 *   program joesstore, plugin
 *
 *
 * libraryname should be as in your (gcc!) linker commandline: e.g. if you specify "-ljoesmeat" there, specific "joesmeat" here.
 * This will search your adopath for the file named
 *   Windows: libraryname.dll
 *   OS X:    liblibraryname.dylib
 *   *nix:    liblibraryname.so
 * and add the specific directory that file is in (e.g. C:\ado\plus\l\) to your shared library path
 *   Windows: %PATH%
 *   OS X:    $DYLD_LIBRARY_PATH
 *   *nix:    $LIBRARY_PATH
 * But if it does not find the library in your adopath, it will let the system use its usual library directories.
 *
 * Roughly, it is as if we have done:
 *   export LD_LIBARY_PATH=$ADOPATH:$LD_LIBRARY_PATH
 * but in a cross-platform way which also handles Stata's tricky alphabetical installation chunks ([M-5] adosubdir()).
 *
 * Since Stata usually includes "." in the adopath, you can use this during development as well:
 *   just keep the DLLs you plan to bundle in your working directory.
 *
 * We follow close to [MinGW's naming rules](http://www.mingw.org/wiki/specify_the_libraries_for_the_linker_to_use),
 * except that since we're only loading shared (not static) libraries, on Windows there is only one option just like the rest.
 * In particular from MinGW's rules, **if your library on Windows is uses the aberrant lib<name>.dll** you will must either:
 * - special-case your loading on Windows to call "ensurelib lib<name>"**,
 * - change the naming scheme of the .dll to conform to Windows standard: <name>.dll.
 * This problem generally only comes up with libraries that have been ported carelessly from *nix.
 *
 * Works on Windows, OS X, and Linux (which are the only platforms Stata supports)
 *
 * Dependencies:
 *  _setenv.plugin
 *  _getenv.plugin (Stata provides the "environment" macro function for read-only env access,
 *                  but it doesn't seem to be live: it just caches the env at boot, not expecting it to be edited)
 *
 * TODO:
 * [ ] Pull this into a separate .pkg
 *     Stata has, essentially, a global install namespace and no dependency tracking.
 *     So what happens if two packages bundle this? Does the second overwrite the first?
 *     Get denied? Mysteriously break the first one? And what happens if one package uninstalls?
 * [ ] Is this worth factoring further? maybe "prependpath" could come out?
 */

program _getenv, plugin
program _setenv, plugin
program _dlopenable, plugin

program define ensurelib
  gettoken libname 0 : 0
  if("`libname'"=="") {
    di as error "ensurelib: argument required"
    exit 1
  }
  syntax , []/* disallow everything else */

  /* platform-settings */
  // libvar == platform specific environment variable that can be edited (there may be more than one option)
  // sep    == platform specific path separator
  // dl{prefix,ext} == what to wrap the libname in to generate the library filename
  if("`c(os)'"=="Windows") {
    local libvar = "PATH"
    local sep = ";"
    local dlprefix = ""
    local dlext = "dll"
  }
  else if("`c(os)'"=="MacOSX") {
    local libvar = "DYLD_LIBRARY_PATH" /* or is this DYLD_FALLBACK_LIBRARY_PATH ?? */
    local sep = ":"
    local dlprefix = "lib"
    local dlext = "dylib"
  }
  else if("`c(os)'"=="Unix") { //i.e. Linux, and on Linux really only like Fedora and Ubuntu; Stata doesn't test builds for others.
    local libvar = "LD_LIBRARY_PATH"
    local sep = ":"
    local dlprefix = "lib"
    local dlext = "so"
  }
  else {
    di as error "ensurelib: Unsupported OS `c(os)'"
    exit 1
  }

  /* wrap the library name into a file name */
  local lib = "`dlprefix'`libname'.`dlext'"

  di as txt "looking for `lib'"

  /* If the lib is in the adopath, prepend its path to the system library path */
  capture quietly findfile "`lib'"
  if(_rc==0) {
    di as txt "addddindg to path"
    /* the path to the library on the adopath */
    local adolib = "`r(fn)'"

    /* extract the directory from the file path */
    mata pathsplit("`adolib'",adopath="",lib="") //_Stata_ doesn't have pathname manipulation, but _mata_ does. the ="" are to declare variables (variables need to be declared before use, even if they are just for output)
    mata st_local("adopath",adopath)  // getting values out of mata to Stata is inconsistent: numerics in r() go through st_numscalar(), strings have to go through st_global(), however non-r() scalars have to go through st_strscalar
    mata st_global("lib",lib)

    /* prepend the discovered library path (adopath) to the system library path (libvar) */
    // get the current value of libvar into libpath
    plugin call _getenv, "`libvar'"
    local libpath = "`_getenv'"

    // skip prepending if adopath is already there in `libvar', to prevent explosion
    local k = ustrpos("`libpath'", "`adopath'")
    if(`k' == 0) {
      // prepend
      plugin call _setenv, "`libvar'" "`adopath'`sep'`libpath'"
    }
  }
  /* Check that the library is now loadable */
  /* by checking here, we prevent Stata's "unable to load [...].plugin" with an error which points out the actual problem. */
  capture plugin call _dlopenable, "`lib'"
  if(_rc!=0) {
    di as error "ensurelib: unable to load `libname'"
    exit _rc
  }

end

/* ensurelib: edit the OS shared library path to ensure shared library dependencies will be found when Stata loads plugins.
 *
 * This allows you to bundle non-plugin DLLs, which you will have to do to create wrapper plugins
 * (unless you want to statically link, which is a almost always wrong).
 *
 * Nick Guenther <nguenthe@uwaterloo.ca>, June 2015.
 * BSD License.
 *
 * Example usage:
 * Suppose you have joesstore.plugin which is linked (dynamically) against library joesmeat and veggiegarden.
 * For Windows, OS X, and *nix joesmeat should be, respectively, compiled to joesmeat.dll, libjoesmeat.dylib,
 * or libjoesmeat.so, and similarly for veggiegarden. It should be distributed to users' adopaths with the
 * special *capitalized* .pkg commands
 *   G WIN joesmeat.dll
 *   G MACINTEL libjoesmeat.dylib
 *   G UNIX libjoesmeat.so
 * Then, in your code
 *   ensurelib joesmeat
 *   ensurelib veggiegarden
 *   program joesstore, plugin
 *
 *
 * libraryname should be as in your (gcc!) linker commandline: e.g. if you specify "-ljoesmeat" there, specific "joesmeat" here.
 * This will search your adopath for the file named
 *   Windows: libraryname.dll
 *   OS X:    liblibraryname.dylib
 *   *nix:    liblibraryname.so
 * and add the specific directory that file is in (e.g. C:\ado\plus\l\) to your shared library path
 *   Windows: %PATH%
 *   OS X:    $DYLD_LIBRARY_PATH
 *   *nix:    $LIBRARY_PATH
 * But if it does not find the library in your adopath, it will let the system use its usual library directories.
 *
 * Roughly, it is as if we have done:
 *   export LD_LIBARY_PATH=$ADOPATH:$LD_LIBRARY_PATH
 * but in a cross-platform way which also handles Stata's tricky alphabetical installation chunks ([M-5] adosubdir()).
 *
 * Since Stata usually includes "." in the adopath, you can use this during development as well:
 *   just keep the DLLs you plan to bundle in your working directory.
 *
 * We follow close to [MinGW's naming rules](http://www.mingw.org/wiki/specify_the_libraries_for_the_linker_to_use),
 * except that since we're only loading shared (not static) libraries, on Windows there is only one option just like the rest.
 * In particular from MinGW's rules, **if your library on Windows is uses the aberrant lib<name>.dll** you will must either:
 * - special-case your loading on Windows to call "ensurelib lib<name>"**,
 * - change the naming scheme of the .dll to conform to Windows standard: <name>.dll.
 * This problem generally only comes up with libraries that have been ported carelessly from *nix.
 *
 * Works on Windows, OS X, and Linux (which are the only platforms Stata supports)
 *
 * Dependencies:
 *  _setenv.plugin
 *  _getenv.plugin (Stata provides the "environment" macro function for read-only env access,
 *                  but it doesn't seem to be live: it just caches the env at boot, not expecting it to be edited)
 *
 * TODO:
 * [ ] Pull this into a separate .pkg
 *     Stata has, essentially, a global install namespace and no dependency tracking.
 *     So what happens if two packages bundle this? Does the second overwrite the first?
 *     Get denied? Mysteriously break the first one? And what happens if one package uninstalls?
 * [ ] Is this worth factoring further? maybe "prependpath" could come out?
 */

program _getenv, plugin
program _setenv, plugin
program _dlopenable, plugin

program define ensurelib
  gettoken libname 0 : 0
  if("`libname'"=="") {
    di as error "ensurelib: argument required"
    exit 1
  }
  syntax , []/* disallow everything else */

  /* platform-settings */
  // libvar == platform specific environment variable that can be edited (there may be more than one option)
  // sep    == platform specific path separator
  // dl{prefix,ext} == what to wrap the libname in to generate the library filename
  if("`c(os)'"=="Windows") {
    local libvar = "PATH"
    local sep = ";"
    local dlprefix = ""
    local dlext = "dll"
  }
  else if("`c(os)'"=="MacOSX") {
    local libvar = "DYLD_LIBRARY_PATH" /* or is this DYLD_FALLBACK_LIBRARY_PATH ?? */
    local sep = ":"
    local dlprefix = "lib"
    local dlext = "dylib"
  }
  else if("`c(os)'"=="Unix") { //i.e. Linux, and on Linux really only like Fedora and Ubuntu; Stata doesn't test builds for others.
    local libvar = "LD_LIBRARY_PATH"
    local sep = ":"
    local dlprefix = "lib"
    local dlext = "so"
  }
  else {
    di as error "ensurelib: Unsupported OS `c(os)'"
    exit 1
  }

  /* wrap the library name into a file name */
  local lib = "`dlprefix'`libname'.`dlext'"

  /* If the lib is in the adopath, prepend its path to the system library path */
  capture quietly findfile "`lib'"
  if(_rc==0) {
    /* the path to the library on the adopath */
    local adolib = "`r(fn)'"

    /* extract the directory from the file path */
    mata pathsplit("`lib'",adopath="",lib="") //_Stata_ doesn't have pathname manipulation, but _mata_ does. the ="" are to declare variables (variables need to be declared before use, even if they are just for output)
    mata st_global("r(adopath)",adopath)  // getting values out of mata to Stata is inconsistent: numerics in r() go through st_numscalar(), strings have to go through st_global(), however non-r() scalars have to go through st_strscalar
    mata st_global("r(lib)",lib)

    /* prepend the discovered library path (r(adopath)) to the system library path (libvar) */
    // get the current adopath
    plugin call _getenv, "`libvar'"
    local libpath = "`_getenv'"

    // skip prepending if adopath is already there in `libvar', to prevent explosion
    local k = ustrpos("`r(libpath)'", "`r(adopath)'")
    if(`k' == 0) {
      // prepend
      plugin call _setenv, "`libvar'" "`r(adopath)'`sep'`libpath'"
    }
  }
  /* Check that the library is now loadable */
  /* by checking here, we prevent Stata's "unable to load [...].plugin" with an error which points out the actual problem. */
  capture plugin call _dlopenable, "`lib'"
  if(_rc!=0) {
    di as error "ensurelib: unable to load `libname'"
    exit _rc
  }

end


[iegitaddmd] add manual option

[iegitaddmd] add manual option

*! version 6.2 31JAN2019 DIME Analytics dimeanalytics@worldbank.org

cap program drop   iegitaddmd
	program define iegitaddmd

qui {

		syntax , folder(string) [customfile(string) all skip replace manual]

		/******************************
		*******************************
			Test user input
		*******************************
		******************************/

		******************************
		*	Test input: folder

		*Test that folder exist
		mata : st_numscalar("r(dirExist)", direxists("`folder'"))

		if (`r(dirExist)' == 0) | (length("`folder'")<=10) {

			noi di as error `"{phang}The "`folder'" folder does not exist or you have not entered the full path. For example, full paths on most Windows computers it starts with {it:C:/} and on most Mac computers with {it:/user/}. Important: Specify the whole file path to the repository folder, not just {it:C:/} or {it:/user/} as that would create the placeholder file in every empty folder on your computer!{p_end}"'
			error 693
			exit
		}

		* File paths can have both forward and/or back slash. We'll standardize them so they're easier to handle
		local folderStd	= subinstr("`folder'","\","/",.)

		******************************
		*	Test input: customfile

		*Test that file exist if not using default file
		if "`customfile'" != "" {
			*File option used test if file exists
			capture confirm file "`customfile'"
			if _rc {
				*File does not exist, throw error
				noi di as error `"{phang}File "`customfile'" was not found. Remember that you must enter the full path. For example, on most Windows computers it starts with {it:C:/} and on most Mac computers with {it:/user/}.{p_end}"'
				error 693
				exit
			}

			* Get the name of file (include path to keep )
			* File paths can have both forward and/or back slash. We'll standardize them so they're easier to handle
			local customFileStd	= subinstr("`customfile'","\","/",.)
			*Find the last slash in the file name
			local lastSlash = strpos(strreverse(`"`customFileStd'"'),"/")
			*Use that position to get the file name. Multiply with minus one as we count from the back
			local customFileName = substr(`"`customFileStd'"', (-1 * `lastSlash') ,.)
			*Used for the recursive call of the command when there is a subfolder
			local customFileRecurse `"customfile(`customFileStd')"'

			*Path and name of thile regardless if customfile were used
			local newPlaceholderFile `"`folderStd'`customFileName'"'
		}
		else {
			*Path and name of thile regardless if customfile were not used
			local newPlaceholderFile `"`folderStd'/README.md"'
		}

		******************************
		*	Test input: skip & replace

		*Options skip and replace cannot be used together
		if "`skip'" != "" & "`replace'" != "" {
			noi di as error `"{phang}The options skip and replace may not be used together.{p_end}"'
			error 198
			exit
		}

		/******************************
		*******************************
			Execute command
		*******************************
		******************************/

		******************************
		*	List all files and folders

		*List files, directories and other files
		local flist : dir `"`folderStd'"' files "*"	, respectcase
		local dlist : dir `"`folderStd'"' dirs  "*" , respectcase
		local olist : dir `"`folderStd'"' other "*"	, respectcase

		******************************
		*	Call command recursively on all sub-folders

		*Use the command on each subfolder to this folder (if any)
		foreach dir of local dlist {
			*Recursive call on each subfolder
			noi iegitaddmd , folder(`"`folderStd'/`dir'"') `all' `customFileRecurse' `skip' `replace' `manual'
		}

		******************************
		*	Evaluate if file will be crated in this folder

		*Test if all of those lists are empty, meaning there are
		* no folders or files in this folder
		if `"`flist'`dlist'`olist'"' == "" noi writeDefaultPlaceholder, newfileinclone(`"`newPlaceholderFile'"') customfile(`"`customFileStd'"') `manual'

		*If the folder is not empty, test if option all were used.
		else if ("`all'" == "all") {

				cap confirm file `"`newPlaceholderFile'"'

				* No file with this name exists in this folder, create file without further ado
				if _rc != 0 noi writeDefaultPlaceholder, newfileinclone(`"`newPlaceholderFile'"') customfile(`"`customFileStd'"') `manual'

				* File exist, but no sintructions on how to deal with this has been given, throw error
				else if missing("`skip'") & missing("`replace'")  {
					noi di as error `"{phang}The file  `newPlaceholderFile' already exists. Either remove option {it:all} or use either option {it:skip} or {it:replace}. See help file before using either of these options unless you are already familiar with them.{p_end}"'
					error 602
				}

				* File exist, and instruction is to replace, create files and overwrite as needed
				else if !missing("`replace'") noi writeDefaultPlaceholder, newfileinclone(`"`newPlaceholderFile'"') customfile(`"`customFileStd'"') `manual'

				* File exist, and instruction is to skip, do nothing
				else if !missing("`skip'") {
						*Nothing is done, this if-block is only included for readability and completion
				}

				* The code should nevere get to this point
				else  {
					noi di as error `"{phang}Coding error in if-chain in "All" block.Please report this error to dimeanalytics@worldbank.org or here: https://github.com/worldbank/ietoolkit/issues/new{p_end}"'
					error 602
				}

		}
}

end

	*Write a README.md file when iegitaddmd finds an empty folder
cap program drop writeDefaultPlaceholder
program define   writeDefaultPlaceholder

qui {

	syntax , newfileinclone(string) [customfile(string) manual]

	*Get the current folder name from newfileinclone
	local lastSlash = strpos(strreverse(`"`newfileinclone'"'),"/")
	local folder = substr(`"`newfileinclone'"',1,strlen("`newfileinclone'")-`lastSlash')
	local fileName = substr(`"`newfileinclone'"', (-1 * `lastSlash')+1 ,.)

	*If manual was used, get manual confirmation for each file
	if !missing("`manual'") {
		noi di ""
		global confirmation "" //Reset global

		*Keep aslking for input until the input is either Y, y, N, n or BREAK
		while (upper("${confirmation}") != "Y" & upper("${confirmation}") != "N" & "${confirmation}" != "BREAK") {
		  noi di as txt "{pstd}You are about to create a file [`fileName'] in the folder [`folder']. Do you want to do that? To confirm type {bf:Y} and hit enter, to abort type {bf:N} and hit enter. Type {bf:BREAK} and hit enter to stop the code.{p_end}", _request(confirmation)
		}
		*Copy user input to local
		local createfile = upper("${confirmation}")
		* If user wrote "BREAK" then exit the code
		if ("`createfile'" == "BREAK") error 1
	}

	*If "manual" were used and input was Y or if manual was not used, create the file
	if ("`createfile'" == "Y") | (missing("`manual'")) {

		*Copy custom file if custom file is used
		if !missing(`"`customfile'"') copy "`customfile'" `"`newfileinclone'"', replace
		*Custom file is not used, so cretae defeault file
		else {
			*Create file
			tempname 	newHandle
			cap file close 	`newHandle'
			file open  	`newHandle' using "`newfileinclone'", text write replace
			*Write the content to the file
			file write  `newHandle' ///
				"# Placeholder file" _n _n ///
				"This file has been created automatically by the command **iegitaddmd** from the Stata package [**ietoolkit**](https://worldbank.github.io/ietoolkit) to make GitHub sync this folder. GitHub does not sync empty folders or folders that only contain ignored files, but in research projects it is often important to share the full standardized folder structure along with the actual files. This command is intended to be used with **iefolder**, but it can be used in any folder structure intended to be shared on GitHub." _n _n ///
				"In recently started projects, it is typical to create data folders, script folders (do-files, r-files) and output folders, among others. The output folders are initially empty, but the script files might include a file path to them for later use. If an output folder is empty and another collaborator clones the repository, then the output folder expected by the scripts will not be included by GitHub in the cloned repository, and the script will not run properly." _n _n ///
				"## You should replace the content of this placeholder file" _n _n ///
				"The text in this file should be replaced with text that describes the intended use of this folder. This file is written in markdown (.md) format, which is suitable for GitHub syncing (unlike .doc/.docx). If the file is named *README.md*, GitHub automatically displays its contents when someone opens the containing folder on GitHub.com using a web browser." _n _n ///
				"If you are new to markup languages (markdown, html etc.) then this [Markdown Tutorial](https://www.markdowntutorial.com/) is a great place to start. If you have some experience with markup languages, then this [Markdown Cheat Sheet](https://guides.github.com/pdfs/markdown-cheatsheet-online.pdf) is a great place to start." _n _n ///
				"## Add similar files in other folders" _n _n ///
				"The Stata command **iegitaddmd** does not add anything to folders that already have content unless this is explicitly requested using the option `all`. It is best practice to create a *README.md* file in any folders that have content, for example, in folders whose purpose might not obvious to someone using the repository for the first time. Again, if the file is named *README.md*, then the content of the file will be shown in the browser when someone explores the repository on GitHub.com." _n _n ///
				"Another great use of a *README.md* file is to use it as a documentation on how the folder it sits in and its subfolders are organized,  where its content can be found, and where new content is meant to be saved. For example, if you have a folder called `/Baseline/`, then you can give a short description of the activities conducted during the baseline and where data, scripts and outputs related to it can be found." _n _n ///
				"## Removing this file" _n _n ///
				"Removing this file is not recommended, as GitHub may stop syncing the parent folder unless the folder now has other content. However, even when content is added and the file can be removed without breaking the GitHub functionality, our recommendation is to replace the content with more relevant content rather than deleting it." _n _n

			*Closing the file
			file close 		`newHandle'

		}
		*Uoutput that the file was created
		noi di as result "{pstd}File [`newfileinclone'] created.{p_end}"
	}
	*Manual was used and input was N, no file were creaetd
	else noi di as result "{pstd}No file created.{p_end}"
}
end

*! version 6.2 31JAN2019 DIME Analytics dimeanalytics@worldbank.org

cap program drop   iegitaddmd
	program define iegitaddmd

qui {

		syntax , folder(string) [customfile(string) all skip replace]

		/******************************
		*******************************
			Test user input
		*******************************
		******************************/

		******************************
		*	Test input: folder

		*Test that folder exist
		mata : st_numscalar("r(dirExist)", direxists("`folder'"))

		if (`r(dirExist)' == 0) | (length("`folder'")<=10) {

			noi di as error `"{phang}The "`folder'" folder does not exist or you have not entered the full path. For example, full paths on most Windows computers it starts with {it:C:/} and on most Mac computers with {it:/user/}. Important: Specify the whole file path to the repository folder, not just {it:C:/} or {it:/user/} as that would create the placeholder file in every empty folder on your computer!{p_end}"'
			error 693
			exit
		}

		* File paths can have both forward and/or back slash. We'll standardize them so they're easier to handle
		local folderStd	= subinstr("`folder'","\","/",.)

		******************************
		*	Test input: customfile

		*Test that file exist if not using default file
		if "`customfile'" != "" {
			*File option used test if file exists
			capture confirm file "`customfile'"
			if _rc {
				*File does not exist, throw error
				noi di as error `"{phang}File "`customfile'" was not found. Remember that you must enter the full path. For example, on most Windows computers it starts with {it:C:/} and on most Mac computers with {it:/user/}.{p_end}"'
				error 693
				exit
			}

			* Get the name of file (include path to keep )
			* File paths can have both forward and/or back slash. We'll standardize them so they're easier to handle
			local customFileStd	= subinstr("`customfile'","\","/",.)
			*Find the last slash in the file name
			local lastSlash = strpos(strreverse(`"`customFileStd'"'),"/")
			*Use that position to get the file name. Multiply with minus one as we count from the back
			local customFileName = substr(`"`customFileStd'"', (-1 * `lastSlash') ,.)
			*Used for the recursive call of the command when there is a subfolder
			local customFileRecurse `"customfile(`customFileStd')"'

			*Path and name of thile regardless if customfile were used
			local newPlaceholderFile `"`folderStd'`customFileName'"'
		}
		else {
			*Path and name of thile regardless if customfile were not used
			local newPlaceholderFile `"`folderStd'/README.md"'
		}

		******************************
		*	Test input: skip & replace

		*Options skip and replace cannot be used together
		if "`skip'" != "" & "`replace'" != "" {
			noi di as error `"{phang}The options skip and replace may not be used together.{p_end}"'
			error 198
			exit
		}

		/******************************
		*******************************
			Execute command
		*******************************
		******************************/

		******************************
		*	List all files and folders

		*List files, directories and other files
		local flist : dir `"`folderStd'"' files "*"	, respectcase
		local dlist : dir `"`folderStd'"' dirs  "*" , respectcase
		local olist : dir `"`folderStd'"' other "*"	, respectcase

		******************************
		*	Call command recursively on all sub-folders

		*Use the command on each subfolder to this folder (if any)
		foreach dir of local dlist {
			*Recursive call on each subfolder
			noi iegitaddmd , folder(`"`folderStd'/`dir'"') `all' `customFileRecurse' `skip' `replace'
		}

		******************************
		*	Evaluate if file will be crated in this folder

		*Test if all of those lists are empty, meaning there are
		* no folders or files in this folder
		if `"`flist'`dlist'`olist'"' == "" {

			*If custom file was specified, you copy that one to empt folder
			if "`customFileStd'" != "" copy "`customFileStd'" `"`newPlaceholderFile'"', replace
			*No custom file so write default README.md file
			else writeDefaultPlaceholder `"`newPlaceholderFile'"'
		}

		*If the folder is not empty, test if option all were used.
		else if ("`all'" == "all") {

				* No file with this name exists in this folder, create file without further ado
				if _rc != 0 {
					*If custom file was specified, you copy that one to empt folder
					if "`customFileStd'" != "" copy "`customFileStd'" `"`newPlaceholderFile'"', replace
					*No custom file so write default README.md file
					else writeDefaultPlaceholder `"`newPlaceholderFile'"'
				}

				* File exist, but no sintructions on how to deal with this has been given, throw error
				else if missing("`skip'") & missing("`replace'")  {
					noi di as error `"{phang}The file  `newPlaceholderFile' already exists. Either remove option {it:all} or use either option {it:skip} or {it:replace}. See help file before using either of these options unless you are already familiar with them.{p_end}"'
					error 602
				}

				* File exist, and instruction is to replace, create files and overwrite as needed
				else if !missing("`replace'") {
					*If custom file was specified, you copy that one to empt folder
					if "`customFileStd'" != "" copy "`customFileStd'" `"`newPlaceholderFile'"', replace
					*No custom file so write default README.md file
					else writeDefaultPlaceholder `"`newPlaceholderFile'"'
				}

				* File exist, and instruction is to skip, do nothing
				else if !missing("`skip'") {
						*Nothing is done, this if-block is only included for readability and completion
				}

				* The code should nevere get to this point
				else  {
					noi di as error `"{phang}Coding error in if-chain in "All" block.Please report this error to dimeanalytics@worldbank.org or here: https://github.com/worldbank/ietoolkit/issues/new{p_end}"'
					error 602
				}

		}
}

end

	*Write a README.md file when iegitaddmd finds an empty folder
	cap program drop writeDefaultPlaceholder
	program define   writeDefaultPlaceholder

		args newplaceholderfile

		*Create file
		tempname 	newHandle
		cap file close 	`newHandle'
		file open  	`newHandle' using "`newplaceholderfile'", text write replace

		*Add some text to the file
		file write  `newHandle' ///
			"# Placeholder file" _n _n ///
			"This file has been created automatically by the command **iegitaddmd** from the Stata package [**ietoolkit**](https://worldbank.github.io/ietoolkit) to make GitHub sync this folder. GitHub does not sync empty folders or folders that only contain ignored files, but in research projects it is often important to share the full standardized folder structure along with the actual files. This command is intended to be used with **iefolder**, but it can be used in any folder structure intended to be shared on GitHub." _n _n ///
			"In recently started projects, it is typical to create data folders, script folders (do-files, r-files) and output folders, among others. The output folders are initially empty, but the script files might include a file path to them for later use. If an output folder is empty and another collaborator clones the repository, then the output folder expected by the scripts will not be included by GitHub in the cloned repository, and the script will not run properly." _n _n ///
			"## You should replace the content of this placeholder file" _n _n ///
			"The text in this file should be replaced with text that describes the intended use of this folder. This file is written in markdown (.md) format, which is suitable for GitHub syncing (unlike .doc/.docx). If the file is named *README.md*, GitHub automatically displays its contents when someone opens the containing folder on GitHub.com using a web browser." _n _n ///
			"If you are new to markup languages (markdown, html etc.) then this [Markdown Tutorial](https://www.markdowntutorial.com/) is a great place to start. If you have some experience with markup languages, then this [Markdown Cheat Sheet](https://guides.github.com/pdfs/markdown-cheatsheet-online.pdf) is a great place to start." _n _n ///
			"## Add similar files in other folders" _n _n ///
			"The Stata command **iegitaddmd** does not add anything to folders that already have content unless this is explicitly requested using the option `all`. It is best practice to create a *README.md* file in any folders that have content, for example, in folders whose purpose might not obvious to someone using the repository for the first time. Again, if the file is named *README.md*, then the content of the file will be shown in the browser when someone explores the repository on GitHub.com." _n _n ///
			"Another great use of a *README.md* file is to use it as a documentation on how the folder it sits in and its subfolders are organized,  where its content can be found, and where new content is meant to be saved. For example, if you have a folder called `/Baseline/`, then you can give a short description of the activities conducted during the baseline and where data, scripts and outputs related to it can be found." _n _n ///
			"## Removing this file" _n _n ///
			"Removing this file is not recommended, as GitHub may stop syncing the parent folder unless the folder now has other content. However, even when content is added and the file can be removed without breaking the GitHub functionality, our recommendation is to replace the content with more relevant content rather than deleting it." _n _n

		*Closing the file
		file close 		`newHandle'
end