Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot upload files without extensions #6557

Closed
setgree opened this issue Jan 22, 2020 · 11 comments · Fixed by #6804
Closed

Cannot upload files without extensions #6557

setgree opened this issue Jan 22, 2020 · 11 comments · Fixed by #6804

Comments

@setgree
Copy link

setgree commented Jan 22, 2020

Background:

  • Political Analysis is working with authors and with Code Ocean (whom I work for) to make authors' code reproducible & executable as part of the publication process.
  • Authors upload their materials to Code Ocean, e.g. https://doi.org/10.24433/CO.4189072.v1, and then those materials are exported to the Political Analysis Dataverse (https://dataverse.harvard.edu/dataverse/pan)
  • We currently do this manually but the goal is to have API integration that automates the export and uploading process.

Problem:

  • Code Ocean's 'master script' (the thing the system executes when a reader or author presses 'Reproducible Run') is just called run, no file extension. It's a shell script comprising something like:
#!/usr/bin/env bash
set -ex

# This is the master script for the capsule. When you click "Reproducible Run", the code in this file will execute.
Rscript "Run_all.R"
  • It's a bash script, but we dropped the extension at some point.

  • Dataverse does not seem to allow us to upload files without file extensions.

  • When I drag and drop run (or something called newfile with arbitrary text in it) via the Dataverse Interface, my browser (Firefox) scrolls to the top of the page, and when I scroll down, the file has not been uploaded.

  • When I tried a few weeks ago (on Chrome) to upload all the materials from https://doi.org/10.24433/CO.4189072.v1, I received a message that run and Run_all.R are duplicates and only Run_all.R was successfully uploaded.

The short-term solution:

  • We can rename all the run scripts run.sh before they are uploaded to Dataverse.

The problem with that short-term solution, long-term:

  • An additional manual step in the process makes API integration harder because it's one more thing that could go wrong in an unsupervised setting (what if users already have a run.sh script uploaded, for instance).

The ideal solution (from our POV):

  • Dataverse allows files that do not have file extensions to be uploaded.
@pdurbin
Copy link
Member

pdurbin commented Jan 22, 2020

Huh. Sure enough I tried the run file above on my "dev2" server (running fb4bd69 which is a bit behind 4.19 but I don't think it matters) and in server.log I see "File must have an extension" like in the stacktrace below.

The user experience is that the screen flashes after I try to upload run and no file is shown, like the screenshot below.

I believe this is a regression. We always say that any file can be uploaded to Dataverse. Thanks for opening this issue @setgree !

Screen Shot 2020-01-22 at 11 35 23 AM

[#|2020-01-22T16:33:51.158+0000|INFO|glassfish 4.1|javax.enterprise.resource.webcontainer.jsf.context|_ThreadID=49;_ThreadName=jk-connector(3);_TimeMillis=1579710831158;_LevelValue=800;|
javax.faces.FacesException: File must have an extension
javax.faces.FacesException: File must have an extension
at org.primefaces.util.FileUploadUtils.getValidFilename(FileUploadUtils.java:88)
at org.primefaces.model.NativeUploadedFile.resolveFilename(NativeUploadedFile.java:149)
at org.primefaces.model.NativeUploadedFile.(NativeUploadedFile.java:59)
at org.primefaces.component.fileupload.NativeFileUploadDecoder.decodeAdvanced(NativeFileUploadDecoder.java:110)
at org.primefaces.component.fileupload.NativeFileUploadDecoder.decode(NativeFileUploadDecoder.java:56)
at org.primefaces.component.fileupload.FileUploadRenderer.decode(FileUploadRenderer.java:60)
at edu.harvard.iq.dataverse.FileUploadRenderer.decode(FileUploadRenderer.java:20)
at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:831)
at javax.faces.component.UIInput.decode(UIInput.java:771)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1225)
at javax.faces.component.UIInput.processDecodes(UIInput.java:676)
at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:573)
at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1689)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIForm.visitTree(UIForm.java:371)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:403)
at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:266)
at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:219)
at org.primefaces.context.PrimePartialViewContext.processPartial(PrimePartialViewContext.java:63)
at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:927)
at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.glassfish.tyrus.servlet.TyrusServletFilter.doFilter(TyrusServletFilter.java:295)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.ocpsoft.rewrite.servlet.RewriteFilter.doFilter(RewriteFilter.java:226)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
at java.lang.Thread.run(Thread.java:748)
|#]

[#|2020-01-22T16:33:51.158+0000|WARNING|glassfish 4.1|javax.enterprise.resource.webcontainer.jsf.lifecycle|_ThreadID=49;_ThreadName=jk-connector(3);_TimeMillis=1579710831158;_LevelValue=900;|
javax.faces.FacesException: File must have an extension
javax.faces.FacesException: javax.faces.FacesException: File must have an extension
at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:273)
at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:219)
at org.primefaces.context.PrimePartialViewContext.processPartial(PrimePartialViewContext.java:63)
at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:927)
at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.glassfish.tyrus.servlet.TyrusServletFilter.doFilter(TyrusServletFilter.java:295)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.ocpsoft.rewrite.servlet.RewriteFilter.doFilter(RewriteFilter.java:226)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.faces.FacesException: File must have an extension
at org.primefaces.util.FileUploadUtils.getValidFilename(FileUploadUtils.java:88)
at org.primefaces.model.NativeUploadedFile.resolveFilename(NativeUploadedFile.java:149)
at org.primefaces.model.NativeUploadedFile.(NativeUploadedFile.java:59)
at org.primefaces.component.fileupload.NativeFileUploadDecoder.decodeAdvanced(NativeFileUploadDecoder.java:110)
at org.primefaces.component.fileupload.NativeFileUploadDecoder.decode(NativeFileUploadDecoder.java:56)
at org.primefaces.component.fileupload.FileUploadRenderer.decode(FileUploadRenderer.java:60)
at edu.harvard.iq.dataverse.FileUploadRenderer.decode(FileUploadRenderer.java:20)
at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:831)
at javax.faces.component.UIInput.decode(UIInput.java:771)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1225)
at javax.faces.component.UIInput.processDecodes(UIInput.java:676)
at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:573)
at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1689)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIForm.visitTree(UIForm.java:371)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:403)
at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:266)
... 43 more
|#]

[#|2020-01-22T16:33:51.161+0000|SEVERE|glassfish 4.1|javax.enterprise.resource.webcontainer.jsf.context|_ThreadID=49;_ThreadName=jk-connector(3);_TimeMillis=1579710831161;_LevelValue=1000;|
javax.faces.FacesException: File must have an extension
at org.primefaces.util.FileUploadUtils.getValidFilename(FileUploadUtils.java:88)
at org.primefaces.model.NativeUploadedFile.resolveFilename(NativeUploadedFile.java:149)
at org.primefaces.model.NativeUploadedFile.(NativeUploadedFile.java:59)
at org.primefaces.component.fileupload.NativeFileUploadDecoder.decodeAdvanced(NativeFileUploadDecoder.java:110)
at org.primefaces.component.fileupload.NativeFileUploadDecoder.decode(NativeFileUploadDecoder.java:56)
at org.primefaces.component.fileupload.FileUploadRenderer.decode(FileUploadRenderer.java:60)
at edu.harvard.iq.dataverse.FileUploadRenderer.decode(FileUploadRenderer.java:20)
at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:831)
at javax.faces.component.UIInput.decode(UIInput.java:771)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1225)
at javax.faces.component.UIInput.processDecodes(UIInput.java:676)
at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:573)
at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1689)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIForm.visitTree(UIForm.java:371)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:403)
at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:266)
at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:219)
at org.primefaces.context.PrimePartialViewContext.processPartial(PrimePartialViewContext.java:63)
at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:927)
at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.glassfish.tyrus.servlet.TyrusServletFilter.doFilter(TyrusServletFilter.java:295)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.ocpsoft.rewrite.servlet.RewriteFilter.doFilter(RewriteFilter.java:226)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
at java.lang.Thread.run(Thread.java:748)
|#]

@djbrooke
Copy link
Contributor

I agree that we should allow every file type to be uploaded, but I think that's different than whether or not we require a file extension, which I'd see as important for preservation, reproducibility, previewing, etc.. Since this decision predates me, I'd be interested in hearing from @scolapasta @landreev and others that have been here longer. Thanks @setgree for reporting!

@setgree
Copy link
Author

setgree commented Jan 22, 2020

You are welcome, thank you both for the prompt reply!

My 2c is to quote
https://google.github.io/styleguide/shell.xml?showone=File_Extensions#File_Extensions

Executables should have no extension (strongly preferred) or a .sh extension...
It is not necessary to know what language a program is written in when executing it and shell doesn't require an extension so we prefer not to use one for executables.

On Code Ocean, the run script is an executable -- it's effectively telling the Docker container which command to run when one spins up the container, e.g.:

docker run --rm \
  --workdir /code \
  --volume "$PWD/data":/data \
  --volume "$PWD/code":/code \
  --volume "$PWD/results":/results \
  registry.codeocean.com/published/45b8b602-c010-409c-829c-25305705e8c9:v1 ./run

So I think for reproducibility, this is in line with some practices considered good (or best) by some people.

As to previewing, as far as I know, unless the extension-less file is a compiled binary, it can be previewed as plaintext.

@pdurbin
Copy link
Member

pdurbin commented Feb 3, 2020

"Dockerfile" is an example of a common filename that doesn't have an extension. Dataverse should support uploading of files called "Dockerfile".

@scolapasta
Copy link
Contributor

This wasn't a specific decision we made, but an artifact of the primefaces file upload component. It does appear they've fixed it, but not in a free version yet. (fixed version is 7.0.9)

primefaces/primefaces#4863

@pdurbin
Copy link
Member

pdurbin commented Feb 7, 2020

Related to being unable to upgrade to minor releases of PrimeFaces: https://github.com/IQSS/dataverse-security/issues/9 (via #6281 (comment) )

@scolapasta
Copy link
Contributor

scolapasta commented Feb 10, 2020

I reviewed Primefaces release schedule and the good news is that they released 8.0 RC3 11 days ago (RC1 was Dec 2019). Historically, once they've started with RC1, the final release comes soon after (weeks, a few months, depending on how many RCs there are). So I would expect that 8.0 final should come out in February or March and we can upgrade then.

If I can find out anything more concrete, I'll add it here (and here: #6634).

@mheppler
Copy link
Contributor

mheppler commented Feb 13, 2020

@setgree in case you are blocked getting your project exported from Code Ocean and deposited into Dataverse, I just wanted to point out that there are workarounds available as alternatives to depositing individual files via the drag and drop widget in the UI.

Depositing a ZIP of all the files together (User Guide: http://guides.dataverse.org/en/4.19/user/dataset-management.html#compressed-files) and uploading them through the UI or the API will allow for the successful deposit of run or Dockerfile files and anything else missing a file extension.

Screen Shot 2020-02-13 at 3 48 06 PM

In the meantime, we are working to get that drag and drop widget fixed, so that we have consistent system behavior across all our upload methods.

Also, I'd like to point out that we are working on resolving the duplicate file name #6574 and duplicate MD5 #4813 issues you mentioned in your use case, as well as empty directories #6627 and other technical issues we'd need to resolve to better support depositing capsules from Code Ocean and other tools.

Feedback on those issues are welcome!

@setgree
Copy link
Author

setgree commented Feb 19, 2020

Hi @mheppler , FWIW, we encountered the issue with run not when uploading a zip file via the UI. It was through drag and drop; when you say "through the UI," do you mean via the option that says 'upload files' and then opens up the file finder on one's computer?

@mheppler
Copy link
Contributor

mheppler commented Feb 20, 2020

@setgree, correct, the drag and drop file upload UI component on the Upload Files should support depositing files without extensions when they are included in a ZIP file. I have just confirmed this with a Code Ocean capsule ZIP on both Harvard Dataverse and Demo Dataverse.

Screen Shot 2020-02-20 at 8 47 55 AM

I went back to your original comment, to see if there was something in your particular use case that was different than what I was trying, and I think I found something.

When I tried a few weeks ago (on Chrome) to upload all the materials from https://doi.org/10.24433/CO.4189072.v1, I received a message that run and Run_all.R are duplicates and only Run_all.R was successfully uploaded.

Since you got a "duplicates" message on upload for your run file, I am wondering if some other hidden error occurred on your first upload. Can you please try to upload your ZIP to Demo Dataverse (https://demo.dataverse.org) and see if it works on that installation?

Also, does your ZIP have a directory structure to it with multiple folders or is it just one compressed folder with all the files directly in it?

@mheppler
Copy link
Contributor

UPDATE: @setgree, I was able to export a Code Ocean capsule ZIP from the DOI you provided, and upload it to Demo Dataverse. The run file successfully uploaded, and I received a duplicates msg for the following file:

  • C527AAE7
  • 1DD912E6-contents
  • 7A311E84-contents
  • BD2762AE-contents
  • D82D20CB-contents
  • FA3D5639-contents
  • lock_file
  • Run_all.R

As I referred to in a previous comment, we are currently working to resolve duplicate file name #6574 and duplicate MD5 #4813 issues related to supporting deposits from Code Ocean or any other upload method.

While researching those issues, I have found what appear to be workarounds to get those duplicate files deposited via the Native API (http://guides.dataverse.org/en/4.19/api/native-api.html#add-a-file-to-a-dataset) and Sword API (http://guides.dataverse.org/en/4.19/api/sword.html#add-files-to-a-dataset-with-a-zip-file).

Our plan is for all of these various UI and API upload methods to behave consistently, and to improve the messaging so any warnings or errors are clearer.

@djbrooke djbrooke added this to the Dataverse 5 milestone Apr 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants