def create(name="myproject", origin=None, skeleton=None, **argv): """Creates a new project""" header("Creating project %s" % name) if not validProjectName.match(name): raise JasyError("Invalid project name: %s" % name) # # Initial Checks # # Figuring out destination folder destinationPath = os.path.abspath(name) if os.path.exists(destinationPath): raise JasyError("Cannot create project in %s. File or folder exists!" % destinationPath) # Origin can be either: # 1) None, which means a skeleton from the current main project # 2) An repository URL # 3) A project name known inside the current session # 4) Relative or absolute folder path if origin is None: originProject = session.getMain() if originProject is None: raise JasyError("Auto discovery failed! No Jasy projects registered!") originPath = originProject.getPath() originName = originProject.getName() elif isRepository(origin): info("Using remote skeleton") tempDirectory = tempfile.TemporaryDirectory() originPath = os.path.join(tempDirectory.name, "clone") originUrl = origin originVersion = getKey(argv, "origin-version") indent() originRevision = updateRepository(originUrl, originVersion, originPath) outdent() if originRevision is None: raise JasyError("Could not clone origin repository!") debug("Cloned revision: %s" % originRevision) originProject = getProjectFromPath(originPath) originName = originProject.getName() else: originProject = session.getProjectByName(origin) if originProject is not None: originPath = originProject.getPath() originName = origin elif os.path.isdir(origin): originPath = origin originProject = getProjectFromPath(originPath) originName = originProject.getName() else: raise JasyError("Invalid value for origin: %s" % origin) # Figure out the skeleton root folder skeletonDir = os.path.join(originPath, originProject.getConfigValue("skeletonDir", "skeleton")) if not os.path.isdir(skeletonDir): raise JasyError("The project %s offers no skeletons!" % originName) # For convenience: Use first skeleton in skeleton folder if no other selection was applied if skeleton is None: skeleton = getFirstSubFolder(skeletonDir) # Finally we have the skeleton path (the root folder to copy for our app) skeletonPath = os.path.join(skeletonDir, skeleton) if not os.path.isdir(skeletonPath): raise JasyError('Skeleton %s does not exist in project "%s"' % (skeleton, originName)) # # Actual Work # # Prechecks done info( "Creating %s from %s %s...", colorize(name, "bold"), colorize(skeleton + " @", "bold"), colorize(originName, "magenta"), ) debug("Skeleton: %s", colorize(skeletonPath, "grey")) debug("Destination: %s", colorize(destinationPath, "grey")) # Copying files to destination info("Copying files...") shutil.copytree(skeletonPath, destinationPath) debug("Files were copied successfully.") # Build data for template substitution data = {} data.update(argv) data["name"] = name data["origin"] = originName data["skeleton"] = os.path.basename(skeletonPath) data["jasy"] = jasy.__version__ # Do actual replacement of placeholders massFilePatcher(destinationPath, data) debug("Files were patched successfully.") # Change to directory before continuing os.chdir(destinationPath) # Create configuration file from question configs and custom scripts info("Starting configuration...") config = Config() config.injectValues(**argv) config.readQuestions("jasycreate", optional=True) config.executeScript("jasycreate.py", optional=True) config.write("jasyscript.yaml") # Done info("Your application %s was created successfully!", colorize(name, "bold"))
def getRequires(self, prefix="external"): """ Return the project requirements as project instances """ global projects result = [] for entry in self.__requires: if type(entry) is dict: source = entry["source"] config = getKey(entry, "config") version = getKey(entry, "version") kind = getKey(entry, "kind") else: source = entry config = None version = None kind = None revision = None if isRepository(source): kind = kind or getRepositoryType(source) path = os.path.abspath(os.path.join(prefix, getRepositoryFolder(source, version, kind))) # Only clone and update when the folder is unique in this session # This reduces git/hg/svn calls which are typically quite expensive if not path in projects: revision = updateRepository(source, version, path) if revision is None: raise JasyError("Could not update repository %s" % source) else: kind = "local" if not source.startswith(("/", "~")): path = os.path.join(self.__path, source) else: path = os.path.abspath(os.path.expanduser(source)) if path in projects: project = projects[path] else: fullversion = [] # Produce user readable version when non is defined if version is None and revision is not None: version = "master" if version is not None: if "/" in version: fullversion.append(version[version.rindex("/")+1:]) else: fullversion.append(version) if revision is not None: # Shorten typical long revisions as used by e.g. Git if type(revision) is str and len(revision) > 20: fullversion.append(revision[:10]) else: fullversion.append(revision) if fullversion: fullversion = "-".join(fullversion) else: fullversion = None project = Project(path, config, fullversion) projects[path] = project result.append(project) return result