Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.installer / src / main / packaging / gvspkg @ 42824

History | View | Annotate | Download (59.6 KB)

1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3
#
4
import sys
5
import os
6
import os.path
7
import fnmatch
8
import shutil
9
import zipfile
10
import stat
11
import getopt
12
from os.path import dirname
13
import shutil
14
from os import system
15
import ConfigParser
16
import StringIO
17
import re
18
import urllib2
19
import time
20

    
21
DEBUG = False
22
DEBUG = False
23
VERBOSE = False
24
SEARCH_VERSIONS = list()
25

    
26
class Platform:
27
  def __init__(self,os,arch,exe):
28
    self.os = os
29
    self.arch = arch
30
    self.exe_extension = exe
31

    
32
  def getOS(self):
33
    return self.os
34

    
35
  def getArch(self):
36
    return self.arch
37

    
38
  def getExeExtension(self):
39
    return self.exe_extension
40

    
41
platforms = (
42
  Platform("lin","x86",".run"),
43
  Platform("lin","x86_64",".run"),
44
  Platform("win","x86",".exe"),
45
  Platform("win","x86_64",".exe")
46
)
47

    
48

    
49
def log(msg):
50
  f=open("/tmp/gvspkg.log","a")
51
  f.write(time.ctime())
52
  f.write(": ")
53
  f.write(msg)
54
  f.write("\n")
55
  f.close()
56

    
57
def message(msg):
58
    if VERBOSE:
59
        print msg
60
        sys.stdout.flush()
61
    log(msg)
62

    
63
def msgerror(msg, err=None):
64
    print "ERROR: ", msg
65
    log("ERROR: "+msg)
66
    if err!=None :
67
      print "ERROR: ", str(err)
68
      sys.stdout.flush()
69
      log("ERROR: "+ str(err))
70

    
71

    
72
def msgwarn(msg):
73
    print "WARNING: ", msg
74
    sys.stdout.flush()
75
    log("WARNING: "+ msg)
76

    
77
def debug(msg):
78
    if DEBUG:
79
        print "DEBUG: ", msg
80
        sys.stdout.flush()
81
        log("DEBUG: "+ msg)
82

    
83
def acquire_file(name):
84
  files = list()
85
  folder = os.getcwd()
86
  while folder not in ( None, "", "/"):
87
    pathname = os.path.join(folder,name)
88
    if os.path.exists(pathname):
89
      files.append(pathname)
90
    folder = os.path.dirname(folder)
91
  return files
92

    
93
def get_gvspkg_bin_folder():
94
    files = list()
95
    if os.environ.get("HOME") != None :
96
        files.append(os.path.join(os.environ['HOME'],".gvspkg.bin"))
97
    files.extend( acquire_file(".gvspkg.bin") )
98
    files.extend( acquire_file("gvspkg.bin") )
99
    if len(files)<1 :
100
      return None
101
    debug( "gvspkg.bin = %s" % files[-1])
102
    return files[-1]
103

    
104
def search_GVSPKG_ROOT():
105
  f = get_gvspkg_bin_folder()
106
  if f==None:
107
    return None
108
  return os.path.dirname(f)
109

    
110
RWALL = stat.S_IWOTH | stat.S_IROTH | stat.S_IWUSR | stat.S_IRUSR | stat.S_IWGRP | stat.S_IRGRP
111
RWXALL = RWALL | stat.S_IXUSR | stat.S_IXOTH | stat.S_IXGRP
112

    
113
VERSION = os.path.basename(os.getcwd())
114
GVSPKG_ROOT = search_GVSPKG_ROOT()
115

    
116
def getVersion():
117
    return VERSION
118

    
119
def getSearchVersions():
120
    vers = list();
121
    vers.extend(SEARCH_VERSIONS)
122
    vers.append(VERSION)
123
    return vers
124

    
125
def getPackagesRoot():
126
    return GVSPKG_ROOT
127

    
128
def getPool():
129
    return getPackagesRoot() + "/pool"
130

    
131
def getWeb():
132
    return getPackagesRoot() + "/web"
133

    
134
def getDist():
135
    return getPackagesRoot() + "/dists/" +getVersion()
136

    
137
def findfiles(root,filename):
138
    result=list()
139
    for wroot, dirs, files in os.walk(root):
140
        for f in files :
141
            if fnmatch.fnmatch(f,filename):
142
                result.append(wroot+"/"+f)
143
    result.sort()
144
    return result
145

    
146
def mychmod(filename, perms):
147
    try:
148
        os.chmod(filename,perms)
149
    except Exception, ex:
150
        msgwarn("Can't change permissions of file '%s', error %s" % (filename, str(ex)))
151

    
152
def makedirs(path):
153
    if not os.path.isdir(path) :
154
      os.makedirs(path)
155

    
156
class Command:
157

    
158
    def __init__(self, args):
159
        self.args = args
160
        self.defaultoptions = None
161

    
162
    def load_options(self,filename):
163
        debug("loading option from %s" % filename)
164
        if not os.path.isfile(filename):
165
            debug("filename %s not found" % filename)
166
            return
167
        f=file(filename,"r")
168
        for line in f.readlines():
169
            line = line.strip()
170
            if line=="" or line.startswith("#"):
171
                continue
172
            if line[-1] == "\n":
173
                line = line[:-1]
174
            n = line.find("=")
175
            if n<0 :
176
                continue
177
            cmd = line[:n]
178
            args = line[n+1:].strip()
179

    
180
            if args != "":
181
              self.defaultoptions[cmd] = self.defaultoptions.get(cmd,[]) +  args.split(" ")
182
            debug("add options: %s=%r" % (cmd, args.split(" ")))
183

    
184
        f.close()
185

    
186
    def load_default_options(self):
187
        if self.defaultoptions != None:
188
            return
189
        self.defaultoptions = dict()
190
        options = list();
191
        if GVSPKG_ROOT != None:
192
          rootoptions = os.path.join(GVSPKG_ROOT,"gvspkg.bin/options")
193
        else:
194
          rootoptions = None
195
        if rootoptions != None and os.path.isfile(rootoptions):
196
            options.append(rootoptions)
197
        else:
198
            options.append("~/.gvspkg.bin/options")
199
        options.extend(acquire_file(".gvspkg.options"))
200
        options.extend(acquire_file("gvspkg.options"))
201
        for optionfile in options:
202
          self.load_options(optionfile)
203

    
204
    def getArgs(self,name):
205
        self.load_default_options()
206
        l = list()
207
        cmd = self.defaultoptions.get(name,None)
208
        if cmd != None:
209
          l.extend(cmd)
210
        l.extend(self.args[1:])
211
        return l
212

    
213
def isDigit(s):
214
    if len(s)>1:
215
        s=s[0]
216
    return s in ("0","1","2","3","4","5","6","7","8","9")
217

    
218

    
219

    
220
class PackageInfo(str):
221
    def __init__(self, filename):
222
        self._ini = None
223
        self.filename = filename[:-7]
224
        self.type = filename[-6:]
225
        s = os.path.basename(self.filename)
226
        s = s.split("-")
227
        #print "## PackageInfo ", repr(s)
228
        self.gvsig = s[0] + "-" + s[1]
229
        self.gvsig_version = s[2]
230
        self.code = s[3]
231
        try:
232
  # gvSIG-desktop-1.12.0-com.iver.cit.gvsig.cad-1.12.0-opencadtools-1418-final-all-all-j1_6.gvspkg
233
  #    0 -  1    -  2   -          3           -  4   - 5          -  6 - 7   - 8 - 9 - 10
234
  # gvSIG-desktop-1.12.0-com.iver.cit.gvsig.cad-1.12.0-1418-final-all-all-j1_6.gvspkg
235
  #    0 -  1    -  2   -          3           -  4   - 5  -  6  - 7 - 8 - 9
236

    
237
            if isDigit(s[5]) :
238
                self.version = s[4]
239
                self.build = s[5]
240
                self.status = s[6]
241
                self.os = s[7]
242
                self.arch = s[8]
243
            else:
244
                self.version = s[4] + "-" + s[5]
245
                self.build = s[6]
246
                self.status = s[7]
247
                self.os = s[8]
248
                self.arch = s[9]
249

    
250
        except Exception:
251
            self.build = "0"
252
            self.status = "unknow"
253
            self.os = "all"
254
            self.arch = "all"
255
        try:
256
            self.build = int(self.build)
257
        except:
258
            pass
259

    
260
    def getCode(self):
261
        return self.code
262

    
263
    def getOS(self):
264
        return self.os
265

    
266
    def getArch(self):
267
        return self.arch
268

    
269
    def getKey(self):
270
        return self.code+"-"+self.os+"-"+self.arch
271

    
272
    def getFullName(self):
273
        return os.path.basename(self.filename)
274

    
275
    def getFullVersion(self):
276
        try:
277
          r = re.compile("([0-9]+)[.]([0-9]+)[.]([0-9]+)-([a-zA-Z0-0]+)$")
278
          m = r.match(self.version)
279
          if m == None:
280
            clasificador="ZZZZZZZZ"
281
            r = re.compile("([0-9]+)[.]([0-9]+)[.]([0-9]+)$")
282
            m = r.match(self.version)
283
          else:
284
            clasificador=m.group(4)
285
          v1=int(m.group(1))
286
          v2=int(m.group(2))
287
          v3=int(m.group(3))
288
          return "%06d.%06d.%06d-%s-%06d" % (v1,v2,v3,clasificador,self.build)
289
        except:
290
          if "-" in self.version :
291
            return "%s-%06d" %(self.version,self.build)
292
          else:
293
            return "%s-ZZZZZZZZ-%06d" %(self.version,self.build)
294

    
295
    def getFilename(self):
296
        return self.filename + "." + self.type
297

    
298
    def hasPki(self):
299
        return os.path.isfile( self.getPkiFilename() )
300

    
301
    def getPkiFilename(self):
302
        return self.filename + ".gvspki"
303

    
304
    def hasPkg(self):
305
        return os.path.isfile( self.getPkgFilename() )
306

    
307
    def getPkgFilename(self):
308
        return self.filename + ".gvspkg"
309

    
310
    def getIniOption(self, name, default=None):
311
      section = "general"
312
      ini = self.getIni()
313
      if ini.has_option(section, name):
314
        x = ini.get(section, name)
315
        x = x.replace("\\:", ":")
316
        return x
317
      return default
318

    
319
    def getDescription(self):
320
      return self.getIniOption("description")
321

    
322
    def getCategories(self):
323
      return self.getIniOption("categories")
324

    
325
    def getName(self):
326
      return self.getIniOption("name")
327

    
328
    def getOwner(self):
329
      ini = self.getIni()
330
      if ini.has_option("general","owner"):
331
        return ini.get("general","owner")
332
      return None
333

    
334
    def getUrl(self):
335
      ini = self.getIni()
336
      if ini.has_option("general","download-url"):
337
        return ini.get("general","download-url")
338
      return None
339

    
340
    def getSourceUrl(self):
341
      ini = self.getIni()
342
      if ini.has_option("general","source-url"):
343
        return ini.get("general","source-url")
344
      return None
345

    
346
    def getDependencies(self):
347
      ini = self.getIni()
348
      if ini.has_option("general","dependencies"):
349
        return ini.get("general","dependencies")
350
      return None
351

    
352
    def getType(self):
353
      ini = self.getIni()
354
      if ini.has_option("general","type"):
355
        return ini.get("general","type")
356
      return None
357

    
358
    def getOfficial(self):
359
      ini = self.getIni()
360
      if ini.has_option("general","official"):
361
        return ini.get("general","official")
362
      return None
363

    
364
    def getIni(self):
365
        if self._ini != None:
366
          return self._ini
367
        index_path = self.getPkiFilename()
368
        outputfolder="/tmp/gvspkg.%s" % os.getpid()
369
        os.mkdir(outputfolder)
370
        os.system('unzip -q %s -d %s' % (index_path,outputfolder))
371

    
372
        files = findfiles(outputfolder, "package.info")
373
        if len(files) != 1:
374
            msgerror("Can't locate package.info in pool '%s'." % (index_path))
375
            return None
376

    
377
        package_info = files[0]
378
        self._ini = ConfigParser.ConfigParser()
379
        f = file(package_info,"r")
380
        ss = f.read()
381
        self._ini.readfp(StringIO.StringIO("[general]\n"+ss))
382
        f.close()
383
        shutil.rmtree(outputfolder)
384
        return self._ini
385

    
386
    def __str__(self):
387
        return self.filename
388

    
389
    def __repr__(self):
390
        return "filename=%r:gvsig=%r:gvsig_version=%r:code=%r:version=%r:build=%r:status=%r" % (
391
                self.filename, self.gvsig, self.gvsig_version, self.code, self.version, self.build, self.status )
392

    
393
class IndexList(list):
394

    
395
    def load(self, fname):
396
        message( "Loading index list from '%s'." % fname)
397
        f=file(fname,"r")
398
        lines=f.readlines()
399
        f.close()
400
        for line in lines:
401
          if line[-1] == "\n":
402
            line = line[:-1]
403

    
404
          info = PackageInfo(line)
405
          self.append(info)
406

    
407
    def save(self,fname):
408
        message( "Saving index list from '%s'." % fname)
409
        f=file(fname,"w")
410
        for index in self:
411
          f.write("%s\n" % index.getFilename())
412
        f.close()
413
        mychmod(fname,RWALL)
414

    
415
    def build(self, pool, versions):
416
        message( "Creating index list for version '%s' from '%s'" % (versions, pool) )
417
        packages=dict()
418
        for root, dirs, files in os.walk(pool):
419
            for f in files :
420
                if f[-7:].lower()  in (".gvspki", ".gvspkg") :
421
                    fullpath = root+"/"+f
422
                    info = PackageInfo(fullpath)
423
                    if info.gvsig == "gvSIG-desktop" and info.gvsig_version in versions :
424
                        if packages.get(info.getKey()) == None:
425
                            debug( "build: add    " + repr(info))
426
                            packages[info.getKey()]=info
427
                        else:
428
                            oldinfo = packages[info.getKey()]
429
                            debug("build: %s %s %s" % ( info.getKey(), oldinfo.getFullVersion(),info.getFullVersion()))
430
                            if oldinfo.getFullVersion()<info.getFullVersion()  :
431
                                debug( "build: update "+ repr(oldinfo))
432
                                packages[info.getKey()]=info
433
                    else:
434
                        debug( "build: skip   "+ repr(info))
435
        self.extend(packages.values())
436
        self.sort()
437

    
438
def lsi(args):
439
    cmd = Command(args)
440
    try:
441
        opts, args = getopt.getopt(cmd.getArgs("lsi"), "l", ["long-format"])
442
    except getopt.GetoptError, err:
443
        # print help information and exit:
444
        print str(err) # will print something like "option -a not recognized"
445
        shorthelp(args)
446
        sys.exit(2)
447

    
448
    long_format=False
449
    for opt, arg in opts:
450
        if opt in ("-l", "--long-format"):
451
            long_format = True
452
        else:
453
            assert False, "unhandled option"
454

    
455
    indexes = IndexList()
456
    indexes.build(getPool(), getSearchVersions())
457

    
458
    for info in indexes:
459
        if info.hasPki():
460
            if long_format:
461
                print "["+os.path.basename(info.getPkiFilename())+"]"
462
                print "# ", info.getPkiFilename()
463
                show(["show", os.path.basename(info.getPkiFilename())])
464
            else:
465
                print info.getPkiFilename()
466

    
467

    
468
def installer_add(cmd,arg1,arg2):
469
    installer_add_use_zip(cmd,arg1,arg2)
470

    
471
def installer_add_use_zip(cmd,arg1,arg2):
472
    if cmd == "addjrelin":
473
      return
474

    
475
    if cmd == "addjrewin":
476
      return
477

    
478
    if cmd == "addpks":
479
       zip = zipfile.ZipFile(arg1,"a",zipfile.ZIP_STORED)
480
       zip.write(arg2,"package.gvspks")
481
       zip.close()
482

    
483
def installer_add_use_installkit(cmd,arg1,arg2):
484
    folder = "%s/gvspkg.bin" % GVSPKG_ROOT
485

    
486
    cmd = "%s/installkit %s/main.tcl %s %s %s" % (
487
        "/mnt/data0/public-files/gvsig-desktop/gvspkg.bin",
488
        folder,
489
        cmd,
490
        arg1,
491
        arg2
492
    )
493
    system(cmd)
494

    
495
def mkinstall(args):
496
    cmd = Command(args)
497
    try:
498
        opts, args = getopt.getopt(cmd.getArgs("mkinstall"), "N:lL:wW:", ["addjrewin", "addjrelin", "jrelin=", "jrewin=", "distribution-name="])
499
    except getopt.GetoptError, err:
500
        # print help information and exit:
501
        print str(err) # will print something like "option -a not recognized"
502
        shorthelp(args)
503
        sys.exit(2)
504

    
505
    #print "opts = ",opts
506
    #print "args = ",args
507
    addjrelin=False
508
    addjrewin=False
509
    jrelin=None
510
    jrewin=None
511
    distribution_name = "custom"
512
    for opt, arg in opts:
513
        if opt in ("-L", "--jrelin"):
514
            jrelin = arg
515
        elif opt in ("-W", "--jrewin"):
516
            jrewin = arg
517
        elif opt in ("-l", "--addjrelin"):
518
            addjrelin = True
519
        elif opt in ("-w", "--addjrewin"):
520
            addjrewin = True
521
        elif opt in ("-N", "--distrinution-name"):
522
            distribution_name = arg
523
        else:
524
            assert False, "unhandled option"
525

    
526

    
527
    if len(args) != 2 :
528
        shorthelp(args)
529
        sys.exit(4)
530

    
531
    bin_name = args[0]
532
    gvspks_name = args[1]
533
    custom_name = bin_name.replace("online", distribution_name)
534

    
535
    if not "online" in bin_name :
536
        print "gvspkg mkinstall: binary file name must contain 'online'"
537
        sys.exit(3)
538

    
539
    if addjrelin and addjrewin :
540
        print "gvspkg mkinstall: only one of addjrelin or addjrewin is allowed."
541
        sys.exit(4)
542

    
543
    message("Creating %s..." % custom_name)
544
    shutil.copyfile(bin_name, custom_name)
545
    mychmod(custom_name,RWALL)
546
    message("Adding %s..." % gvspks_name)
547
    installer_add("addpks", custom_name, gvspks_name)
548

    
549
    """
550
    if addjrelin:
551
        withjre_name = bin_name.replace("online", distribution_name+"-withjre")
552
        message("Creating %s..." % withjre_name)
553
        shutil.copyfile(custom_name, withjre_name)
554
        mychmod(withjre_name,RWALL)
555
        message("Adding %s..." % jrelin)
556
        installer_add("addjrelin", withjre_name, jrelin)
557

    
558

    
559
    if addjrewin:
560
        withjre_name = bin_name.replace("online", distribution_name+"-withjre")
561
        message("Creating %s..." % withjre_name)
562
        shutil.copyfile(custom_name, withjre_name)
563
        mychmod(withjre_name,RWALL)
564
        message("Adding %s..." % jrewin)
565
        installer_add("addjrewin", withjre_name, jrewin)
566
    """
567

    
568
def mks(args):
569
    cmd = Command(args)
570
    try:
571
        opts, args = getopt.getopt(cmd.getArgs("mks"), "ixscI:", ["index-only","include-default-selection", "clear-list", "exclude=", "excludepki=", "excludepkg=", "include="])
572
    except getopt.GetoptError, err:
573
        # print help information and exit:
574
        print str(err) # will print something like "option -a not recognized"
575
        shorthelp(args)
576
        sys.exit(2)
577

    
578
    default_selection = None
579
    index_only = False
580
    clear_list=False
581
    includes=list()
582
    excludes_pki=list()
583
    excludes_pkg=list()
584
    for opt, arg in opts:
585
        if opt in ("-c", "--clear-list"):
586
            clear_list = True
587
        elif opt in ("-s", "--include-default-selection"):
588
            default_selection = "defaultPackages"
589
        elif opt in ("-x", "--exclude"):
590
            excludes_pki.append(arg)
591
            excludes_pkg.append(arg)
592
        elif opt in ( "--excludepki"):
593
            excludes_pki.append(arg)
594
        elif opt in ( "--excludepkg"):
595
            excludes_pkg.append(arg)
596
        elif opt in ( "--include", "-I"):
597
            if not os.path.isabs(arg) :
598
              arg = os.path.join(getPool(), arg)
599
            if arg.endswith(".*"):
600
              includes.append(PackageInfo(arg[:-2]+".gvspkg"))
601
              includes.append(PackageInfo(arg[:-2]+".gvspki"))
602
            else:
603
              includes.append(PackageInfo(arg))
604
        elif opt in ("-i", "--index-only"):
605
            index_only = True
606
        else:
607
            assert False, "unhandled option %r" % opt
608

    
609
    if default_selection!=None and  not os.path.isfile(default_selection) :
610
        msgwarn("No se ha encontrado el fichero %r. la opcion -s/--include-default-selection sera ignorada." % default_selection)
611
        default_selection = None
612

    
613

    
614
    indexes = IndexList()
615

    
616
    packages_txt = getDist() +"/packages.txt"
617
    packages_gvspki = getDist() +"/packages.gvspki"
618

    
619
    message( "Creating 'packages.gvspki' for version '%s'" % getVersion() + "...")
620
    if not os.path.exists(getDist()):
621
        msgerror("Can't locate version folder '%s'." % getDist())
622
        sys.exit(3)
623

    
624
    if os.path.exists(packages_txt) and not clear_list:
625
        indexes.load(packages_txt)
626
    else:
627
        indexes.build(getPool(), getSearchVersions())
628
        indexes.save(packages_txt)
629

    
630
    for pkg in includes:
631
      indexes.append(pkg)
632

    
633
    # El indice de paquetes lleva los paquetes para todas las plataformas y sistemas
634
    # ya que al conectarnos a el desde el administrador de complementos ya
635
    # se encarga la aplicacion de seleccionar los correspondientes a la plataforma
636
    # sobre la que esta rodando gvSIG.
637
    message( "Writing 'packages.gvspki' to '%s'" % packages_gvspki )
638
    set = zipfile.ZipFile(packages_gvspki,"w",zipfile.ZIP_STORED)
639
    for info in indexes:
640
        if not ( info.code in excludes_pki or info.getFullName() in excludes_pki ):
641
            debug("Add package '%s'" % info.getPkiFilename())
642
            try:
643
                if info.hasPki() :
644
                    set.write(info.getPkiFilename(), os.path.basename(info.getPkiFilename()))
645
            except Exception, ex:
646
                msgerror("Can't add index '%s', error %s" % (info, str(ex)))
647
        else:
648
            debug("Exclude package '%s'" % info.getFullName())
649
    if default_selection != None :
650
        set.write(default_selection,default_selection)
651
    set.close()
652
    mychmod(packages_gvspki,RWALL)
653

    
654
    md5sum(packages_gvspki,packages_gvspki+".md5")
655
    mychmod(packages_gvspki+".md5",RWALL)
656

    
657
    if not index_only :
658
      for platform in platforms:
659
        packages_gvspks = getDist() +"/packages-"+platform.getOS()+"-"+platform.getArch()+".gvspks"
660
        message( "Writing 'packages-"+platform.getOS()+"-"+platform.getArch()+".gvspks' to '%s'" % packages_gvspks )
661
        set = zipfile.ZipFile(packages_gvspks,"w",zipfile.ZIP_STORED)
662
        for info in indexes:
663
            if not ( info.code in excludes_pkg or info.getFullName() in excludes_pkg ):
664
                try:
665
                    if info.hasPkg():
666
                      if info.getOS() in ("all", platform.getOS()) :
667
                        if info.getArch() in ("all", platform.getArch()) :
668
                          set.write(info.getPkgFilename(), os.path.basename(info.getPkgFilename()))
669
                except Exception, ex:
670
                    msgerror("Can't add package '%s', error %s" % (index, str(ex)))
671
            else:
672
                debug("Exclude package '%s'" % info.getFullName())
673
        if default_selection != None :
674
            set.write(default_selection,default_selection)
675
        set.close()
676
        mychmod(packages_gvspks,RWALL)
677

    
678
        md5sum(packages_gvspks,packages_gvspks+".md5")
679
        mychmod(packages_gvspks+".md5",RWALL)
680

    
681
    message( "Createds package indexes.\n")
682

    
683
def mkmirror(args):
684
    cmd = Command(args)
685
    try:
686
        opts, args = getopt.getopt(cmd.getArgs("mkmirrot"), "b:", [ "build="])
687
    except getopt.GetoptError, err:
688
        # print help information and exit:
689
        print str(err) # will print something like "option -a not recognized"
690
        shorthelp(args)
691
        sys.exit(2)
692

    
693
    build = None
694
    for opt, arg in opts:
695
        if opt in ("-b", "--build"):
696
            build = arg
697
        else:
698
            assert False, "unhandled option %r" % opt
699

    
700
    if build == None:
701
        msgerror("Build number required.")
702
        sys.exit(3)
703
    domkmirror( getPackagesRoot(),getVersion(),build)
704

    
705
def linkfile(src,dst):
706
  if os.path.lexists(dst):
707
    os.remove(dst)
708
  os.symlink(src,dst)
709
  if os.path.lexists(src+".md5") :
710
    if os.path.lexists(dst+".md5"):
711
      os.remove(dst+".md5")
712
    os.symlink(src+".md5",dst+".md5")
713

    
714
def domkmirror(root_src, version, build):
715
  join = os.path.join
716

    
717
  build = str(build)
718
  root_target = join(root_src,"mirrors",version+"-"+build,"gvsig-desktop")
719
  build_src = join(root_src,"dists",version,"builds",build)
720
  build_target = join(root_target,"dists",version,"builds",build)
721
  pool_src = join(root_src,"pool")
722
  pool_target = join(root_target,"pool")
723

    
724
  makedirs(root_target)
725
  makedirs(build_target)
726
  makedirs(pool_target)
727
  files = os.listdir(build_src)
728
  linkfile(join(build_src,"packages.gvspki"), join(root_target,"dists",version,"packages.gvspki"))
729
  for f in files:
730
    f_src = join(build_src,f)
731
    f_target = join(build_target,f)
732
    if os.path.isfile(f_src):
733
      linkfile(f_src,f_target)
734

    
735
  z = zipfile.ZipFile(join(build_src,"packages.gvspki"))
736
  pkgs = z.namelist()
737
  for pkgname in pkgs:
738
    if pkgname!='defaultPackages':
739
      pkg = PackageInfo(pkgname)
740
      makedirs(join(root_target,"pool",pkg.getCode()))
741
      src = join(root_src,"pool",pkg.getCode(),pkg.getPkgFilename())
742
      target = join(root_target,"pool",pkg.getCode(),pkg.getPkgFilename())
743
      linkfile(src,target)
744
  cmd = "cd %s ; find . ! -type d >%s/files.lst" % (root_target, build_target)
745
  os.system(cmd)
746

    
747
def mkhtml(args):
748
    def getCode(info):
749
      return info.code
750

    
751

    
752
    cmd = Command(args)
753
    try:
754
        opts, args = getopt.getopt(cmd.getArgs("mkhtml"), "xsc", ["clear-list", "exclude=", "excludepki=", "excludepkg=", "include="])
755
    except getopt.GetoptError, err:
756
        # print help information and exit:
757
        print str(err) # will print something like "option -a not recognized"
758
        shorthelp(args)
759
        sys.exit(2)
760

    
761
    index_only = False
762
    clear_list=False
763
    includes=list()
764
    excludes_pki=list()
765
    excludes_pkg=list()
766
    for opt, arg in opts:
767
        if opt in ("-c", "--clear-list"):
768
            clear_list = True
769
        elif opt in ("-x", "--exclude"):
770
            excludes_pki.append(arg)
771
            excludes_pkg.append(arg)
772
        elif opt in ( "--excludepki"):
773
            excludes_pki.append(arg)
774
        elif opt in ( "--excludepkg"):
775
            excludes_pkg.append(arg)
776
        elif opt in ( "--include", "-I"):
777
            includes.append(PackageInfo(arg))
778
        else:
779
            assert False, "unhandled option %r" % opt
780

    
781
    message("Creating html pages...")
782
    indexes = IndexList()
783

    
784
    packages_txt = getDist() +"/packages.txt"
785

    
786
    if os.path.exists(packages_txt) and not clear_list:
787
        indexes.load(packages_txt)
788
    else:
789
        indexes.build(getPool(), getSearchVersions())
790
        indexes.save(packages_txt)
791

    
792
    for pkg in includes:
793
      indexes.append(pkg)
794

    
795
    allpackages = list()
796
    basepath = getWeb()
797
    for info in indexes:
798
        if not ( info.code in excludes_pki or info.getFullName() in excludes_pki ):
799
            try:
800
                if info.hasPki() :
801
                    mkpkihtml(basepath, info)
802
                    allpackages.append(info)
803
            except Exception, ex:
804
                msgerror("Can't create html '%s', error %s" % (info, str(ex)))
805

    
806
    html = '''
807
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
808
<html xmlns="http://www.w3.org/1999/xhtml">
809
<head>
810
  <meta http-equiv="Content-Type" content= "text/html; charset=us-ascii" />
811
      <title>"%s" package list</title>'''% getVersion() # Title
812

    
813
    html += '''
814
<!-- estilos para las tablas -->
815
  <style type="text/css" title="currentStyle">
816
    @import "css/demo_table.css";
817
    @import "css/thickbox.css";
818
    #pkglist{
819
        width:100%;
820
        clear:both;
821
        font-family:Arial,Helvetica,sans-serif;
822
    }
823
    #pkgdetails{
824
        width:600px !important;
825
        clear:both;
826
    }
827
    #pkgdetails table th{
828
        text-algin:right;
829
    }
830
  </style>
831
</head>'''
832

    
833
    html += '''
834
<body>
835
  <h1>%s package list</h1>
836
  <table id="pkglist" summary="%s package list" width="100%%" >
837
    <thead>
838
    <tr>
839
      <td>Package name</td>
840
      <td>Version</td>
841
      <td>O.S.</td>
842
      <td>Official</td>
843
      <td>Type</td>
844
      <td>Owner</td>
845
    </tr>
846
    </thead>
847
    <tbody>'''%(getVersion(),getVersion())
848

    
849
    # sort allpackages
850
    for item in sorted(allpackages, key=getCode):
851
      html += '''\n    <tr>
852
      <td><a class="thickbox" href="%s">%s</a></td>
853
      <td>%s</td>
854
      <td>%s</td>
855
      <td>%s</td>
856
      <td>%s</td>
857
      <td>%s</td>
858
    </tr>\n'''%(
859
  "../../../web/" + item.getFullName() + ".html?height=400&width=600",
860
        item.getName(),
861
  item.version,
862
  item.os,
863
  item.getOfficial(),
864
  item.getType(),
865
  item.getOwner()
866
      )
867
    html += """ </tbody>\n </table>
868
<!--javascript para la visualizacion de la tabla y carga dinamica del contenido del enlace -->
869
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js" type="text/javascript"></script>
870
<script src="http://datatables.net/release-datatables/media/js/jquery.dataTables.js" type="text/javascript"></script>
871
<script type="text/javascript" src="js/thickbox-compressed.js"></script>
872

    
873
<!-- inicializaci�n de la tabla con cosas chachis -->
874
<script type="text/javascript">
875
  $(document).ready(function() {
876
      $('#pkglist').dataTable( {
877
      "bPaginate": false,
878
      "bLengthChange": true,
879
      "bFilter": true,
880
      "bSort": true,
881
      "bInfo": true,
882
      "bAutoWidth": true
883
    });
884
 } );
885
</script>
886
</body>
887
</html>"""
888

    
889
    # generate index.html
890
    try:
891
      f=file(getDist()+"/web/index.html","w")
892
      f.write(html)
893
      f.close()
894
    except Exception, ex:
895
      raise ex
896

    
897
    message("html pages createds.\n")
898

    
899

    
900
def mkpkihtml(basepath, info):
901
  html='''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
902
<html xmlns="http://www.w3.org/1999/xhtml">
903
<head>
904
  <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
905
  <title>%s</title>
906
  <!-- estilos para las tablas -->
907
  <style type="text/css" title="currentStyle">
908
    @import "../dists/%s/web/css/demo_table.css";
909
    #pkgdetails{
910
      width:600px;
911
      clear:both;
912
    }
913
    #pkgdetails table th{
914
        text-algin:right;
915
    }
916
  </style>
917
</head>
918
<body>\n'''%(info.getIniOption("name"), getVersion())
919
  html += '  <table id="pkgdetails" summary=%s >\n'%info.getIniOption("name")
920
  html += '    <thead>\n  <tr>\n  <th>%s </th>\n  <td>%s</td>\n  </tr>\n  </thead>\n'%("Name", info.getIniOption("name"))
921
  html += '    <tbody><tr><th>%s </th><td>%s</td></tr>\n'%("Code", info.code)
922
  html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("Version", info.version)
923
  html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("State", info.getIniOption("state"))
924
  html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("Build", info.build)
925
  html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("Owner", info.getOwner())
926

    
927
  #url = info.getUrl()
928
  url = info.getIniOption("download-url")
929
  if url != None:
930
    html += '    <tr><th valing="top">Downloads</th><td><a href ="%s">Binaries</a></td></tr>\n'%(url)
931
  else:
932
    html += '    <tr><th valing="top">Downloads</th><td>Binaries</td></tr>\n'
933

    
934
  sourceUrl = info.getSourceUrl()
935

    
936
  if sourceUrl != None:
937
    html += '    <tr><td></td><td><a href ="%s">Sources</a></td></tr>\n'%(sourceUrl)
938
  else:
939
    html += "    <tr><td></td><td>Sources</td></tr>\n"
940

    
941
  if info.getDependencies() == None:
942
    html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("Dependencies", "")
943
  else:
944
    html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("Dependencies", info.getDependencies().replace("\:",":"))
945
  html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("Type", info.getType())
946
  html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("Official", info.getOfficial())
947
  html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("O.S.", info.getOS())
948
  html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("Architecture", info.getArch())
949
  html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("Categories", info.getCategories())
950

    
951
  description = info.getDescription()
952
  if description == None:
953
    description = ""
954
  description = description.replace("\\n", "<br>")
955
  description = description.replace("\:",":")
956
  html += '    <tr valing="top"><th valing="top">%s </th><td>%s</td></tr>\n'%("Description", description)
957
  html += """  </tbody>\n</table>\n"""
958
  html += """
959
  <!-- javascript para la visualizacion de la tabla -->
960
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript"></script>
961
  <script src="http://datatables.net/release-datatables/media/js/jquery.dataTables.js" type="text/javascript"></script>
962
  <!-- inicializaci�n de la tabla con cosas chachis -->
963
  <script type="text/javascript">
964
    $(document).ready(function() {
965
      $('#pkgdetails').dataTable( {
966
        "bPaginate": false,
967
        "bLengthChange": true,
968
        "bFilter": false,
969
        "bSort": false,
970
        "bInfo": false,
971
        "bAutoWidth": true
972
      });
973
    });
974
  </script>
975
  </body>\n</html>"""
976

    
977

    
978
  try:
979
    f = file(getWeb() + "/" + info.getFullName() + ".html","w")
980
    f.write(html)
981
    f.close()
982
  except Exception, ex:
983
    raise ex
984

    
985
def extract_make_portable(zfile, targetfolder):
986
  zf = zipfile.ZipFile(zfile)
987
  data = zf.read("tools/make-portable")
988
  f = open(os.path.join(targetfolder,"make-portable"),"wb")
989
  f.write(data)
990
  f.close()
991
  zf.close()
992

    
993

    
994
def extract_mkexec(zfile, targetfolder):
995
  print "extract_mkexec: zfile=%s, target=%s" % (zfile, os.path.join(targetfolder,"mkexec"))
996
  zf = zipfile.ZipFile(zfile)
997
  data = zf.read("tools/mkexec")
998
  f = open(os.path.join(targetfolder,"mkexec"),"wb")
999
  f.write(data)
1000
  f.close()
1001
  zf.close()
1002

    
1003

    
1004
def prepare_portable(args):
1005
    cmd = Command(args)
1006
    try:
1007
        opts, args = getopt.getopt(cmd.getArgs("prepare-portable"), "b:s:", [ "build=", "state=" ])
1008
    except getopt.GetoptError, err:
1009
        # print help information and exit:
1010
        print str(err) # will print something like "option -a not recognized"
1011
        shorthelp(args)
1012
        sys.exit(2)
1013

    
1014
    build=None
1015
    state=None
1016
    for opt, arg in opts:
1017
        if opt in ("-b", "--build"):
1018
            build=arg
1019
        elif opt in ("-s", "--state"):
1020
            state=arg
1021
        else:
1022
            assert False, "unhandled option %r" % opt
1023

    
1024
    if build == None:
1025
      print "Requiered option --build not found."
1026
      shorthelp(args)
1027
      sys.exit(2)
1028

    
1029
    if state == None:
1030
      print "Requiered option --state not found."
1031
      shorthelp(args)
1032
      sys.exit(2)
1033

    
1034
    join = os.path.join
1035
    build_folder = join(getPackagesRoot(),"dists",getVersion(),"builds",build)
1036
    if not os.path.isdir(build_folder):
1037
      print "Can't access the build folder "+build_folder+"."
1038
      sys.exit(2)
1039

    
1040
    do_prepare_portable(build,state)
1041

    
1042
def do_prepare_portable(build,state):
1043
    join = os.path.join
1044
    build_folder = join(getPackagesRoot(),"dists",getVersion(),"builds",build)
1045
    portable_folder = join(build_folder,"misc","portable")
1046
    makedirs(portable_folder)
1047
    makedirs(join(portable_folder,"packages","custom"))
1048
    makedirs(join(portable_folder,"standard"))
1049
    makedirs(join(portable_folder,"patchs"))
1050
    f=open(join(portable_folder,"packages","excludes"),"w")
1051
    f.write("""EPSG_v6
1052
EPSG_v8_4
1053
EPSG_v8_5
1054
EPSG_v8_6
1055
org.gvsig.app.document.layout1.app.mainplugin
1056
org.gvsig.dyschromatopsia.app.extension
1057
org.gvsig.educa.portableview.app.editor
1058
org.gvsig.educa.portableview.app.viewer
1059
org.gvsig.projection.app.cresques
1060
org.gvsig.projection.app.proj4j
1061
org.gvsig.editing.app.mainplugin
1062
org.gvsig.downloader.app.mainplugin
1063
""")
1064
    f.close()
1065
    fname_base = "gvSIG-desktop-%s-%s-%s" % (getVersion(),build,state)
1066
    for platform in platforms :
1067
      linkfile(
1068
        join(build_folder,fname_base + "-" + platform.getOS() + "-" + platform.getArch() + "-online.zip"),
1069
        join(portable_folder,"standard",fname_base + "-" + platform.getOS() + "-" + platform.getArch() + "-online.zip")
1070
      )
1071
      linkfile(
1072
        join(build_folder,fname_base + "-" + cur_os + "-" + platform.getArch() + ".gvspks"),
1073
        join(portable_folder,"standard",fname_base + "-" + platform.getOS() + "-" + platform.getArch() + ".gvspks")
1074
      )
1075
    extract_make_portable(
1076
      join(build_folder,fname_base + "-lin-x86_64-online.zip"),
1077
      join(portable_folder)
1078
    )
1079
    mychmod(join(portable_folder,"make-portable"),RWXALL)
1080

    
1081
def zipfolder(source,target):
1082
  def zipdir(path, zip):
1083
      for root, dirs, files in os.walk(path):
1084
          for file in files:
1085
              zip.write(os.path.join(root, file))
1086
  zipf = zipfile.ZipFile(target, 'w')
1087
  zipdir(source, zipf)
1088
  zipf.close()
1089

    
1090
def removefile(filename):
1091
  if os.path.exists(filename):
1092
    os.remove(filename)
1093

    
1094
def mkportable(args):
1095
    cmd = Command(args)
1096
    try:
1097
        opts, args = getopt.getopt(cmd.getArgs("mkportable"), "b:s:", [ "build=", "state=" ])
1098
    except getopt.GetoptError, err:
1099
        # print help information and exit:
1100
        print str(err) # will print something like "option -a not recognized"
1101
        shorthelp(args)
1102
        sys.exit(2)
1103

    
1104
    build=None
1105
    state=None
1106
    for opt, arg in opts:
1107
        if opt in ("-b", "--build"):
1108
            build=arg
1109
        elif opt in ("-s", "--state"):
1110
            state=arg
1111
        else:
1112
            assert False, "unhandled option %r" % opt
1113

    
1114
    if build == None:
1115
      print "Requiered option --build not found."
1116
      shorthelp(args)
1117
      sys.exit(2)
1118

    
1119
    if state == None:
1120
      print "Requiered option --state not found."
1121
      shorthelp(args)
1122
      sys.exit(2)
1123

    
1124
    join = os.path.join
1125
    build_folder = join(getPackagesRoot(),"dists",getVersion(),"builds",build)
1126
    if not os.path.isdir(build_folder):
1127
      print "Can't access the build folder "+build_folder+"."
1128
      sys.exit(2)
1129

    
1130
    portable_folder = join(build_folder,"misc","portable")
1131
    if not os.path.isdir(portable_folder) :
1132
      do_prepare_portable(build,state)
1133
    os.system('cd %s ; ./make-portable' % (portable_folder))
1134

    
1135
    message("Removing previos portable zip files")
1136
    for platform in platforms :
1137
      removefile(join(build_folder,"gvSIG-desktop-%s-%s-%s-%s-%s.zip" %  (getVersion(),build,state,platform.getOS(),platform.getArch())))
1138

    
1139
    target_folder = join(getPackagesRoot(),"dists",getVersion(),"builds",build,"misc","portable","target")
1140
    for platform in platforms :
1141
      message("Moving zip gvSIG-desktop-%s-%s-%s-%s-%s.zip" % (getVersion(),build,state,platform.getOS(),platform.getArch()))
1142
      shutil.move(
1143
        join(portable_folder,"gvSIG-desktop-%s-%s-%s-%s-%s" % (getVersion(),build,state,platform.getOS(),platform.getArch())),
1144
        build_folder
1145
      )
1146
    message("Remove temporary folders")
1147
    shutil.rmtree(target_folder)
1148

    
1149
def mkexec(version, build, state, distribution_name, folder):
1150
  fname = "gvSIG-desktop-%s-%s-%s-lin-x86_64-online.zip" % (version,build,state)
1151
  extract_mkexec(os.path.join(folder,fname), folder)
1152
  mychmod(os.path.join(folder,"mkexec"),RWXALL)
1153
  cmd = 'cd %s ; ./mkexec "%s" "%s" "%s" "%s" "%s"' % (folder,version, build, state, distribution_name, folder)
1154
  print "mkexec: cmd=", cmd
1155
  os.system(cmd)
1156
  os.remove(os.path.join(folder,"mkexec"))
1157

    
1158
def mkdist(args):
1159
    cmd = Command(args)
1160
    try:
1161
        opts, args = getopt.getopt(cmd.getArgs("mkdist"), "b:s:", [ "build=", "state=", "distribution_name=" ])
1162
    except getopt.GetoptError, err:
1163
        # print help information and exit:
1164
        print str(err) # will print something like "option -a not recognized"
1165
        shorthelp(args)
1166
        sys.exit(2)
1167

    
1168
    build=None
1169
    state=None
1170
    distribution_name = "standard"
1171

    
1172
    for opt, arg in opts:
1173
        if opt in ("-b", "--build"):
1174
            build=arg
1175
        elif opt in ("-s", "--state"):
1176
            state=arg
1177
        elif opt in ("-N", "--distrinution-name"):
1178
            distribution_name = arg
1179
        else:
1180
            assert False, "unhandled option %r" % opt
1181

    
1182
    if build == None:
1183
      print "Requiered option --build not found."
1184
      shorthelp(args)
1185
      sys.exit(2)
1186

    
1187
    if state == None:
1188
      print "Requiered option --state not found."
1189
      shorthelp(args)
1190
      sys.exit(2)
1191

    
1192
    if not os.path.isdir("builds/"+build):
1193
      print "Can't access the build folder builds/"+build+"."
1194
      sys.exit(2)
1195

    
1196
    message( "Generating distribution for build "+ build + "...")
1197
    message("Recreating index of packages...")
1198
    executeCommand("mks", "-s", "-c")
1199

    
1200
    executeCommand("mkhtml" )
1201

    
1202
    gvspki_filename = "builds/"+build+"/packages.gvspki"
1203
    message( "Coping packages.gvspki to "+ gvspki_filename + "\n")
1204
    shutil.copyfile("packages.gvspki", gvspki_filename)
1205
    shutil.copyfile("packages.gvspki.md5", gvspki_filename +".md5")
1206

    
1207
    for platform in platforms:
1208
        message( "Creating installers for platform "+platform.getOS()+"/"+platform.getArch()+"...")
1209
        gvspks_filename = "builds/"+build+"/gvSIG-desktop-" + VERSION + "-" + build+ "-" + state + "-"+platform.getOS()+"-"+platform.getArch()+".gvspks"
1210
        online_filename = "builds/"+build+"/gvSIG-desktop-" + VERSION + "-" + build+ "-" + state + "-"+platform.getOS()+"-"+platform.getArch() + "-online.jar"
1211

    
1212
        if not os.path.isfile(online_filename):
1213
          msgwarn("Can't access the online installable for "+platform.getOS()+"/"+platform.getArch() + " ("+online_filename+").")
1214
          continue
1215

    
1216
        message( "Coping packages-"+platform.getOS()+"-"+platform.getArch()+".gvspks to "+ gvspks_filename)
1217
        shutil.copyfile("packages-"+platform.getOS()+"-"+platform.getArch()+".gvspks", gvspks_filename)
1218
        shutil.copyfile("packages-"+platform.getOS()+"-"+platform.getArch()+".gvspks.md5", gvspks_filename +".md5")
1219

    
1220
        message( "Add execution permissions to online installables....")
1221
        mychmod(online_filename,RWXALL)
1222

    
1223
        md5sum(online_filename,online_filename+".md5")
1224
        mychmod(online_filename+".md5",RWALL)
1225

    
1226

    
1227
        executeCommand("mkinstall" , online_filename, gvspks_filename)
1228

    
1229
        message( "Renaming files from custom to standard...")
1230
        target_filename = "builds/"+build+"/gvSIG-desktop-" + VERSION + "-" + build+ "-" + state + "-"+platform.getOS()+"-"+platform.getArch()+"-"+distribution_name + ".jar"
1231
        shutil.move(
1232
            "builds/"+build+"/gvSIG-desktop-" + VERSION + "-" + build+ "-" + state + "-"+platform.getOS()+"-"+platform.getArch() + "-custom.jar",
1233
            target_filename
1234
        )
1235
        mychmod(target_filename,RWXALL)
1236

    
1237
        md5sum(target_filename,target_filename+".md5")
1238
        mychmod(target_filename+".md5",RWALL)
1239

    
1240
        message( "Createds installers for platform "+platform.getOS()+"/"+platform.getArch()+"\n")
1241

    
1242
    mkexec(VERSION, build, state, distribution_name, os.path.join(os.getcwd(), "builds", build))
1243

    
1244
    message( "Coping html index to browse paqueges of the distro.")
1245
    shutil.rmtree("builds/"+build+"/web", ignore_errors=True)
1246
    shutil.copytree("web", "builds/"+build+"/web")
1247
    f = file("builds/"+build+"/web/index.html","r")
1248
    contents = f.read()
1249
    f.close()
1250
    contents = contents.replace("href=\"../../../web/gvSIG-desktop-", "href=\"../../../../../web/gvSIG-desktop-")
1251
    f = file("builds/"+build+"/web/index.html","w")
1252
    f.write(contents)
1253
    f.close()
1254

    
1255
    message( "\nCreation of distribution completed.\n")
1256

    
1257

    
1258
def show(args):
1259
    cmd = Command(args)
1260
    try:
1261
        opts, args = getopt.getopt(cmd.getArgs("show"), "S", [ "verify"])
1262
    except getopt.GetoptError, err:
1263
        # print help information and exit:
1264
        print str(err) # will print something like "option -a not recognized"
1265
        shorthelp(args)
1266
        sys.exit(2)
1267

    
1268
    eerify = False
1269
    for opt, arg in opts:
1270
        if opt in ("-V", "--verify"):
1271
            verify = True
1272
        else:
1273
            assert False, "unhandled option %r" % opt
1274

    
1275
    index_name=args[0]
1276
    message( "Show package.info from '%s'" % index_name)
1277
    files = findfiles(getPool(), index_name)
1278
    if len(files) != 1:
1279
        msgerror("Can't locate package '%s' in pool '%s'." % (index_name, getPool()))
1280
        return
1281
    index_path = files[0]
1282
    outputfolder="/tmp/gvspkg.%s" % os.getpid()
1283
    os.mkdir(outputfolder)
1284
    os.system('unzip -q %s -d %s' % (index_path,outputfolder))
1285

    
1286
    files = findfiles(outputfolder, "package.info")
1287
    if len(files) != 1:
1288
        msgerror("Can't locate package.info in pool '%s'." % (index_name))
1289
        return
1290

    
1291
    package_info = files[0]
1292
    f = file(package_info,"r")
1293
    s = f.read()
1294
    f.close()
1295
    print s
1296
    if verify:
1297
      verify_sign(package_info)
1298
    shutil.rmtree(outputfolder)
1299

    
1300
def editall(args):
1301
    cmd = Command(args)
1302
    try:
1303
        opts, args = getopt.getopt(cmd.getArgs("editall"), "Scx:I:r:", ["clear-list", "exclude=", "excludepki=", "excludepkg=", "include=", "replace=", "sign"])
1304
    except getopt.GetoptError, err:
1305
        # print help information and exit:
1306
        print str(err) # will print something like "option -a not recognized"
1307
        shorthelp(args)
1308
        sys.exit(2)
1309

    
1310
    index_only = False
1311
    clear_list=False
1312
    includes=list()
1313
    excludes_pki=list()
1314
    replaces = list()
1315
    excludes_pkg=list()
1316
    sign = False
1317
    interactive = True
1318
    for opt, arg in opts:
1319
        if opt in ("-c", "--clear-list"):
1320
            clear_list = True
1321
        elif opt in ("-x", "--exclude"):
1322
            excludes_pki.append(arg)
1323
            excludes_pkg.append(arg)
1324
        elif opt in ( "--excludepki"):
1325
            excludes_pki.append(arg)
1326
        elif opt in ( "--excludepkg"):
1327
            excludes_pkg.append(arg)
1328
        elif opt in ( "--include", "-I"):
1329
            includes.append(PackageInfo(arg))
1330
        elif opt in ("-r", "--replace"):
1331
            interactive = False
1332
            replaces.append(arg)
1333
        elif opt in ("-S", "--sign"):
1334
            sign = True
1335
        else:
1336
            assert False, "unhandled option %r" % opt
1337

    
1338
    indexes = IndexList()
1339

    
1340
    packages_txt = getDist() +"/packages.txt"
1341
    if os.path.exists(packages_txt) and not clear_list:
1342
        indexes.load(packages_txt)
1343
    else:
1344
        indexes.build(getPool(), getSearchVersions())
1345
        indexes.save(packages_txt)
1346

    
1347
    for pkg in includes:
1348
      indexes.append(pkg)
1349

    
1350
    allpackages = list()
1351
    for info in indexes:
1352
        if not ( info.code in excludes_pki or info.getFullName() in excludes_pki ):
1353
            try:
1354
                if info.hasPki() :
1355
                  print info.getPkiFilename()
1356
                  if interactive :
1357
                    edit_pkginfo_of_package(info.getPkiFilename(), edit_ui)
1358
                  elif len(replaces) < 1:
1359
                    edit_pkginfo_of_package(info.getPkiFilename(), edit_replace, replaces)
1360

    
1361
                  if sign:
1362
                    edit_pkginfo_of_package(info.getPkiFilename(), edit_sign)
1363

    
1364
            except Exception, ex:
1365
                msgerror("Can't add index '%s', error %s" % (info, str(ex)))
1366

    
1367
def edit(args):
1368
    cmd = Command(args)
1369
    try:
1370
        opts, args = getopt.getopt(cmd.getArgs("edit"), "Sr:", [ "replace=", "onlysign", "sign" ])
1371
    except getopt.GetoptError, err:
1372
        # print help information and exit:
1373
        print str(err) # will print something like "option -a not recognized"
1374
        shorthelp(args)
1375
        sys.exit(2)
1376

    
1377
    replaces = list()
1378
    interactive = True
1379
    sign = False
1380
    for opt, arg in opts:
1381
        if opt in ("-r", "--replace"):
1382
            interactive = False
1383
            replaces.append(arg)
1384
        elif opt in ("--onlysign"):
1385
            interactive = False
1386
            sign = True
1387
        elif opt in ("-S", "--sign"):
1388
            sign = True
1389
        else:
1390
            assert False, "unhandled option %r" % opt
1391

    
1392
    index_name=args[0]
1393
    message( "Show package.info from '%s'" % index_name)
1394
    files = findfiles(getPool(), index_name)
1395
    if len(files) != 1:
1396
        msgerror("Can't locate package '%s' in pool '%s'." % (index_name, getPool()))
1397
        return
1398
    index_path = files[0]
1399
    if interactive:
1400
      edit_pkginfo_of_package(index_path, edit_ui)
1401
    elif len(replaces) < 1:
1402
      edit_pkginfo_of_package(index_path, edit_replace, replaces)
1403

    
1404
    if sign:
1405
      edit_pkginfo_of_package(index_path, edit_sign)
1406

    
1407
def edit_ui(filename, args):
1408
      os.system('vi "%s"' % filename)
1409

    
1410
def edit_replace(filename, args):
1411
      replaces = args[0]
1412
      f = open(filename)
1413
      s = f.read()
1414
      f.close()
1415
      for replace in replaces:
1416
        x = replace.split(replace[0])
1417
        if len(x)==4:
1418
          s=re.sub(x[1],x[2],s)
1419
      f = open(filename,"w")
1420
      f.write(s)
1421
      f.close()
1422

    
1423
def edit_sign(filename, args):
1424
      os.system('java -cp "%s/commons-codec-1.6.jar:%s/org.gvsig.installer.lib.impl-1.0.1-SNAPSHOT.jar" org.gvsig.installer.lib.impl.utils.SignUtil sign %s' %  (
1425
        get_gvspkg_bin_folder(),
1426
        get_gvspkg_bin_folder(),
1427
        filename)
1428
      )
1429

    
1430
def verify_sign(filename):
1431
      os.system('java -cp "%s/commons-codec-1.6.jar:%s/org.gvsig.installer.lib.impl-1.0.1-SNAPSHOT.jar" org.gvsig.installer.lib.impl.utils.SignUtil verify %s' % (
1432
        get_gvspkg_bin_folder(),
1433
        get_gvspkg_bin_folder(),
1434
        filename)
1435
      )
1436

    
1437
def edit_pkginfo_of_package(pkg_path, operation, *args):
1438
    outputfolder="/tmp/gvspkg.%s" % os.getpid()
1439
    os.mkdir(outputfolder)
1440
    os.system('unzip -q %s -d %s' % (pkg_path,outputfolder))
1441

    
1442
    files = findfiles(outputfolder, "package.info")
1443
    if len(files) != 1:
1444
        msgerror("Can't locate package.info in pool '%s'." % (pkg_path))
1445
        return
1446

    
1447
    package_info = files[0]
1448
    code = package_info.split("/")[-2]
1449
    operation(package_info, args)
1450

    
1451
    # zip -Dr kk.zip org.gvsig.wfs
1452
    temp_index_name = "/tmp/packages.gvspki.%s" % os.getpid()
1453
    temp_index = zipfile.ZipFile(temp_index_name,"w",zipfile.ZIP_STORED)
1454
    temp_index.write(package_info, "%s/package.info" % (code))
1455
    temp_index.close()
1456
    shutil.rmtree(outputfolder)
1457
    os.remove(pkg_path)
1458
    shutil.move(temp_index_name,pkg_path)
1459

    
1460
def install(args):
1461
    cmd = Command(args)
1462
    try:
1463
        opts, args = getopt.getopt(cmd.getArgs("install"), "fS", [ "force","nohttps" ])
1464
    except getopt.GetoptError, err:
1465
        # print help information and exit:
1466
        print str(err) # will print something like "option -a not recognized"
1467
        shorthelp(args)
1468
        sys.exit(2)
1469

    
1470
    force = False
1471
    nohttps = False
1472
    for opt, arg in opts:
1473
        if opt in ("-f", "--force"):
1474
            force = True
1475
        if opt in ("-S", "--nohttps"):
1476
            nohttps = True
1477
        else:
1478
            assert False, "unhandled option %r" % opt
1479

    
1480
    url_pki = args[0]
1481
    if url_pki.startswith("https:") and nohttps :
1482
       url_pki = "http:" + url_pki[6:]
1483

    
1484
    message( "Download package index '%s'" % url_pki)
1485
    temppath_pki= os.path.join("/tmp",os.path.basename(url_pki))
1486
    if not downloadFile(url_pki,temppath_pki):
1487
      msgerror("Can't download index.")
1488
      msgerror("Can't install '%s'." % url_pki)
1489
      print # force a newline
1490
      return 1
1491
    pkg = PackageInfo(temppath_pki)
1492
    url_pkg = pkg.getUrl().replace("\\","")
1493
    if url_pkg[-7:] == ".gvspki" :
1494
      msgwarn("Suspicious download-url value. Ends with gvspki, expected gvspkg.")
1495
      msgwarn("download-url ='%s'." % url_pkg)
1496

    
1497
    if url_pkg.startswith("https:") and nohttps :
1498
       url_pkg = "http:" + url_pkg[6:]
1499

    
1500
    message( "Download package '%s'" % url_pkg)
1501
    temppath_pkg= os.path.join("/tmp",os.path.basename(url_pkg))
1502
    if not downloadFile(url_pkg,temppath_pkg):
1503
      msgerror("Can't download package from download-url ('%s')." % url_pkg)
1504
      msgerror("Can't install '%s'," % url_pki)
1505
      print # force a newline
1506
      return 1
1507
    folder = os.path.join(getPool(),pkg.getCode())
1508
    makedirs(folder)
1509
    pathname_pki = os.path.join(folder,os.path.basename(url_pki))
1510
    if not force and os.path.isfile(pathname_pki) :
1511
        msgwarn("The package index alreade exist in the pool. Use -f to forrce install.")
1512
        print # force a newline
1513
        return 1
1514
    pathname_pkg = os.path.join(folder,os.path.basename(url_pkg))
1515
    if  not force and os.path.isfile(pathname_pki) :
1516
        msgwarn("The package downloaded from download-url alredy exists in the pool. Use -f to force install.")
1517
        print # force a newline
1518
        return 1
1519
    message( "installing package '%s'" % os.path.basename(pathname_pki))
1520
    shutil.copyfile(temppath_pki, pathname_pki)
1521
    message( "installing package '%s'" % os.path.basename(pathname_pkg))
1522
    shutil.copyfile(temppath_pkg, pathname_pkg)
1523

    
1524
    md5sum(pathname_pki, pathname_pki+".md5")
1525
    md5sum(pathname_pkg, pathname_pkg+".md5")
1526

    
1527

    
1528
def md5sum(fin, fout):
1529
    message( "Calculating md5sum of %s..." % fin )
1530
    system("md5sum -b %s >%s" % (fin, fout) )
1531

    
1532
def downloadFile(url,path):
1533
  try:
1534
    fsrc = urllib2.urlopen(url)
1535
  except urllib2.HTTPError,e:
1536
    msgerror("Error abriendo url '%s'." % url, e)
1537
    return False
1538
  fdst = file(path,"wb")
1539
  shutil.copyfileobj(fsrc,fdst)
1540
  fdst.close()
1541
  fsrc.close()
1542
  return True
1543

    
1544
def shorthelp(args):
1545
    print """
1546
usage: gvspkg [OPTIONS] COMMANDS
1547
OPTIONS:
1548

    
1549
-h,--help       Muestra esta ayuda
1550
-v,--verbose    Activa el modo verbose
1551
-d,--debug      Activa el modo debug.
1552
--version ver   Fija la version con la que van a trabajar.
1553
-r,--package-root root    Fija la carpeta del raiz del sistema de paquetes
1554

    
1555
COMMANDS:
1556

    
1557
mkinstall [OPTIONS] install-file packages-file
1558
    -L, --jrelin=path
1559
    -W, --jrewin=path
1560
    -l, --addjrelin
1561
    -w, --addjrewin
1562
    -N, --distribution-name=name
1563

    
1564
lsi [OPTIONS]
1565
    -l, --long-format
1566

    
1567
mks [OPTIONS]
1568
     -c, --clear-list
1569
     --excludepkg pkgcode
1570
     --excludepki pkgcode
1571
     --exclude pkgcode
1572
     -s, --include-default-selection
1573
     -i, --index-only
1574
     -I full-path-to-package, --include full-path-to-package
1575

    
1576
mkdist [OPTIONS]
1577
     -s STATE, --state=STATE
1578
     -b BUILD, --build=BUILD
1579
     -N, --distribution-name=name
1580

    
1581
mkmirror [OPTIONS]
1582
     -b, --build buildnumber
1583

    
1584
mkhtml [OPTIONS]
1585
     -c, --clear-list
1586
     --excludepkg pkgcode
1587
     --excludepki pkgcode
1588
     --exclude pkgcode
1589

    
1590
show OPTIONS package-index
1591
    --verify, -V
1592

    
1593
edit [OPTIONS] package-index
1594
     --replace=@search@replace@
1595
     --onlysign
1596
     --sign, -S
1597

    
1598
editall [OPTIONS]
1599
     -c, --clear-list
1600
     --excludepkg pkgcode
1601
     --excludepki pkgcode
1602
     --exclude pkgcode
1603
     --replace=@search@replace@
1604
     --sign, -S
1605

    
1606
install [OPTIONS] url-to-pki
1607
     -f, --force
1608

    
1609
prepare-portable [OPTIONS]
1610
     -b, --build
1611
     -s, --state
1612

    
1613
mkportable [OPTIONS]
1614
     -b, --build
1615
     -s, --state
1616

    
1617
La version actual a utilizar es:
1618
  %s
1619

    
1620
El directorio root de la estructura de packetes actual es:
1621
  %s
1622
    """ % (VERSION, GVSPKG_ROOT)
1623

    
1624

    
1625
def help(args):
1626
    print """
1627
usage: gvspkg [OPTIONS] COMMANDS
1628

    
1629
OPTIONS:
1630

    
1631
-h|--help
1632
    Muestra esta ayuda
1633

    
1634
-v|--verbose
1635
    Activa el modo verbose
1636

    
1637
-d|--debug
1638
    Activa el modo debug. Se muestran mensajes que pueden ser
1639
    utilies de cara a depuracion.
1640

    
1641
--version version
1642
    Fija la version con la que van a trabajar los comandos indicados.
1643

    
1644
-r|--package-root package-root
1645
    Fija la carpeta en la que va a buscar el raiz del sistema de paquetes
1646
    con el que trabajar
1647

    
1648
COMMANDS:
1649

    
1650
mkinstall [OPTIONS] install-file packages-file
1651

    
1652
    OPTIONS:
1653

    
1654
    -L | --jrelin=path
1655

    
1656
    -W | --jrewin=path
1657

    
1658
    -l | --addjrelin
1659

    
1660
    -w | --addjrewin
1661

    
1662
    -N | --distribution-name=name
1663
      Nombre usado como sufijo del nuevo binario a generar. Por defecto si no se
1664
      indica valdra "custom".
1665

    
1666

    
1667
lsi [OPTIONS]
1668
    Lista los indices disponibles de la version
1669

    
1670
    OPTIONS:
1671

    
1672
    -l | --long-format
1673
        Muestra para cada paquete la informacion del package.info
1674

    
1675
mks [OPTIONS]
1676
     Crea el fichero packages.gvspki con los indices de la
1677
     version y packages.gvspkg con los paquetes.
1678

    
1679
     OPTIONS:
1680

    
1681
     -c | --clear-list
1682
        Elimina la lista de paquetes a utilizar recreandola a partir
1683
        de los paquetes del pool tomando el ultimo build de cada paquete.
1684

    
1685
     --excludepkg pkgcode
1686
        No incluye el paquete indicado en el fichero gvspkg a generar
1687

    
1688
     --excludepki pkgcode
1689
        No incluye el paquete indicado en el fichero gvspki a generar
1690

    
1691
     --exclude pkgcode
1692
        No incluye el paquete indicado en los ficheros gvspkg y gvspki a generar
1693

    
1694
     -s | --include-default-selection
1695
        Incluye el fichero "defaultPackages", que se debe encontrar en el
1696
        directorio corriente, con los nombres de paquetes a seleccionar
1697
        por defecto.
1698

    
1699
     -i | --index-only
1700
        No crea el fichero gvspks, solo crea el gvspki
1701

    
1702
     -I full-path-to-package | --include full-path-to-package
1703
        Agrega el paquete indicado a la lista de paquetes aunque no coincida para
1704
        la version de gvSIG con la que se esta trabajando.
1705

    
1706
mkdist [OPTIONS]
1707
     Crea los ficheros de la distribucion standard para el buil dindicado a partir de
1708
     la distribucion online y los paquetes que hayan en el pool para esta version.
1709
     Ejecuta un "mks" y un "mkhtml" automaticamente para preparar el conjunto de paquetes
1710
     a incluir en la distribucion, y una vez preparados ejecuta un "mkinsrall" por
1711
     S.O. (win y lin), renombrando los ficheros generados segun corresponda.
1712

    
1713
     OPTIONS:
1714
     -s STATE | --state=STATE
1715
        Indica el estado de la distribucion a generar, devel, alpha, ..., debe estar
1716
        deacuerdo con lo que diga el cihero online a usar como base.
1717

    
1718
     -b BUILD | --build=BUILD
1719
        Indica el numero de build de la destribucion a generar. Es usado para localizar
1720
        los ficheros en la carpeta builds de la distribucion y para saber donde debe
1721
        dejar los ficheros generados.
1722

    
1723
     -N | --distribution-name=name
1724
        Nombre usado como sufijo del nuevo binario a generar. Por defecto si no se
1725
        indica valdra "standard".
1726

    
1727

    
1728
mkmirror [OPTIONS]
1729

    
1730
  Prepara una carpeta para hacer un mirror de un build en concreto.
1731

    
1732
     OPTIONS:
1733

    
1734
     -b | --build buildnumber
1735
       Indica el numero de build del que se quiere hacer un mirror.
1736

    
1737
mkhtml [OPTIONS]
1738
     ????
1739

    
1740
     OPTIONS:
1741

    
1742
     -c | --clear-list
1743
        Elimina la lista de paquetes a utilizar recreandola a partir
1744
        de los paquetes del pool tomando el ultimo build de cada paquete.
1745

    
1746
     --excludepkg pkgcode
1747
        No incluye el paquete indicado en el fichero gvspkg a generar
1748

    
1749
     --excludepki pkgcode
1750
        No incluye el paquete indicado en el fichero gvspki a generar
1751

    
1752
     --exclude pkgcode
1753
        No incluye el paquete indicado en los ficheros gvspkg y gvspki a generar
1754

    
1755
show OPTIONS package-index
1756
    Muestra el package.info del indice indicado como parametro.
1757

    
1758
    OPTIONS
1759

    
1760
    --verify | -V
1761
      Comprueba la forma del packete.
1762

    
1763
edit [OPTIONS] package-index
1764
    Edita el package.info del indice indicado como parametro.
1765

    
1766
     OPTIONS:
1767

    
1768
     --replace=@search@replace@
1769
       Reemplaza en el package.info de cada paquete la cadena "search" por "replace"
1770
       todas las veces que aparezca. "@" puede ser cualquier caracter que no aparezca
1771
       en "search" y "replace".
1772
       Esta opcion puede indicarse tatas veces como reemplazos se deseen efectuar.
1773

    
1774
     --onlysign
1775
       firma el package.info sin editarlo de forma interactiva (no invoca al editor antes
1776
       de firmarlo).
1777

    
1778
     --sign | -S
1779
       Firma el package.info tras terminar la edicion (bach o interactiva)
1780

    
1781
editall [OPTIONS]
1782
    Edita todos los package.info
1783

    
1784
     OPTIONS:
1785

    
1786
     -c | --clear-list
1787
        Elimina la lista de paquetes a utilizar recreandola a partir
1788
        de los paquetes del pool tomando el ultimo build de cada paquete.
1789

    
1790
     --excludepkg pkgcode
1791
        No incluye el paquete indicado en el fichero gvspkg a generar
1792

    
1793
     --excludepki pkgcode
1794
        No incluye el paquete indicado en el fichero gvspki a generar
1795

    
1796
     --exclude pkgcode
1797
        No incluye el paquete indicado en los ficheros gvspkg y gvspki a generar
1798

    
1799
     --replace=@search@replace@
1800
       Reemplaza en el package.info de cada paquete la cadena "search" por "replace"
1801
       todas las veces que aparezca. "@" puede ser cualquier caracter que no aparezca
1802
       en "search" y "replace".
1803
       Esta opcion puede indicarse tatas veces como reemplazos se deseen efectuar.
1804

    
1805
      --sign | -S
1806
        Firma todos los paquetes que sean oficiales
1807

    
1808
install [OPTIONS] url-to-pki
1809
    descarga de la url indicada un fichero gvspki e instala este junto con su correspondiente
1810
    pkg en el pool local.
1811

    
1812
     OPTIONS:
1813

    
1814
     -f | --force
1815
       fuerza la sobreescritura de los ficheros en caso de que estos ya existan.
1816

    
1817
Si en la carpeta corriente encuentra un fichero gvspkg.options cargara los
1818
flags indicados ahi como flags por defecto para cada comando. El formato del
1819
fichero es:
1820
  main=OPCION-POR-DEFECTO
1821
  mks=OPCOPNES-POR-DEFECTO
1822
Donde main indica las opciones por defecto generales, independientes del comando
1823
a ejecutar. "mks" indica las opciones por defecto a usar en el comando "mks", y
1824
asi sucesivamente, indicando el nombre del comando seguido de un "=" y las opciones
1825
por defecto para ese comando.
1826

    
1827
Por defecto la version la obtiene del nombre de la carpeta
1828
corriente (%s). Las opciones indicadas en el fichero gvspkg.options tienen prioridad
1829
sobre este valor.
1830

    
1831
El directorio root de la estructura de packetes lo buscara en el
1832
sitio indicado por la variable de entorno GVPKG_ROOT, y si esta no
1833
esta establecida usara "%s". Las opciones indicadas en el fichero gvspkg.options
1834
tienen prioridad sobre este valor.
1835

    
1836
    """ % (VERSION, GVSPKG_ROOT)
1837

    
1838
def executeCommand(*args):
1839
    command = "shorthelp"
1840
    if len(args)>0:
1841
        command=args[0]
1842

    
1843
    r=1
1844
    if command=="lsi" :
1845
        r=lsi(args)
1846
    elif command == "mks":
1847
        r=mks(args)
1848
    elif command == "edit":
1849
        r=edit(args)
1850
    elif command == "editall":
1851
        r=editall(args)
1852
    elif command == "show":
1853
        r=show(args)
1854
    elif command == "mkhtml":
1855
        r=mkhtml(args)
1856
    elif command == "mkinstall":
1857
        r=mkinstall(args)
1858
    elif command == "install":
1859
        r=install(args)
1860
    elif command == "mkdist":
1861
        r=mkdist(args)
1862
    elif command == "mkmirror":
1863
        r=mkmirror(args)
1864
    elif command == "mkportable":
1865
        r=mkportable(args)
1866
    elif command == "prepare-portable":
1867
        r=prepare_portable(args)
1868
    elif command == "help":
1869
        r=help(args)
1870
    else:
1871
        r=shorthelp(args)
1872
    return r
1873

    
1874
def main():
1875
    global DEBUG
1876
    global VERSION
1877
    global VERBOSE
1878
    global GVSPKG_ROOT
1879
    global SEARCH_VERSIONS
1880

    
1881
    cmd = Command(sys.argv)
1882
    try:
1883
        opts, args = getopt.getopt(cmd.getArgs("main"), "dhvr:", ["debug", "verbose", "version=", "package-root=","help","search_versions="])
1884
    except getopt.GetoptError, err:
1885
        # print help information and exit:
1886
        print str(err) # will print something like "option -a not recognized"
1887
        shorthelp(None)
1888
        sys.exit(2)
1889

    
1890
    for opt, arg in opts:
1891
        if opt in ("-h", "--help"):
1892
            shorthelp(args)
1893
            sys.exit()
1894
        elif opt in ("-d", "--debug"):
1895
            DEBUG = True
1896
        elif opt in ("-v", "--verbose"):
1897
            VERBOSE = True
1898
        elif opt in ("--version"):
1899
            VERSION = arg
1900
        elif opt in ("--search_versions"):
1901
            SEARCH_VERSIONS.append(arg)
1902
        elif opt in ("-r", "--package-root"):
1903
            GVSPKG_ROOT = arg
1904
        else:
1905
            assert False, "unhandled option"
1906
    #
1907
    debug("DEBUG=%s" % DEBUG)
1908
    debug("VERSION=%s" % VERSION)
1909
    debug("GVSPKG_ROOT=%s" % GVSPKG_ROOT)
1910
    if GVSPKG_ROOT == None:
1911
      shorthelp(None)
1912
    else:
1913
      r=executeCommand(*args)
1914
      sys.exit(r)
1915

    
1916
main()