33
33
import urllib2
34
34
import zipfile
35
35
import argparse
36
+ import tempfile
36
37
37
38
38
39
# Application version
39
- ver = '0.9.10 '
40
+ ver = '1.0.0 '
40
41
41
42
# Default paths to Mercurial and Git
42
43
hg_cmd = 'hg'
121
122
verbose = False
122
123
very_verbose = False
123
124
install_requirements = True
125
+ cache_repositories = True
124
126
125
127
# stores current working directory for recursive operations
126
128
cwd_root = ""
@@ -264,10 +266,19 @@ def init(path):
264
266
if not os .path .exists (path ):
265
267
os .mkdir (path )
266
268
269
+ def cleanup ():
270
+ info ("Cleaning up library build folder" )
271
+ for fl in os .listdir ('.' ):
272
+ if not fl .startswith ('.' ):
273
+ if os .path .isfile (fl ):
274
+ os .remove (fl )
275
+ else :
276
+ shutil .rmtree (fl )
277
+
267
278
def clone (url , path = None , depth = None , protocol = None ):
268
279
m = Bld .isurl (url )
269
280
if not m :
270
- raise ProcessException (1 , "Not an mbed library build URL" )
281
+ raise ProcessException (1 , "Not a library build URL" )
271
282
272
283
try :
273
284
Bld .init (path )
@@ -277,60 +288,51 @@ def clone(url, path=None, depth=None, protocol=None):
277
288
error (e [1 ], e [0 ])
278
289
279
290
def fetch_rev (url , rev ):
280
- tmp_file = os .path .join ('.' + Bld .name , '.rev-' + rev + '.zip' )
281
- arch_dir = 'mbed-' + rev
291
+ rev_file = os .path .join ('.' + Bld .name , '.rev-' + rev + '.zip' )
282
292
try :
283
- if not os .path .exists (tmp_file ):
284
- action ("Downloading mbed library build \" %s\" (might take a minute)" % rev )
285
- outfd = open (tmp_file , 'wb' )
293
+ if not os .path .exists (rev_file ):
294
+ action ("Downloading library build \" %s\" (might take a minute)" % rev )
295
+ outfd = open (rev_file , 'wb' )
286
296
inurl = urllib2 .urlopen (url )
287
297
outfd .write (inurl .read ())
288
298
outfd .close ()
289
299
except :
290
- if os .path .isfile (tmp_file ):
291
- os .remove (tmp_file )
300
+ if os .path .isfile (rev_file ):
301
+ os .remove (rev_file )
292
302
raise Exception (128 , "Download failed!\n Please try again later." )
293
303
304
+ def unpack_rev (rev ):
305
+ rev_file = os .path .join ('.' + Bld .name , '.rev-' + rev + '.zip' )
294
306
try :
295
- with zipfile .ZipFile (tmp_file ) as zf :
296
- action ("Unpacking mbed library build \" %s\" in \" %s\" " % (rev , os .getcwd ()))
297
- zf .extractall ()
307
+ with zipfile .ZipFile (rev_file ) as zf :
308
+ action ("Unpacking library build \" %s\" in \" %s\" " % (rev , os .getcwd ()))
309
+ zf .extractall ('.' )
298
310
except :
299
- if os .path .isfile (tmp_file ):
300
- os .remove (tmp_file )
301
- if os .path .isfile (arch_dir ):
302
- rmtree_readonly (arch_dir )
303
- raise Exception (128 , "An error occurred while unpacking mbed library archive \" %s\" in \" %s\" " % (tmp_file , os .getcwd ()))
311
+ if os .path .isfile (rev_file ):
312
+ os .remove (rev_file )
313
+ raise Exception (128 , "An error occurred while unpacking library archive \" %s\" in \" %s\" " % (rev_file , os .getcwd ()))
304
314
305
315
def checkout (rev , clean = False ):
306
316
url = Bld .geturl ()
307
317
m = Bld .isurl (url )
308
318
if not m :
309
- raise ProcessException (1 , "Not an mbed library build URL" )
319
+ raise ProcessException (1 , "Not a library build URL" )
310
320
rev = Hg .remoteid (m .group (1 ), rev )
311
321
if not rev :
312
- error ("Unable to fetch late mbed library revision" )
313
-
314
- if rev != Bld .getrev ():
315
- info ("Cleaning up library build folder" )
316
- for fl in os .listdir ('.' ):
317
- if not fl .startswith ('.' ):
318
- if os .path .isfile (fl ):
319
- os .remove (fl )
320
- else :
321
- shutil .rmtree (fl )
322
+ error ("Unable to fetch library build information" )
323
+
324
+ arch_url = m .group (1 ) + '/archive/' + rev + '.zip'
325
+ Bld .fetch_rev (arch_url , rev )
326
+
327
+ if rev != Bld .getrev () or clean :
328
+ Bld .cleanup ()
322
329
323
330
info ("Checkout \" %s\" in %s" % (rev , os .path .basename (os .getcwd ())))
324
- arch_url = m .group (1 ) + '/archive/' + rev + '.zip'
325
- arch_dir = m .group (7 ) + '-' + rev
326
331
try :
327
- if not os . path . exists ( arch_dir ):
328
- Bld .fetch_rev ( arch_url , rev )
332
+ Bld . unpack_rev ( rev )
333
+ Bld .seturl ( url + '/' + rev )
329
334
except Exception as e :
330
- if os .path .exists (arch_dir ):
331
- rmtree_readonly (arch_dir )
332
335
error (e [1 ], e [0 ])
333
- Bld .seturl (url + '/' + rev )
334
336
335
337
def update (rev = None , clean = False , clean_files = False , is_local = False ):
336
338
return Bld .checkout (rev , clean )
@@ -339,6 +341,7 @@ def untracked():
339
341
return ""
340
342
341
343
def seturl (url ):
344
+ info ("Setting url to \" %s\" in %s" % (url , os .getcwd ()))
342
345
if not os .path .exists ('.' + Bld .name ):
343
346
os .mkdir ('.' + Bld .name )
344
347
@@ -382,6 +385,9 @@ def isurl(url):
382
385
def init (path = None ):
383
386
popen ([hg_cmd , 'init' ] + ([path ] if path else []) + (['-v' ] if very_verbose else ([] if verbose else ['-q' ])))
384
387
388
+ def cleanup ():
389
+ return True
390
+
385
391
def clone (url , name = None , depth = None , protocol = None ):
386
392
popen ([hg_cmd , 'clone' , formaturl (url , protocol ), name ] + (['-v' ] if very_verbose else ([] if verbose else ['-q' ])))
387
393
@@ -445,11 +451,36 @@ def outgoing():
445
451
raise e
446
452
return 0
447
453
454
+ def seturl (url ):
455
+ info ("Setting url to \" %s\" in %s" % (url , os .getcwd ()))
456
+ hgrc = os .path .join ('.hg' , 'hgrc' )
457
+ tagpaths = '[paths]'
458
+ remote = 'default'
459
+ lines = []
460
+
461
+ try :
462
+ with open (hgrc ) as f :
463
+ lines = f .read ().splitlines ()
464
+ except IOError :
465
+ pass
466
+
467
+ if tagpaths in lines :
468
+ idx = lines .index (tagpaths )
469
+ m = re .match (r'^([\w_]+)\s*=\s*(.*)$' , lines [idx + 1 ])
470
+ if m :
471
+ remote = m .group (1 )
472
+ del lines [idx + 1 ]
473
+ lines .insert (idx , remote + ' = ' + url )
474
+ else :
475
+ lines .append (tagpaths )
476
+ lines .append (remote + ' = ' + url )
477
+
448
478
def geturl ():
449
479
tagpaths = '[paths]'
450
480
default_url = ''
451
481
url = ''
452
- if os .path .isfile (os .path .join ('.hg' , 'hgrc' )):
482
+
483
+ try :
453
484
with open (os .path .join ('.hg' , 'hgrc' )) as f :
454
485
lines = f .read ().splitlines ()
455
486
if tagpaths in lines :
@@ -460,8 +491,11 @@ def geturl():
460
491
default_url = m .group (2 )
461
492
else :
462
493
url = m .group (2 )
463
- if default_url :
464
- url = default_url
494
+ except IOError :
495
+ pass
496
+
497
+ if default_url :
498
+ url = default_url
465
499
466
500
return formaturl (url or pquery ([hg_cmd , 'paths' , 'default' ]).strip ())
467
501
@@ -551,6 +585,11 @@ def isurl(url):
551
585
def init (path = None ):
552
586
popen ([git_cmd , 'init' ] + ([path ] if path else []) + ([] if very_verbose else ['-q' ]))
553
587
588
+ def cleanup ():
589
+ info ("Cleaning up Git index" )
590
+ if os .path .exists (os .path .join ('.git' , 'logs' )):
591
+ rmtree_readonly (os .path .join ('.git' , 'logs' ))
592
+
554
593
def clone (url , name = None , depth = None , protocol = None ):
555
594
popen ([git_cmd , 'clone' , formaturl (url , protocol ), name ] + (['--depth' , depth ] if depth else []) + (['-v' ] if very_verbose else ([] if verbose else ['-q' ])))
556
595
@@ -623,10 +662,10 @@ def checkout(rev, clean=False):
623
662
popen ([git_cmd , 'checkout' , rev ] + (['-f' ] if clean else []) + ([] if very_verbose else ['-q' ]))
624
663
625
664
def update (rev = None , clean = False , clean_files = False , is_local = False ):
626
- if clean :
627
- Git .discard (clean_files )
628
665
if not is_local :
629
666
Git .fetch ()
667
+ if clean :
668
+ Git .discard (clean_files )
630
669
if rev :
631
670
Git .checkout (rev , clean )
632
671
else :
@@ -638,11 +677,11 @@ def update(rev=None, clean=False, clean_files=False, is_local=False):
638
677
except ProcessException :
639
678
pass
640
679
else :
641
- err = "Unable to update \" %s\" in \" %s\" .\n " % (os .path .basename (os .getcwd ()), os .getcwd ())
680
+ err = "Unable to update \" %s\" in \" %s\" ." % (os .path .basename (os .getcwd ()), os .getcwd ())
642
681
if not remote :
643
- info (err + "The local repository is not associated with a remote one." )
682
+ info (err + " The local repository is not associated with a remote one." )
644
683
if not branch :
645
- info (err + "Working set is not on a branch." )
684
+ info (err + " Working set is not on a branch." )
646
685
647
686
def status ():
648
687
return pquery ([git_cmd , 'status' , '-s' ] + (['-v' ] if very_verbose else []))
@@ -698,6 +737,10 @@ def getremotes(rtype='fetch'):
698
737
result .append ([remote [0 ], remote [1 ], t ])
699
738
return result
700
739
740
+ def seturl (url ):
741
+ info ("Setting url to \" %s\" in %s" % (url , os .getcwd ()))
742
+ return pquery ([git_cmd , 'remote' , 'set-url' , 'origin' , url ]).strip ()
743
+
701
744
def geturl ():
702
745
url = ""
703
746
remotes = Git .getremotes ()
@@ -810,12 +853,15 @@ def fromurl(cls, url, path=None):
810
853
repo .path = os .path .abspath (path or os .path .join (os .getcwd (), repo .name ))
811
854
repo .url = formaturl (m_repo_url .group (1 ))
812
855
repo .rev = m_repo_url .group (3 )
813
- if repo .rev and not re .match (r'^([a-fA-F0-9]{6,40})$' , repo .rev ):
856
+ if repo .rev and repo . rev != 'latest' and not re .match (r'^([a-fA-F0-9]{6,40})$' , repo .rev ):
814
857
error ('Invalid revision (%s)' % repo .rev , - 1 )
815
858
else :
816
859
error ('Invalid repository (%s)' % url .strip (), - 1 )
817
860
818
- repo .cache = Program (repo .path ).get_cfg ('CACHE' )
861
+ cache_cfg = Global ().get_cfg ('CACHE' , '' )
862
+ if cache_repositories and cache_cfg and cache_cfg != 'none' and cache_cfg != 'off' and cache_cfg != 'disabled' :
863
+ loc = cache_cfg if (cache_cfg and cache_cfg != 'on' and cache_cfg != 'enabled' ) else None
864
+ repo .cache = loc or os .path .join (tempfile .gettempdir (), 'mbed-repo-cache' )
819
865
820
866
return repo
821
867
@@ -846,7 +892,11 @@ def fromrepo(cls, path=None):
846
892
847
893
repo .path = os .path .abspath (path )
848
894
repo .name = os .path .basename (repo .path )
849
- repo .cache = Program (repo .path ).get_cfg ('CACHE' )
895
+
896
+ cache_cfg = Global ().get_cfg ('CACHE' , '' )
897
+ if cache_repositories and cache_cfg and cache_cfg != 'none' and cache_cfg != 'off' and cache_cfg != 'disabled' :
898
+ loc = cache_cfg if (cache_cfg and cache_cfg != 'on' and cache_cfg != 'enabled' ) else None
899
+ repo .cache = loc or os .path .join (tempfile .gettempdir (), 'mbed-repo-cache' )
850
900
851
901
repo .sync ()
852
902
@@ -1004,10 +1054,13 @@ def clone(self, url, path, rev=None, depth=None, protocol=None, **kwargs):
1004
1054
shutil .copytree (cache , path )
1005
1055
1006
1056
with cd (path ):
1057
+ scm .seturl (formaturl (url , protocol ))
1058
+ scm .cleanup ()
1007
1059
info ("Update cached copy from remote repository" )
1008
1060
scm .update (rev , True )
1009
1061
main = False
1010
1062
except (ProcessException , IOError ):
1063
+ info ("Discarding cached repository" )
1011
1064
if os .path .isdir (path ):
1012
1065
rmtree_readonly (path )
1013
1066
@@ -1160,7 +1213,7 @@ def __init__(self, path=None, print_warning=False):
1160
1213
if self .is_cwd and print_warning :
1161
1214
warning (
1162
1215
"Could not find mbed program in current path \" %s\" .\n "
1163
- "You can fix this by calling \" mbed new .\" or \" mbed config root . \" in the root of your program." % self .path )
1216
+ "You can fix this by calling \" mbed new .\" in the root of your program." % self .path )
1164
1217
1165
1218
def get_cfg (self , * args , ** kwargs ):
1166
1219
return Cfg (self .path ).get (* args , ** kwargs ) or Global ().get_cfg (* args , ** kwargs )
@@ -1304,18 +1357,15 @@ def add_tools(self, path):
1304
1357
error ("An error occurred while cloning the mbed SDK tools from \" %s\" " % mbed_sdk_tools_url )
1305
1358
1306
1359
def update_tools (self , path ):
1307
- if not os .path .exists (path ):
1308
- os .mkdir (path )
1309
- with cd (path ):
1310
- tools_dir = 'tools'
1311
- if os .path .exists (tools_dir ):
1312
- with cd (tools_dir ):
1313
- try :
1314
- action ("Updating the mbed 2.0 SDK tools..." )
1315
- repo = Repo .fromrepo ()
1316
- repo .update ()
1317
- except Exception :
1318
- error ("An error occurred while update the mbed SDK tools from \" %s\" " % mbed_sdk_tools_url )
1360
+ tools_dir = 'tools'
1361
+ if os .path .exists (os .path .join (path , tools_dir )):
1362
+ with cd (os .path .join (path , tools_dir )):
1363
+ try :
1364
+ action ("Updating the mbed 2.0 SDK tools..." )
1365
+ repo = Repo .fromrepo ()
1366
+ repo .update ()
1367
+ except Exception :
1368
+ error ("An error occurred while update the mbed SDK tools from \" %s\" " % mbed_sdk_tools_url )
1319
1369
1320
1370
def get_tools (self ):
1321
1371
mbed_tools_path = self .get_tools_dir ()
@@ -1373,6 +1423,7 @@ def get_macros(self):
1373
1423
macros = f .read ().splitlines ()
1374
1424
return macros
1375
1425
1426
+
1376
1427
def ignore_build_dir (self ):
1377
1428
build_path = os .path .join (self .path , self .build_dir )
1378
1429
if not os .path .exists (build_path ):
@@ -1436,6 +1487,9 @@ def __init__(self, path):
1436
1487
1437
1488
# Sets config value
1438
1489
def set (self , var , val ):
1490
+ if not re .match (r'^([\w+-]+)$' , var ):
1491
+ error ("%s is invalid config variable name" % var )
1492
+
1439
1493
fl = os .path .join (self .path , self .file )
1440
1494
try :
1441
1495
with open (fl ) as f :
@@ -1630,15 +1684,11 @@ def new(name, scm='git', program=False, library=False, mbedlib=False, create_onl
1630
1684
p .path = cwd_root
1631
1685
p .set_root ()
1632
1686
if not create_only and not p .get_os_dir () and not p .get_mbedlib_dir ():
1633
- url = mbed_lib_url if mbedlib else mbed_os_url
1687
+ url = mbed_lib_url if mbedlib else mbed_os_url + '#latest'
1634
1688
d = 'mbed' if mbedlib else 'mbed-os'
1635
1689
try :
1636
1690
with cd (d_path ):
1637
1691
add (url , depth = depth , protocol = protocol , top = False )
1638
- if not mbedlib :
1639
- with cd (d ):
1640
- repo = Repo .fromrepo ()
1641
- repo .checkout ('latest' )
1642
1692
except Exception as e :
1643
1693
if os .path .isdir (os .path .join (d_path , d )):
1644
1694
rmtree_readonly (os .path .join (d_path , d ))
@@ -1690,7 +1740,8 @@ def import_(url, path=None, ignore=False, depth=None, protocol=None, top=True):
1690
1740
with cd (repo .path ):
1691
1741
Program (repo .path ).set_root ()
1692
1742
try :
1693
- repo .checkout (repo .rev , True )
1743
+ if repo .rev and repo .getrev () != repo .rev :
1744
+ repo .checkout (repo .rev , True )
1694
1745
except ProcessException as e :
1695
1746
err = "Unable to update \" %s\" to %s" % (repo .name , repo .revtype (repo .rev , True ))
1696
1747
if depth :
@@ -2383,6 +2434,10 @@ def config_(var=None, value=None, global_cfg=False, unset=False, list_config=Fal
2383
2434
else :
2384
2435
# Find the root of the program
2385
2436
program = Program (os .getcwd ())
2437
+ if program .is_cwd :
2438
+ error (
2439
+ "Could not find mbed program in current path \" %s\" .\n "
2440
+ "Change the current directory to a valid mbed program or use the '--global' option to set global configuration." % program .path )
2386
2441
with cd (program .path ):
2387
2442
if unset :
2388
2443
program .set_cfg (var , None )
0 commit comments