Repository: iterative/dvc

Issue:
`dvc run` without arguments should show help instead of producing an empty dvc file
Right now `dvc run` produces:

```
cmd: ''
md5: 103a608cacf27fc1a59526a0096da33d
```

I'm not sure if it makes sense to do that. Probably it's just better to show help?
consider redesigning state file
Currently we store state in a json file .dvc/state and limit it to 10000 entries. We also don't save state for files smaller than 7MB. While these were the means to workaround other limitations, we definitely need to consider thinking about a better solution.


Discussion:
Hm, looked into it right now and discovered that I have added a test for that :slightly_smiling_face: Looks like I was considering it a corner case of sorts. I'll give it a better thought again soon. Thank you for noticing!
Cool, thank you. Could we check the commit message for the test? May be there is some explanation for that. Just a random suggestion :)
Unfortunately it was in one of the first bulks of unittests for the current design, all it says is:

```
commit f47a2c75855ea2fe5aaa97a17efdb3a7cd20c13f         
Author: Ruslan Kuprieiev <kupruser@gmail.com>           
Date:   Mon Jan 1 15:00:48 2018 +0200                   
                                                        
    dvc: initial unittests                              
                                                        
    Initial unittests for new design.                   
                                                        
    Signed-off-by: Ruslan Kuprieiev <kupruser@gmail.com>
```

So looks like I had something trivial on my mind when adding that. I will think about it and come back to this issue soon.
👍 
Hi @efiop!

Does the current size limitation limits the number of files DVC can currently keep track of?

If yes, if I dvc track a directory, what goes into the state file:
- the info regarding the dir itself only (small state file usage)?
- the infor regarding the dir itself and all the files inside it (large state file usage?
Hi @andrethrill !

State file is only used for optimization, so you don't have to recompute checksums for large files. It doesn't affect the core functionality of dvc and doesn't limit the number of files that dvc can keep track of. 
When saving state for the directory, dvc will save state about the directory itself(effective inode, effective checksum, effective mtime) as well as state(inode, checksum, mtime) for each file in the directory that is bigger than 7MB. When the limit of entries in the state file is reached, dvc will simply drop the previous state and next time compute it once again and will put it into the state file for later use.

Thanks,
Ruslan
Thanks for the reply @efiop .

So... (I'm just thinking in edge cases here so bear with me ;) ) if I had more than 10000 large files tracked by DVC, say 10123 large files, then there would be always 123 files that have their checksum recalculated everytime I do a `dvc status` or other commands?
@andrethrill Unfortunately yes, in the current implementation. I'm working on a better solution right now, should be ready for 0.19.0 very soon. The current limit was introduced a day ago with 0.18.12 to help debug another issue where I suspected that state file got way too big.
That's perfect. Thank you for the explanation!
Merged https://github.com/iterative/dvc/pull/1112 with sqlite support. Also need to consider merging link.state and state into one db by introducing additional columns and using paths instead of inodes.

Resolving patch:
diff --git a/dvc/cli.py b/dvc/cli.py
--- a/dvc/cli.py
+++ b/dvc/cli.py
@@ -805,4 +805,12 @@ def parse_args(argv=None):
                 pipeline_show_parser.error(msg)
         args.targets = ['Dvcfile']
 
+    if issubclass(args.func, CmdRun) \
+       and len(args.deps) == 0 \
+       and len(args.outs) == 0 \
+       and len(args.outs_no_cache) == 0 \
+       and len(args.command) == 0:
+        run_parser.error("Too few arguments. Specify at least one: "
+                         "'-d', '-o', '-O', 'command'.")
+
     return args
diff --git a/dvc/project.py b/dvc/project.py
--- a/dvc/project.py
+++ b/dvc/project.py
@@ -106,7 +106,6 @@ def destroy(self):
 
     def _ignore(self):
         flist = [self.state.state_file,
-                 self.link_state.state_file,
                  self.lock.lock_file,
                  self.config.config_local_file,
                  self.updater.updater_file]
diff --git a/dvc/state.py b/dvc/state.py
--- a/dvc/state.py
+++ b/dvc/state.py
@@ -14,7 +14,6 @@ class StateDuplicateError(DvcException):
 
 class State(object):
     STATE_FILE = 'state'
-    STATE_LOCK_FILE = 'state.lock'
     STATE_TABLE = 'state'
     STATE_TABLE_LAYOUT = "inode TEXT PRIMARY KEY, " \
                          "mtime TEXT NOT NULL, " \
@@ -166,8 +165,6 @@ def get(self, path):
 
 
 class LinkState(State):
-    STATE_FILE = 'link.state'
-    STATE_LOCK_FILE = STATE_FILE + '.lock'
     STATE_TABLE = 'link'
     STATE_TABLE_LAYOUT = "path TEXT PRIMARY KEY, " \
                          "inode TEXT NOT NULL, " \


Test patch: