aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/models.py10
-rw-r--r--app/tasks/importtasks.py86
-rw-r--r--app/templates/packages/release_new.html2
-rw-r--r--app/views/packages/releases.py4
4 files changed, 58 insertions, 44 deletions
diff --git a/app/models.py b/app/models.py
index f045d75..a50c4d0 100644
--- a/app/models.py
+++ b/app/models.py
@@ -434,16 +434,6 @@ class Package(db.Model):
return None
- def canMakeReleaseFromVCS(self):
- if self.repo is None:
- return False
-
- url = urlparse(self.repo)
- if url.netloc == "github.com":
- return True
-
- return False
-
def checkPerm(self, user, perm):
if not user.is_authenticated:
return False
diff --git a/app/tasks/importtasks.py b/app/tasks/importtasks.py
index ae689e1..d2c26ea 100644
--- a/app/tasks/importtasks.py
+++ b/app/tasks/importtasks.py
@@ -137,9 +137,9 @@ class PackageTreeNode:
print("Scanning " + baseDir)
self.baseDir = baseDir
self.author = author
- self.name = name
- self.repo = repo
- self.meta = None
+ self.name = name
+ self.repo = repo
+ self.meta = None
self.children = []
# Detect type
@@ -275,26 +275,30 @@ class PackageTreeNode:
return self.meta.get(key)
-def cloneRepo(urlstr):
+# Clones a repo from an unvalidated URL.
+# Returns a tuple of path and repo on sucess.
+# Throws `TaskError` on failure.
+# Caller is responsible for deleting returned directory.
+def cloneRepo(urlstr, ref=None, recursive=False):
gitDir = tempfile.gettempdir() + "/" + randomString(10)
err = None
try:
- git.Repo.clone_from(urlstr, gitDir, progress=None, env=None, depth=1)
+ repo = git.Repo.clone_from(urlstr, gitDir, progress=None, env=None, depth=1, recursive=recursive)
+ if ref is not None:
+ repo.create_head("myhead", ref).checkout()
+ return gitDir, repo
except GitCommandError as e:
# This is needed to stop the backtrace being weird
err = e.stderr
- if err is not None:
- raise TaskError(err.replace("stderr: ", "") \
- .replace("Cloning into '" + gitDir + "'...", "") \
- .strip())
-
- return gitDir
+ raise TaskError(err.replace("stderr: ", "") \
+ .replace("Cloning into '" + gitDir + "'...", "") \
+ .strip())
@celery.task()
def getMeta(urlstr, author):
- gitDir = cloneRepo(urlstr)
+ gitDir, _ = cloneRepo(urlstr, recursive=True)
tree = PackageTreeNode(gitDir, author=author, repo=urlstr)
shutil.rmtree(gitDir)
@@ -320,24 +324,8 @@ def getMeta(urlstr, author):
return result
-@celery.task()
-def makeVCSRelease(id, branch):
- release = PackageRelease.query.get(id)
-
- if release is None:
- raise TaskError("No such release!")
-
- if release.package is None:
- raise TaskError("No package attached to release")
-
- url = urlparse(release.package.repo)
-
- urlmaker = None
- if url.netloc == "github.com":
- urlmaker = GithubURLMaker(url)
- else:
- raise TaskError("Unsupported repo")
-
+def makeVCSReleaseFromGithub(id, branch, release, url):
+ urlmaker = GithubURLMaker(url)
if not urlmaker.isValid():
raise TaskError("Invalid github repo URL")
@@ -356,6 +344,37 @@ def makeVCSRelease(id, branch):
return release.url
+
+@celery.task()
+def makeVCSRelease(id, branch):
+ release = PackageRelease.query.get(id)
+ if release is None:
+ raise TaskError("No such release!")
+ elif release.package is None:
+ raise TaskError("No package attached to release")
+
+ urlmaker = None
+ url = urlparse(release.package.repo)
+ if url.netloc == "github.com":
+ return makeVCSReleaseFromGithub(id, branch, release, url)
+ else:
+ gitDir, repo = cloneRepo(release.package.repo, ref=branch, recursive=True)
+
+ try:
+ filename = randomString(10) + ".zip"
+ destPath = os.path.join("app/public/uploads", filename)
+ with open(destPath, "wb") as fp:
+ repo.archive(fp)
+
+ release.url = "/uploads/" + filename
+ print(release.url)
+ release.task_id = None
+ db.session.commit()
+
+ return release.url
+ finally:
+ shutil.rmtree(gitDir)
+
@celery.task()
def importRepoScreenshot(id):
package = Package.query.get(id)
@@ -363,7 +382,12 @@ def importRepoScreenshot(id):
raise Exception("Unexpected none package")
# Get URL Maker
- gitDir = cloneRepo(package.repo)
+ try:
+ gitDir, _ = cloneRepo(package.repo)
+ except TaskError as e:
+ # ignore download errors
+ print(e)
+ return None
# Find and import screenshot
try:
diff --git a/app/templates/packages/release_new.html b/app/templates/packages/release_new.html
index eea9a5a..3578466 100644
--- a/app/templates/packages/release_new.html
+++ b/app/templates/packages/release_new.html
@@ -11,7 +11,7 @@
{{ render_field(form.title, placeholder="Human readable. Eg: 1.0.0 or 2018-05-28") }}
{{ render_field(form.uploadOpt) }}
- {% if package.canMakeReleaseFromVCS() %}
+ {% if package.repo %}
{{ render_field(form.vcsLabel) }}
{% endif %}
{{ render_field(form.fileUpload) }}
diff --git a/app/views/packages/releases.py b/app/views/packages/releases.py
index 6d8691b..b6f5b20 100644
--- a/app/views/packages/releases.py
+++ b/app/views/packages/releases.py
@@ -52,8 +52,8 @@ def create_release_page(package):
# Initial form class from post data and default data
form = CreatePackageReleaseForm()
- if package.canMakeReleaseFromVCS():
- form["uploadOpt"].choices = [("vcs", "From VCS Commit or Branch"), ("upload", "File Upload")]
+ if package.repo is not None:
+ form["uploadOpt"].choices = [("vcs", "From Git Commit or Branch"), ("upload", "File Upload")]
if request.method != "POST":
form["uploadOpt"].data = "vcs"